Joblarin idempotent oldugunu varsayiyorum, haliyle herhangi bir hata durumunda tekrar ederse guvenli bir sekilde tekrar calisabilir ve veriyi bozmayacagi dusunerek yanit veriyorum.
Joblar seri olmak zorunda mi yoksa paralel’de islenebilirler mi (birbirlerine dependencyleri var mi)? Tabi bir de en sonunda sonuclarin ne olduguyla ilgileniyor musun? (kaci tamamlandi, kaci hata aldi vs)
Biz ihtiyaca gore iki farkli yontem ile ilerliyoruz. Eger bu bir data migration vb gibi kullaniciya yansimayan ve tek seferde yapacagimiz bir is ise Shopify/maintenance_tasks gem’ini kullaniyoruz. Boylelikle akisi takip edip isin ne kadari tamamlandi gorebiliyoruz. Dezavantaji seri calismasi. Bir de paralel calissa tadindan yenmez. Gerci bu gem’i isleri queue’ya atmak icin kullanip paralele de cevirebilirsin ama ben simdilik ihtiyac duymadim. Ozellikle data migration konusunda dogru pratikleri takip edersen ne kadar surdugunun cok uzmemesi gerekir.
Ikinci yontemimiz ise cogunlukla musterinin tetikledigi bulk olarak alinip tek tek islenmesi gereken islerde ortaya cikiyor. Orn musteriden gelen bir product filtresine gore (kac urun oldugu filtrenin ne kadar urun icerdigiyle orantili) her product icin bir servisin cagirilmasi gibi. Bu durumda da Shopify/job-iteration kullaniyoruz. Guzel tarafi job uzunsa ve calisirken interrupt edilirse kaldigi yerden devam edebilmesi. Boylelikle restart sonrasi job bastan baslamiyor. Ayni zamanda sagladigi on_start, on_complete gibi callbackler ile de musteriye anlik job’in ne kadarinin tamamlandigi geri bildirimini verebiliyoruz.
Diger bir yontem de bahsettigin gibi fire & forget
Dikkat etmeni onerdigim bazi kisimlar var ozellikle her is icin job paslayacaksan. Redis’inin buyuklugune dikkat etmen gerek. Zira daha joblari paslarken redisi doldurursan uzulebilirsin. Ayrica mumkun mertebe bu isi normal queuelarin disinda yap. Eger musterilerin kullandigi ya da default queue icinde yaparsan uygulamanin diger kisimlari queue icinde geride kalacaklarindan gecikmeler yasanabilir (yeni islerin islenmesi gecikiyor). Son olarak exception handling onemli Yoksa hata sirasinda bugsnag vb gibi bir sistemden hata yagdigi oluyor (bizzat yapmisligim var:))
Aslında maintance gem’ine ihtiyaç yok gibi duruyor. Ama belki düşünülebilir ki biz de kullanıyoruz başka işlerde onu.
Yaşar güzel sordu. Bu bir veri tabanına bulk veri import yapma işi. Job’ların hepsi ayni tipten aynı işi yapan job’lar. Tek seferlik çalışıyorlar. Gerçi retry’ları var ama bence olmamalı o ayrı konu. Zamanlanmış değil biz kendimiz import edeceğimiz vakit trigger ediyoruz. Verilen veriyi DB’ye yazıyor ya da var olan veriyi güncelliyor. Birden fazla tabloya dokunabilir. Ama job’larin hepsi aynı worker tarafından oluşturuluyor. Yani bir batch’deki job’lar yani worker’dan geliyor. Zaman kısıtımız yok parallel koşulabilir job’lar birbirini ile alakası yok. Beklemelerine gerek yok birbirlerini.