Workflow Automation

Temporal'i Ustalaşmak: Dayanıklı ve Uzun Süreli Çalışan İş Akışları Oluşturma

Modern dağıtık sistemler dünyasında, güvenilir arka plan işleri ve karmaşık çok adımlı süreçler yazmak son derece zordur. Geleneksel yaklaşımlar genellikle mesaj kuyruklarına, durum makinelerine veya basit cron işlerine dayanır, ancak bu çözümler çoğu zaman görünürlük, hata ayıklama ve kısmi hatalarla başa çıkmada zorluk çeker. İşte bu noktada Temporal devreye girer; geliştiricilere iş mantığını standart kod olarak yazmalarına olanak tanıyan, geliştirici deneyiminden ödün vermeden kalıcılığı ve güvenilirliği garanti eden bir iş akışı yürütme platformudur.

Temporal'in temel değer önermesi "Kalıcı Yürütme"dir (Durable Execution). Çökene veya tamamlanana kadar çalışan geleneksel kodun aksine, Temporal her fonksiyon çağrısının geçmişini kaydeder. Bir süreç yürütme sırasında çökerse, Temporal süreci son denetim noktasından (checkpoint) geri yükleyebilir ve tam olarak kaldığı yerden devam edebilir. Bu paradigma değişikliği, durum yönetiminin karmaşıklığını geliştiriciden platforma taşır.

Temel Mimari: İş Akışları ve Etkinlikler

Temporal'i anlamak için, iki temel bileşeni birbirinden ayırmanız gerekir: İş Akışları (Workflows) ve Etkinlikler (Activities).

  • İş Akışları: Orkestrasyon mantığıdır. İşlemlerin sırasını tanımlar, yeniden denemeleri (retry) yönetir ve zaman aşımını kontrol eder. Önemli olan nokta, İş Akışı kodunun deterministik olmasıdır. Bir İş Akışı fonksiyonu içinde doğrudan rastgele sayı üreteçleri, güncel zaman damgaları veya doğrudan veritabanı çağrıları kullanamazsınız. Bunun yerine, dış dünyayla Etkinlikler aracılığıyla etkileşime girersiniz.
  • Etkinlikler: Gerçek yan etki yaratan işlerdir. E-posta gönderme, veritabanı sorgulama veya harici bir API'ye çağrı yapma işlemleri burada gerçekleşir. Etkinlikler deterministik değildir ve Temporal'in işçileri (workers) tarafından yürütülür. Bir Etkinlik başarısız olursa, Temporal, yapılandırılmış politikalara göre bunu otomatik olarak yeniden deneyebilir; tüm İş Akışını baştan başlatmaya gerek kalmaz.

Python'da Pratik Uygulama

Temporal'in Python SDK'sını kullanan bir ödeme işleme iş akışının pratik bir örneğine bakalım. Bu desen, kart tahsilatı ile kullanıcının kaydının güncellenmesi arasında sunucu yeniden başlatılsa bile sistemin tutarlı kalmasını sağlar.


import time
from temporalio.client import Client
from temporalio.common import RetryPolicy
from temporalio.contrib.opentelemetry import TracingWorkflowInterceptor
from temporalio.worker import Worker
from temporalio.workflow import (
    ActivityError,
    define_workflow,
    workflow_activity,
    workflow_run,
    workflow_signal,
)

# 1. Etkinlikleri Tanımla (Yan Etkiler)
@workflow_activity(name="charge_credit_card")
async def charge_credit_card(amount: float, card_id: str) -> str:
    """Kredi kartı tahsilatını simüle et."""
    # Gerçek bir uygulamada bu, bir ödeme ağ geçidine çağrı yapar
    if amount > 1000:
        raise Exception("Ödeme reddedildi: Limit aşıldı")
    return f"tx_{int(time.time())}_{card_id}"

@workflow_activity(name="update_user_balance")
async def update_user_balance(user_id: str, transaction_id: str) -> None:
    """Kullanıcının dahili defterinin güncellenmesini simüle et."""
    # Gerçek bir uygulamada bu, veritabanına yazar
    print(f"{user_id} için {transaction_id} işlemi ile bakiye güncelleniyor")

# 2. İş Akışını Tanımla (Orkestrasyon)
@define_workflow(name="PaymentProcessingWorkflow")
class PaymentProcessingWorkflow:
    async def __init__(self, amount: float, card_id: str, user_id: str):
        self.amount = amount
        self.card_id = card_id
        self.user_id = user_id

    async def run(self):
        """
        Bu kod deterministiktir.
        Temporal, olay geçmişine dayanarak bu mantığı yeniden oynatır.
        """
        # Etkinliği çalıştır.
        # Bu başarısız olursa, Temporal bunu varsayılan politikaya göre yeniden dener.
        transaction_id = await self._activity(
            charge_credit_card, 
            self.amount, 
            self.card_id
        )
        
        # Gerekirse bir sinyali bekleyin (ör. manuel onay)
        # await self._signal("approval_received")

        # Defteri güncelle
        await self._activity(
            update_user_balance, 
            self.user_id, 
            transaction_id
        )
        
        return transaction_id

    # Etkinlikleri çağırmak için yardımcı fonksiyon
    async def _activity(self, activity_func, *args, **kwargs):
        return await activity_func(*args, **kwargs)

# 3. Bir İşçi Çalıştır (Uygulama hizmetinizin çalıştırdığı şey budur)
async def main():
    client = await Client.connect("localhost:7233", namespace="default")
    
    async with Worker(
        client,
        task_queue="payment-queue",
        workflows=[PaymentProcessingWorkflow],
        activities=[
            charge_credit_card,
            update_user_balance
        ]
    ) as worker:
        print("İşçi hazır")
        await worker.run()

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Alternatifler Yerine Neden Temporal?

AWS Step Functions veya Azure Durable Functions gibi sistemler benzer yetenekler sunsa da, genellikle sizi belirli bulut sağlayıcılarına kilitleyebilir veya iş akışlarını JSON/YAML üzerinden tanımlamanızı zorlayabilir. Temporal açık kaynaklı ve kendi kendine barındırılabilecek (self-hostable) bir platformdur; altyapınız üzerinde tam kontrol sağlar. Ayrıca, iş akışlarını ana akım dillerde (Python, Go, TypeScript, Java, .NET) yazdığınız için mevcut kod tabanlarınızdan, birim test çerçevelerinizden ve IDE desteğinizden yararlanabilirsiniz.

En güçlü özelliklerden biri Görünürlüktür (Visibility). Temporal ile iş akışlarınızın durumunu görmek için özel bir günlük (logging) paneli oluşturmanıza gerek yoktur. Temporal arayüzü, herhangi bir iş akışı yürütmesini denetlemenize, olayların tam sırasını görmenize, yürütülen kodu incelemenize ve hatta çalışan iş akışlarının davranışını gerçek zamanlı olarak değiştirmek için sinyaller tetiklemenize olanak tanır.

Sonuç

Temporal, dağıtık sistemlerdeki en zorlu sorunları çözer: güvenilirlik, gözlemlenebilirlik ve karmaşıklık. Durum yönetimini ve hata işleme mekanizmalarını soyutlayarak, geliştiricilerin altyapı yapıştırıcı kodları (glue code) yerine iş mantığına odaklanmasını sağlar. Veri hattı, sipariş karşılama sistemi veya karmaşık mikro hizmet etkileşimleri geliştiriyor olun, Tempolar ölçeklenebilir ve dayanıklı otomasyon için sağlam bir temel sunar. Uzun süreli çalışan süreçlerle uğraşıyorsanız, cron işlerinin ötesine geçmenin ve Kalıcı Yürütme (Durable Execution) terimleriyle düşünmeye başlamanın zamanı gelmiştir.

Share: