ORTA
Continuations & Batch Jobs
Continuations, bir job tamamlandığında otomatik olarak tetiklenen zincir job'lardır. Batch ise Hangfire Pro ile gelen atomik job grubudur.
Karar Rehberi
| Durum | Öneri | Örnek veya gerekçe |
|---|---|---|
| Sıralı iş akışı | Uygun: Continuation (Core, ücretsiz) | Sipariş: validate → charge → ship |
| Paralel toplu işlem | Uygun: Batch ( Pro, ücretli) | 50 resmi aynı anda resize |
| Basit 2 adımlı iş | Uygun değil: Tek job içinde yap | Overkill karmaşıklık |
| Saga/distributed tx | Uygun değil: Orchestrator pattern | MassTransit Saga daha uygun |
Continuation Kullanımı
// Basit continuation
var jobId = BackgroundJob.Enqueue<IOrderService>(
svc => svc.ValidateOrderAsync(orderId));
BackgroundJob.ContinueJobWith<IPaymentService>(jobId,
svc => svc.ChargeCustomerAsync(orderId));
// Zincirleme continuation (pipeline)
var validateId = BackgroundJob.Enqueue<IOrderService>(
svc => svc.ValidateOrderAsync(orderId));
var chargeId = BackgroundJob.ContinueJobWith<IPaymentService>(validateId,
svc => svc.ChargeCustomerAsync(orderId));
var shipId = BackgroundJob.ContinueJobWith<IShippingService>(chargeId,
svc => svc.InitiateShipmentAsync(orderId));
BackgroundJob.ContinueJobWith<INotificationService>(shipId,
svc => svc.SendOrderShippedAsync(orderId));Batch Jobs ( Hangfire Pro — Ücretli Lisans Gerektirir)
Bu bölüm ücretli Hangfire.Pro NuGet paketi gerektirir. Community (ücretsiz) sürümde BatchJob sınıfı YOKTUR. Eklemeye çalışırsanız derleme hatası alırsınız. Fiyatlandırma: hangfire.io/pricing
// Program.cs — Batch'leri aktifleştirme (Pro lisans sonrası)
builder.Services.AddHangfire(config => config
.UseSqlServerStorage(connectionString)
.UseBatches() // Hangfire.Pro paketi gerekli!
.UseBatchesV2()); // İsteğe bağlı: gelişmiş batch özellikleri// Atomik batch — hepsi birlikte oluşturulur
var batchId = BatchJob.StartNew(batch =>
{
batch.Enqueue<IImageService>(svc => svc.ResizeAsync(imageId, "thumb"));
batch.Enqueue<IImageService>(svc => svc.ResizeAsync(imageId, "medium"));
batch.Enqueue<IImageService>(svc => svc.ResizeAsync(imageId, "large"));
});
// Batch tamamlandığında continuation
BatchJob.ContinueBatchWith(batchId, batch =>
{
batch.Enqueue<ICdnService>(svc => svc.InvalidateCacheAsync(imageId));
});Ücretsiz alternatif: Batch ihtiyacınız basitse (paralel değil sıralı), continuation chain ile aynı sonucu Core ile elde edebilirsiniz. Batch'in farkı: atomik oluşturma + paralel çalışma + toplu completion callback.
JobContinuationOptions
// Varsayılan: Sadece parent Succeeded olunca çalış
BackgroundJob.ContinueJobWith<INotificationService>(parentId,
svc => svc.NotifyAsync(orderId),
JobContinuationOptions.OnlyOnSucceededState); // default
// Parent başarısız olsa bile çalış (cleanup logic)
BackgroundJob.ContinueJobWith<ICleanupService>(parentId,
svc => svc.ReleaseLocksAsync(orderId),
JobContinuationOptions.OnAnyFinishedState); // Succeeded VEYA Failed| Option | Tetiklenme | Kullanım |
|---|---|---|
OnlyOnSucceededState (default) |
Parent succeeded | Normal pipeline |
OnAnyFinishedState |
Parent succeeded VEYA failed | Cleanup, resource release |
Continuation dikkat noktası: Parent job başarısız olursa (varsayılan ayarla) continuation tetiklenmez. Retry sonrası başarılı olursa tetiklenir. Parent Deleted state'e geçerse continuation da silinir. Cleanup gereken durumlarda OnAnyFinishedState kullanın.
Örnek: Bir medya platformunda video yükleme pipeline'ı: Upload → Transcode (480p, 720p, 1080p batch) → Thumbnail → CDN Push → Notify User. Her adım bağımsız retry'a sahip ve tüm batch bitince kullanıcı bilgilendirilir.