Workflow Automation

بناء سير عمل متعدد اللغات باستخدام Temporal

غالباً ما تقدم بنية الخدمات المصغرة (Microservices) تعقيداً في إدارة المعاملات الموزعة. وبينما تكون الخدمات مفككة الارتباط، فإن تنسيق تفاعلاتها يتطلب تنسيقاً قوياً. يعالج Temporal هذا الأمر من خلال توفير قدرات التنفيذ الدائم، مما يسمح للمطورين بكتابة سير عمل موثوق بطريقة تتحمل الأعطال. يستكشف هذا الدليل كيفية الاستفادة من Temporal مع Python و Go و TypeScript، لإنشاء بيئة عميل متعددة اللغات حقاً.

قوة العملاء متعددي اللغات

إحدى أقوى ميزات Temporal هي واجهات برمجية (SDKs) مستقلة عن اللغة. يمكن للفرق اختيار اللغة الأفضل لكل خدمة دون التضحية باتساق سير العمل. سواء كان الخلفية الأساسية (core backend) مكتوبة بـ Go للأداء، أو طبقة معالجة البيانات بـ Python للتحليلات، أو تكامل الواجهة الأمامية بـ TypeScript، يوفر Temporal نموذج برمجة موحداً باستخدام لغة تعريف سير العمل (WDL).

تعريف سير العمل في Go

غالباً ما تكون Go العمود الفقري للخدمات المصغرة عالية الأداء. في Temporal، يُعرف سير عمل Go كدالة عادية. المفتاح هو استخدام دالة workflow.ExecuteActivity، والتي تسمح لك باستدعاء الأنشطة (دوال عديمة الحالة) التي تؤدي العمل الفعلي.

package main

import (
    "go.temporal.io/sdk/workflow"
)

func MyWorkflow(ctx workflow.Context) error {
    ao := workflow.ActivityOptions{
        StartToCloseTimeout: 10 * time.Second,
    }
    ctx = workflow.WithActivityOptions(ctx, ao)

    var result string
    // Execute activity and wait for completion
    err := workflow.ExecuteActivity(ctx, GreetActivity, "Hello").Get(ctx, &result)
    return err
}

func GreetActivity(ctx context.Context, name string) (string, error) {
    return "Greeting: " + name, nil
}

تنفيذ العمال في Python

يستفيد مطورو Python من الزخارف (decorators) البديهية في Temporal. تبسط الزخارف @workflow.defn و @activity.defn تسجيل سير العمل والأنشطة. يحافظ هذا النهج على نظافة منطق الأعمال ويفصل بين تدفق التحكم في سير العمل وتنفيذ النشاط.

from temporalio import workflow
from temporalio import activity
from typing import Dict

@activity.defn
async def greet_activity(name: str) -> str:
    return f"Greeting: {name}"

@workflow.defn
class MyWorkflow:
    @workflow.run
    async def run(self, name: str) -> str:
        result = await workflow.execute_activity(
            greet_activity,
            name,
            schedule_to_close_timeout=timedelta(seconds=10)
        )
        return result

تكامل العميل مع TypeScript

تعد عملاء TypeScript مثالية للدوال الخالية من الخادم (serverless functions) أو العمال المتصلين بالواجهة الأمامية. توفر الواجهة البرمجية واجهات آمنة من حيث الأنواع (type-safe) تتماشى جيداً مع ممارسات تطوير الويب الحديثة. يمكنك بدء سير العمل والاستعلام عن حالته مباشرة من تطبيقات Node.js الخاصة بك.

import { Client } from '@temporalio/client';

async function startWorkflow() {
    const client = new Client({
        connectionOptions: {
            address: 'localhost:7233',
        },
    });

    const handle = await client.start('MyWorkflow', {
        taskQueue: 'default',
        args: ['World'],
    });

    console.log(`Workflow started with ID: ${handle.workflowId}`);
}

startWorkflow();

أفضل الممارسات للبيئات متعددة اللغات

عند العمل عبر لغات متعددة، يعد الاتساق أمراً أساسياً. تأكد من استخدام جميع العملاء لنفس إصدار خادم Temporal لتجنب مشاكل التوافق. استخدم واجهات مشتركة أو مخططات Protobuf لهياكل البيانات الممررة بين الأنشطة في لغات مختلفة. يمنع هذا أخطاء التسلسل ويضمن سلامة الأنواع عبر سير العمل بأكمله.

الخاتمة

يتيح Temporal للمطورين بناء خدمات مصغرة مرنة وقابلة للتوسع دون أن يكونوا محبوسين في نظام بيئي للغة واحدة. من خلال الاستفادة من Python و Go و TypeScript، يمكن للفرق الاستفادة من نقاط القوة في كل لغة مع الحفاظ على نموذج تنفيذ موحد. أثناء اعتمادك لهذه الأنماط، ركز على التنفيذ الدائم وتحمل الأعطال لتسليم تطبيقات قوية يمكنها تحمل الأعطال بسلاسة.

Share: