Dokümantasyon / İşletim
Job'lar
Job, durumu PostgreSQL'de tutulan uzun bir iştir; terminali kapatsanız, süreç çökse ya da makine yeniden başlasa da kaybolmaz. Bu sayfada job'un ne olduğu, hangi durumlardan geçtiği, bir onay gerektiğinde nasıl beklediği ve ilgili komutlar anlatılıyor.
Job nedir
Job, ivralo veritabanındaki jobs tablosunda, oturumların ve çalıştırmaların yanında tutulan tek bir satırdır. Bu satırda job'un ne olduğu, nereye kadar geldiği, onu hangi sürecin çalıştırdığı ve neyi beklediği yazar.
Ortada bir daemon yoktur. Job, onu başlatan süreçte çalışır; kalıcı olan tek şey veritabanıdır. O süreç ölürse satır yerinde kalır ve job'u başka bir süreç devralabilir.
| Tür | Neyi kapsar |
|---|---|
plan | Bir plan çalıştırması: ivralo plan --job, ivralo ask --plan --job |
request | Tek bir istek: ivralo ask --job. Alarm incelemesi de bir request job'udur. |
bisect | Regresyon araması: ivralo bisect commit'leri kendine ait bir worktree'de dener |
api | Yerel API'nin çalıştırdığı bir istek. Workspace'i yalnızca istek sürdüğü sürece tutar. |
Alarm incelemeleri de birer job'dur. Alertmanager ya da PagerDuty yerel API'ye bildirim gönderdiğinde, tetiklenen her alarm iki şey üretir: workspace'te alerts/ altında küçük bir kanıt bundle'ı ve bu bundle'ı inceleyecek, kuyrukta bekleyen bir request job'u. Bu job'lar, alarmı alan ivralo serve sürecinde sırayla çalışır ve ivralo jobs onları diğerleriyle birlikte listeler. Ayrıntılar Alarm alımı sayfasında.
Job başlatmak
plan, ask --plan ya da ask komutuna --job eklemeniz yeterli. Önce job'un satırı yazılır ve id'si ekrana basılır, ardından iş aynı terminalde çalışır:
ivralo plan --job "add a /health endpoint with a test"
job 3f9a1c2e started
Bu satır çıktıktan sonra terminal kapansa, Ctrl+C'ye basılsa ya da makine yeniden başlasa bile job kaybolmaz; ivralo resume 3f9a1c2e ile kaldığı yerden devam eder. plan --job taslak planı hemen çalıştırır; ask --plan --job ise planı gösterip önce onay ister (pipe içinde --yes kullanılır).
Job başında kimse olmadan çalışır. Düz bir ivralo ask, onay gerektiren bir çağrıyı reddeder; job ise bu noktada park eder ve bekler.
Durumlar
queued -> running -> waiting_for_approval -> running -> completed
-> failed
-> cancelled
queued -> blocked (another job holds the workspace) -> queued
| Durum | Anlamı |
|---|---|
queued | Oluşturuldu, henüz başlamadı |
blocked | Workspace'i başka bir job tutuyor; o bitince queued'a döner |
running | Bir süreçte çalışıyor ve workspace'in lease'ini tutuyor |
waiting_for_approval | Park etti: onay gerektiren bir çağrıya geldi |
completed, failed, cancelled | Bitti. Biten bir job bir daha hareket etmez. |
Her geçiş bu durum makinesine göre kontrol edilir ve zamanı ile nedeni job'un log'una yazılır. Log'u ivralo job <id> ile görebilirsiniz.
Park etmek: onay beklemek
Job, birinin evet demesi gereken yerde durur: bir düzenleme (permissions.json'daki allow_tools listesinde yoksa), politikanın onay istediği bir shell komutu ya da bir gönderim. Okumalar, Python, izin verilmiş komutlar ve reddedilen komutlar her zamanki gibi işler. Size yöneltilen bir soru (ask_user) ise reddedilir, çünkü başında kimse yoktur; bu durum job'u hiçbir zaman park ettirmez.
Bir çağrı onayınızı gerektirdiğinde job onu bir soru olarak kaydeder (ne yapacağı, etkisi ve riski), waiting_for_approval durumuna geçer, workspace'i bırakır ve 0 koduyla çıkar:
job 3f9a1c2e parked
it waits for a person: send_email - ivralo wants to send: send_email to=boss@example.com
answer it: ivralo resume 3f9a1c2e --approve (this call) | --approve-job (and every edit of this job) | --reject NOTE
Üç bayraktan biriyle cevap verirsiniz:
| Cevap | Etkisi |
|---|---|
ivralo resume <id> --approve | Evet, yalnızca bu çağrı için |
ivralo resume <id> --approve-job | Evet; bu job'un bundan sonraki bütün düzenlemeleri için de. Gönderimler ve shell komutları için hiçbir zaman geçerli değildir. |
ivralo resume <id> --reject "<note>" | Hayır. Model çağrının yerine notunuzu okur ve çalıştırma devam eder. |
Cevabı veren süreç job'u devam ettirir. Duraklatılan çalıştırma veritabanından geri okunur ve bekleyen çağrıdan devam eder; öncesindeki iş tekrar yapılmaz. Cevapsız bir ivralo resume <id> yalnızca soruyu ekrana basar ve hiçbir şeyi değiştirmeden 1 ile çıkar.
Park etmiş bir çağrıya yalnızca sizin cevabınız izin verebilir: ne bir bayrak, ne bir ayar, ne de bir yeniden deneme. Job önceden verilmiş bir onay taşımaz; bu yüzden bir gönderim her zaman park eder. Park etmiş job lease tutmaz, böylece aynı workspace'te kuyruktaki başka bir job bu arada çalışabilir.
Lease
Bir workspace'te aynı anda yalnızca bir job çalışır. Çalışan job, workspace'in lease'ini tutar: satırda süreç (pid ve host) ile sürecin her IVRALO_JOB_HEARTBEAT_SECONDS saniyede (varsayılan 10) yenilediği bir heartbeat yazar.
Heartbeat'i IVRALO_JOB_LEASE_SECONDS saniyeden (varsayılan 60) eski olan ya da süreci bu makinede artık bulunmayan lease bayatlamış sayılır ve sıradaki süreç onu devralır. Böylece bir çökme workspace'i hiçbir zaman kilitli bırakmaz.
Yerel API'ye gelen bir istek de lease'i aynı şekilde, bir api job'u üzerinden tutar. Bu sırada başlatılan bir job blocked olur ve istek bitince yeniden kuyruğa girer. api job'unu yalnızca API çalıştırır: ivralo resume onu reddeder, ivralo jobs run da hiçbir zaman seçmez.
Çökmeden sonra devam etmek
Süreci ölen bir job, kimsenin tutmadığı bir lease ile running durumunda kalır. ivralo resume <id> onu devralır:
step 3 restarts; the attempt before it left: db.py changed (their versions from before are in history)
Teslim edilmiş adımlar tamamlanmış sayılır. Yarıda kalan adım baştan çalışır. Kesilen denemenin yaptığı değişiklikler workspace'te kalır: hiçbir şey kendiliğinden geri alınmaz, gerisi için ivralo restore var. Request job'u isteğini baştan çalıştırır ve bunu açıkça söyler.
Komutlar
| Komut | Ne yapar |
|---|---|
ivralo jobs (ya da jobs list) | Bu workspace'in job'ları, en yeniden eskiye: id, durum, yaş, tür, sürmekte olan adım, park etmiş job'un beklediği araç |
ivralo job <id> | Tek bir job'un tüm ayrıntısı: durumu, lease'i, park ettiği soru, log'u |
ivralo resume <id> | Job'u devam ettirir: çökmeden sonra, kuyrukta bekleyen ya da cevabı verilmiş park etmiş bir job'u |
ivralo cancel <id> | Çalışan, park etmiş, bloklanmış ya da kuyruktaki bir job'u durdurur ve cancelled olarak kaydeder |
ivralo jobs run | Kuyruktaki en eski job'u, o yoksa cevabı verilmiş en eski park etmiş job'u çalıştırır ve çıkar |
ivralo jobs run, işletim sisteminin zamanlayıcısının çağırdığı komuttur. Çalıştıracak bir şey yoksa bunu söyler ve 0 ile çıkar. Bu komutu --jobs ile oluşturulan bir zamanlama kaydeder; bkz. Zamanlanmış istekler. Komutlar sonucu stdout'a yazar. Bilinmeyen bir id, bitmiş bir job ya da kapalı bir veritabanı ise stderr'e yazılır ve 1 çıkış koduyla biter; böylece script'lerde rahatça kullanılabilirler.
Bildirimler
Telegram ya da Slack ayarlıysa (IVRALO_TELEGRAM_BOT_TOKEN ile IVRALO_TELEGRAM_CHAT_ID, ya da IVRALO_SLACK_WEBHOOK_URL), job park ettiğinde, tamamlandığında ya da başarısız olduğunda tek satırlık bir mesaj gönderilir:
3f9a1c2e parked: send_email - ivralo wants to send: send_email to=boss@example.com; ivralo resume 3f9a1c2e --approve
3f9a1c2e completed
3f9a1c2e failed: step 2 did not deliver: b.md (absent)
Bu satırı model değil, her zaman ivralo yazar. Kanal ayarlı değilse hiçbir şey gönderilmez; durumu ivralo jobs ile görebilirsiniz.
Oturumda
Oturum bu workspace'in job'larını beş saniyede bir okur. Üst çubukta bir tanesi görünür: varsa park etmiş job, yoksa çalışan job ve adımı. /jobs hepsini listeler. Park etmiş bir job için /jobs <id>, job'un kabul ettiği üç cevapla onay penceresini açar. /plan --job bir plan taslağı çıkarır ve siz onaylayınca onu job olarak çalıştırır. Oturum job'ları hiçbir zaman kendisi çalıştırmaz: verdiğiniz cevap, ayrı bir süreçte ivralo resume başlatır. Yani oturumu kapatmak job'u hiç etkilemez.