HHangfire Handbook

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.

Continuation Chain 1. Validate Sipariş kontrol 2. Charge Ödeme al 3. Ship Kargo başlat 4. Notify Müşteriye bildir Batch (Pro) Job A Resize image Job B Generate PDF Job C Send webhook Batch Complete Hepsi bitince çalış

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.