Serverless & İş Akışı Orkestrasyonu 5 dk okuma 2 okunma

Durable Functions ile Uzun Süreli İş Akışları

Durable Functions, Azure Functions üzerinde durumlu (stateful) ve uzun süreli iş akışları yazmayı sağlar. Replay tabanlı event sourcing ile çökmelere ve yeniden başlatmalara dayanıklıdır. Orchestrator, Activity ve Entity fonksiyon rolleri; insan etkileşimi, timer ve fan-out/fan-in desenleri; .NET Isolated Worker modelinde determinizm kuralları ve continue-as-new mekanizması ele alınır.

Durable Functions ile Uzun Süreli İş Akışları

Durable Functions ile Uzun Süreli İş Akışları

Durable Functions, Azure Functions üzerinde durumlu (stateful) orkestrasyonlar yazmayı sağlayan bir uzantıdır. Normal serverless fonksiyonlar durumsuzdur ve 15 dakikalık bir çalışma süresiyle sınırlıdır; Durable Functions ise bu sınırı aşarak günler, haftalar hatta aylar sürebilen iş akışlarını yönetir . Bunu, event sourcing ve replay mekanizmasıyla başarır: her işlem bir olay kaydına yazılır, çökme durumunda iş akışı bu kayıtlardan yeniden oynatılarak kaldığı yerden devam eder .


1. Temel Yapı Taşları: Fonksiyon Rolleri

Durable Functions uygulaması, her biri belirli bir sorumluluğa sahip dört fonksiyon türünden oluşur :

Rol Görevi Tanımı
Orchestrator İş akışı mantığını koordine eder; adımları sıralar, dallandırır, sonuçları birleştirir. Orchestration trigger
Activity Tek bir iş birimini gerçekleştirir: HTTP çağrısı, veritabanı yazımı, model çağrısı. Activity trigger
Entity Küçük, kalıcı bir durumu yönetir; dağıtık kilit veya durumlu nesne modellemesi. Entity trigger
Client Orkestrasyonu başlatır, durumunu sorgular, olay gönderir. Durable client binding

Kritik Ayrım: Orchestrator yalnızca koordinasyon yapar; dış sistemlerle etkileşim kuran tüm işlemler Activity fonksiyonlarında olur .


2. Determinizm: Orchestrator'ın En Kritik Kuralı

Orchestrator kodu, replay mekanizması nedeniyle deterministik olmak zorundadır. Aynı girdi ve olay geçmişi, her replay'de aynı işlem sırasını üretmelidir .

Orchestrator'da Yasak Olan İşlemler:

  • Doğrudan HTTP, veritabanı, dosya sistemi veya Azure SDK çağrıları

  • DateTime.Now, datetime.now() gibi sistem saati okumaları

  • Rastgele sayı üreticileri ve deterministik olmayan UUID API'leri

  • Task.Delay() gibi bloklayan beklemeler; bunun yerine CreateTimer kullanılmalıdır

Deterministik Zaman ve UUID:

csharp

// ❌ Yanlış: Replay'de farklı sonuç üretir
var now = DateTime.UtcNow;
var id = Guid.NewGuid();

// ✅ Doğru: Replay-güvenli API'ler
var now = context.CurrentUtcDateTime;
var id = context.NewGuid();

3. Uzun Süreli Beklemeler: Durable Timer

Klasik Task.Delay() bir worker thread'ini bloke eder ve uzun süreli beklemelerde maliyetlidir. Durable Functions'ın CreateTimer API'si ise belirtilen süre boyunca tamamen ücretsizdir; Consumption plan'da beklerken hiçbir ücret alınmaz .

csharp

[Function("OrderWorkflow")]
public async Task RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    // 7 gün bekle (ücretsiz)
    await context.CreateTimer(
        context.CurrentUtcDateTime.AddDays(7),
        CancellationToken.None);
    
    await context.CallActivityAsync("SendReminder", "Order-123");
}

Kullanım Senaryoları: Sipariş sonrası takip e-postası, abonelik yenileme hatırlatması, zaman aşımlı onay süreçleri .


4. İnsan Etkileşimi: External Events

Durable Functions, insan onayı bekleyen iş akışları için WaitForExternalEvent API'si sunar. Orkestrasyon, dış bir sinyal gelene kadar süresiz bekleyebilir .

csharp

[Function("ApprovalWorkflow")]
public async Task RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    await context.CallActivityAsync("RequestApproval", approvalInfo);
    
    // 72 saat boyunca onay bekle
    using var cts = new CancellationTokenSource();
    var timeoutTask = context.CreateTimer(
        context.CurrentUtcDateTime.AddHours(72), cts.Token);
    var approvalTask = context.WaitForExternalEvent<bool>("ApprovalEvent");
    
    var winner = await Task.WhenAny(timeoutTask, approvalTask);
    
    if (winner == approvalTask)
    {
        cts.Cancel();
        if (approvalTask.Result)
            await context.CallActivityAsync("ProcessApproval", approvalInfo);
    }
    else
    {
        // Zaman aşımı: eskalasyon
        await context.CallActivityAsync("Escalate", approvalInfo);
    }
}

Olay Gönderme (HTTP API):

bash

curl -d "true" http://localhost:7071/runtime/webhooks/durabletask/instances/{instanceId}/raiseEvent/ApprovalEvent

5. Fan-Out/Fan-In: Paralel İşleme

Durable Functions, birden fazla Activity'yi paralel çalıştırıp sonuçlarını birleştirmeyi kolaylaştırır .

csharp

[Function("BatchProcessing")]
public async Task RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    var files = context.GetInput<string[]>();
    
    // Fan-out: Tüm dosyaları paralel işle
    var tasks = files.Select(file =>
        context.CallActivityAsync<Result>("ProcessFile", file));
    
    // Fan-in: Hepsini bekle
    var results = await Task.WhenAll(tasks);
    
    await context.CallActivityAsync("AggregateResults", results);
}

Kullanım Alanları: ETL süreçleri, toplu raporlama, AI ajanlarıyla paralel veri toplama .


6. Sonsuz Orkestrasyonlar: continue-as-new

Sürekli çalışan bir orchestrator (ör. periyodik temizlik), her iterasyonda olay geçmişini biriktirir ve zamanla bellek/performans sorunlarına yol açar. continue-as-new API'si, geçmişi sıfırlayarak aynı instance ID ile orchestrator'ı yeniden başlatır .

csharp

[Function("PeriodicCleanup")]
public async Task RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    var input = context.GetInput<CleanupInput>();
    
    // Temizlik işini yap
    await context.CallActivityAsync("CleanupOldRecords", input.CutoffDate);
    
    // Bir sonraki iterasyon için timer
    await context.CreateTimer(
        context.CurrentUtcDateTime.AddHours(1), CancellationToken.None);
    
    // Geçmişi sıfırla ve yeniden başlat
    context.ContinueAsNew(new CleanupInput 
    { 
        CutoffDate = context.CurrentUtcDateTime.AddDays(-30) 
    });
}

Önemli Detaylar:

  • Aynı instance ID korunur, ancak yeni bir execution ID oluşturulur .

  • Bekleyen timer'lar ve tamamlanmamış görevler iptal edilir .

  • C# ve Java'da işlenmemiş harici olaylar varsayılan olarak korunur .


7. Sürüm ve Altyapı Notları (2026)

  • Durable Functions v3.x önerilen sürümdür; v2.x'ten geçiş kod değişikliği gerektirmez .

  • Azure Storage SDK güncellenmiştir: Azure.Data.Tables, Azure.Storage.Blobs, Azure.Storage.Queues .

  • Partition Manager V3 varsayılan hale gelmiştir; depolama maliyetini düşürür ve debug'ı kolaylaştırır .

  • Functions Runtime v1 desteği Eylül 2026'da sona ermektedir .


8. Durable Functions vs. Alternatifler

Özellik Durable Functions AWS Step Functions Temporal
Tanım Yöntemi Kod (C#, JS, Python) ASL (JSON/DSL) veya görsel Kod (Go, Java, TypeScript)
Çalışma Yeri Azure Functions runtime Bağımsız servis Kendi worker'ınız
Maksimum Süre Sınırsız (continue-as-new ile) 1 yıl (Standard) Sınırsız
Görsel Arayüz Durable Task Scheduler Step Functions Studio Temporal UI
En Uygun Senaryo Kod-ağırlıklı, Lambda-içi iş akışları Servisler arası görsel orkestrasyon Cross-cloud, karmaşık retry

Tavsiye: Kod-ağırlıklı ve Lambda-içi iş akışları için Durable Functions; birden fazla AWS servisini kapsayan görsel orkestrasyon için Step Functions; cross-cloud ve daha zengin workflow tooling için Temporal değerlendirilebilir .


9. En İyi Pratikler

Pratik Açıklama
Orchestrator'ı Deterministik Tutun Tüm I/O işlemlerini Activity'lere taşıyın .
Activity'leri Idempotent Yapın At-least-once çalışma garantisi nedeniyle tekrarlar olabilir .
Timer Kullanın Task.Delay() yerine CreateTimer; beklerken ücret alınmaz .
continue-as-new Kullanın Sonsuz döngülerde geçmiş birikmesini önleyin .
Kritik Bölümler için Entity Kullanın Paylaşılan durumda yarış koşullarını önlemek için .
Hata Yönetimi Yapın try/catch ve retry politikaları ile dayanıklılık sağlayın .

Sonuç

Durable Functions, serverless ortamda uzun süreli, durumlu iş akışlarını kod yazarak oluşturmanın en olgun yoludur. Replay tabanlı event sourcing ile çökmelere ve yeniden başlatmalara dayanıklıdır; Durable Timer ile ücretsiz beklemeler, External Events ile insan onayı, Fan-Out/Fan-In ile paralel işleme ve continue-as-new ile sonsuz orkestrasyonlar sağlar. Determinizm kuralına uyulduğu sürece, karmaşık iş akışlarını basit ve sürdürülebilir bir kod tabanıyla yönetebilirsiniz.

Tüm yazılar Soru ya da yorumun mu var? Yaz