Kendini bekleyen bekleme döngüsü

Claude'dan, Codex filmi kurmayı bitirir bitirmez render almasını istedim. Codex 18:35'te bitirdi. 19:17'de durumu sorduğumda render hâlâ başlamamıştı. Hiçbir şey çökmemişti; bekleme döngüsü kendini izliyordu.
Ne oldu
Kurulum sıradandı. Codex arka planda kısa bir Salvor filminin üçüncü sürümünü kuruyordu. Claude'un işi Codex bitene kadar beklemek, sonra kareleri render edip videoyu bana göndermekti. Beklemek için Claude arka planda küçük bir döngü başlattı:
while pgrep -f "codex exec.*film3d" >/dev/null; do sleep 20; done
node render.cjs
pgrep -f çalışan her işlemin tam komut satırında arama yapar ve eşleşen bir şey olduğu sürece başarılı döner. Fikir basitti: Codex çalıştığı sürece uyu, kaybolunca render al.
Codex 18:35'te bitti ve son raporunu yazdı. Döngü uyumaya devam etti. 19:17'de "durum ne?" diye sordum ve Claude sebebi buldu: desene hâlâ uyan tek işlemler kendi bekleme döngüleriydi.
Neden hiç bitmedi
Claude'un kabuk aracı her komutu bash -c "<komutun tamamı>" olarak çalıştırır. Yani döngünün kendi komut satırında codex exec.*film3d yazısı geçiyor ve pgrep -f döngünün kendisini buluyor. Döngü bir işlemi bekliyor ve o işlem döngünün kendisi. Hiçbir zaman bitemez.
O oturumda aynı hata üç bekleme döngüsünde vardı. İkisi sorun gibi görünmemişti, çünkü ben önemli olmadan önce başka işe geçmiştim. Üçüncüsü render'ı 45 dakika tuttu.
Çözüm, bir desen yerine belirli bir işlem numarasını beklemek:
nohup codex exec ... > codex.log 2>&1 &
echo $! > codex.pid
while kill -0 "$(cat codex.pid)" 2>/dev/null; do sleep 20; done
$! az önce başlatılan işin işlem numarasıdır. kill -0 sinyal göndermez, sadece o işlemin hâlâ yaşayıp yaşamadığına bakar. Desenle aramak şartsa köşeli parantez hilesi (pgrep -f "[c]odex exec") desenin kendi yazısıyla eşleşmesini engeller.
"Salvor yüklü değil mi? Neden hata yapıyorsun?"
Benim tepkim buydu ve haklı bir soru. Salvor'u, ajanlar oturumlar arasında aynı hataları tekrarlamasın diye kullanıyorum. Burada iki sebeple işe yaramadı.
- Salvor bir projenin içinde yaşar. İçinde
.salvorklasörü olan depolarda çalışır: oyun sitem, blogum, bu site. Film ise Salvor beyni olmayan düz bir çalışma klasöründe kuruluyordu. Okunacak bir proje hafızası yoktu. - Salvor tekrarı önler, ilk seferi değil. Öğrenilmiş bir hata, hata yaşandıktan ve bir insan kaydetmeye "evet" dedikten sonra yazılır. Bu hata ilk kez yaşanıyordu, okunacak bir şey henüz yoktu. Aracın çalışma şekli bu: ilk hata dersin bedelidir, hafıza da bu bedelin yalnızca bir kez ödenmesini sağlar.
Salvor işte tam da bu noktada devreye giriyor. Bir ajanın bir kez yaptığı hata, ikinci bir oturuma mal olmamalı. Salvor o ilk hatayı, bir insanın onayıyla depoda yazılı bir kurala çevirir; projeyi açan her ajan işe başlamadan önce o kuralı okur: bu gece Claude Code, yarın Codex, ertesi gün Gemini CLI.
Kayda geçirmek
Ders artık iki yerde kayıtlı. Claude'un kendi uzun süreli hafızasında bir not var: pgrep -f ile kurulan bekleme döngüleri kendileriyle eşleşir; kaydedilmiş bir işlem numarası kill -0 ile beklenmeli. Gelecekteki her oturum bu notu başta okuyor. Bu yazı da aynı dersin, arka planda bekleyen ajanı olan herkes için açık kaydı.
Döngü düzeltildikten sonra film nihayet render edildi. Süreç, filmin kendisinde anlatılanla aynıydı: bir hata, kaydedilen bir ders ve onu tekrarlamayan bir sonraki çalışma.
Bundan ne çıkardım
- Sessiz bekleme ilerleme gibi görünür. Hiçbir şey çökmedi, hiçbir hata yazılmadı. Bir iş olması gerekenden uzun sürüyorsa durumu sorun.
- Aracın kendi izine bakın. Çalışan işlemleri arayan bir komut, özellikle başka bir kabuğun içinde çalışıyorsa, kendini bulabilir.
- Hafızanın bir ilk kayda ihtiyacı var. Bir hafıza katmanı, içine yazılanlar kadar iyidir. Dersi hatadan hemen sonra kaydetmek, işi çalıştıran adımdır.
Yeni makaleleri e-postayla alın
Yalnızca yeni bir makale çıktığında. Reklam yok. Ayrıntılar →