Bu neden önemli?
Arka planda çalışan işler için genelde ayrı bir kuyruk, işçi servis ve durum tablosu kurulur. Verin zaten Postgres'teyse, bu parçaların bir kısmı gereksiz hale gelebilir.
Sorun: Yarıda kalan işler
Bir uygulamada her şey tek bir tıklamayla bitmez. Bazı işler dakikalar, hatta günler sürer:
- Binlerce belgeyi parçalayıp bir yapay zekâ servisine göndermek
- Her gece raporları yeniden hesaplamak
- Bir siparişin, bir yöneticinin onayını beklemesi
Bu işlerin ortak derdi şu: Arada bir şey ters gidebilir. Sunucu yeniden başlar, bir API cevap vermez, bağlantı kopar. Sonra da hangi adımın bittiğini, hangisinin yarım kaldığını bulmak için kod yazarsın.
Bunun için genelde bir yığın parça kurulur: zamanlama için cron, bir iş kuyruğu, kuyruğu dinleyen işçi (worker) programlar, yeniden deneme sayaçları, durumları tutan tablolar. Ya da Temporal, Airflow gibi ayrı bir orkestrasyon servisi.
Dayanıklı çalıştırma nedir?
Durable execution (dayanıklı çalıştırma), bu sorunu çözen genel bir yaklaşım. Fikir basit: Bir iş, küçük adımlardan oluşur. Her adım bitince sonucu diske kaydedilir (buna checkpoint denir). Bir şey çökerse iş baştan başlamaz, son kaydedilen noktadan devam eder.
Oyunlardaki kayıt noktalarını düşün. Karakterin ölünce oyunun başına değil, son kayıt noktasına dönersin.
pg_durable ne yapıyor?
pg_durable, Microsoft’un geliştirdiği açık kaynak bir PostgreSQL eklentisi. Dayanıklı çalıştırmayı ayrı bir servise gerek kalmadan veritabanının içine taşıyor. Rust ile yazılmış, PostgreSQL lisansıyla dağıtılıyor ve Postgres 17 ile 18’i destekliyor.
İşleyiş şöyle:
- İşi SQL ile adım adım tanımlıyorsun.
df.start(...)ile başlatıyorsun. Karşılığında bir kimlik (ID) alıyorsun.df.statusile durumuna,df.resultile sonucuna bakıyorsun.
Adımları birbirine bağlamak için küçük operatörler var: biri adımları sırayla çalıştırıyor, biri paralel çalıştırıyor, biri de bir adımın sonucunu bir değişkende saklıyor. Koşullu dallanma, döngü ve dışarıya HTTP isteği atmak da mümkün.
İki örnek
Zamanlanmış iş. Videoda her dakika çalışan bir döngü kuruluyor: Bir dakika bekle, sonra bir prosedürü çağırıp tabloya kayıt ekle. Zamanlama için ayrı bir cron servisine gerek kalmıyor, cron ifadeleriyle bekleyen bir fonksiyon zaten eklentinin içinde.
İnsan onayı. Daha ilginç olanı bu. İş önce bir siparişi seçiyor, sonra bir sinyal bekleyerek duruyor, 24 saate kadar. Bir yönetici başka bir yerden df.signal ile onay verince iş uyanıyor ve siparişi “onaylandı” olarak işaretliyor. Onay gelmezse “reddedildi” oluyor. Bu sırada sunucu yeniden başlasa bile bekleyen iş kaybolmuyor.
Ne zaman kullanmamalı?
Projenin kendi belgesi de sınırları açıkça yazıyor:
- İş zaten tek bir SQL komutuysa gereksiz.
- Milisaniyeler içinde cevap vermesi gereken istekler için değil.
- Barındırma servisin eklenti kurmana izin vermiyorsa kullanamazsın.
- İşin büyük kısmı Postgres dışında, birçok farklı sistemde geçiyorsa ayrı bir orkestrasyon aracı daha uygun olabilir.
Proje henüz 0.x sürümlerinde. Yani hızla gelişiyor ama arayüzü değişebilir.
Düşün
- Senin projende “yarıda kalırsa ne olur?” diye hiç düşünmediğin bir arka plan işi var mı?
- İşin mantığını veritabanına taşımak işleri basitleştirir mi, yoksa kodu takip etmeyi zorlaştırır mı?
Bu yazıdaki araçlar Araç Kutusu'nda: pg_durable