انتقل إلى المحتوى

السلاسل المتتابعة

النمط الأكثر شيوعًا لسير العمل هو سلسلة خطية من الخطوات. تُنفّذ كل خطوة بعد اكتمال السابقة، مع تمرير الحالة المتراكمة إلى الخطوة التالية.

طريقة ->then()

استخدم ->then() لإضافة خطوات متتابعة إلى سير عمل:

PHP
use Queuety\Queuety;

Queuety::workflow( 'onboarding' )
    ->then( CreateAccountHandler::class )
    ->then( SendWelcomeEmailHandler::class )
    ->then( NotifyAdminHandler::class )
    ->dispatch( [ 'email' => 'user@example.com' ] );

تُنفّذ الخطوات بالترتيب الذي أُضيفت به. ولا يتقدم سير العمل إلا عند اكتمال الخطوة الحالية بنجاح.

واجهة Step

تنفذ معالجات خطوات سير العمل واجهة Queuety\Step:

PHP
use Queuety\Step;

class CreateAccountHandler implements Step {
    public function handle( array $state ): array {
        $user_id = wp_create_user( $state['email'], wp_generate_password() );
        return [ 'user_id' => $user_id ];
    }

    public function config(): array {
        return [
            'max_attempts' => 3,
        ];
    }
}

الفروق الرئيسية عن واجهة Handler:

Handler (المهام) Step (عمليات سير العمل)
توقيع الطريقة handle(array $payload): void handle(array $state): array
الإدخال حمولة المهمة حالة سير العمل المتراكمة
الإخراج لا شيء (void) بيانات تُدمج في الحالة

تدفق الحالة

تتلقى كل خطوة الحالة المتراكمة كاملة وتعيد مصفوفة من أزواج المفاتيح والقيم الجديدة. تُدمج البيانات المعادة في الحالة لتستخدمها الخطوات التالية:

PHP
class FetchUserHandler implements Step {
    public function handle( array $state ): array {
        // $state contains: ['user_id' => 42]
        $user = get_user_by( 'ID', $state['user_id'] );
        return [ 'user_name' => $user->display_name, 'user_email' => $user->user_email ];
    }

    public function config(): array {
        return [];
    }
}

class GenerateReportHandler implements Step {
    public function handle( array $state ): array {
        // $state contains: ['user_id' => 42, 'user_name' => 'Alice', 'user_email' => 'alice@example.com']
        $report = build_report( $state['user_name'] );
        return [ 'report_url' => $report->url ];
    }

    public function config(): array {
        return [];
    }
}

إعداد الخطوة

تدعم طريقة config() المفاتيح التالية:

المفتاح النوع القيمة الافتراضية الوصف
max_attempts int 3 الحد الأقصى لمحاولات إعادة تنفيذ هذه الخطوة
backoff string exponential استراتيجية الانتظار بين محاولات الإعادة

مثال على مسار معالجة LLM

من حالات الاستخدام الشائعة تسلسل استدعاءات LLM API مع معالجة البيانات:

PHP
use Queuety\Step;

class BuildPromptHandler implements Step {
    public function handle( array $state ): array {
        $user = get_user_by( 'ID', $state['user_id'] );
        $posts = get_posts( [ 'author' => $user->ID, 'numberposts' => 10 ] );
        $context = implode( "\n", array_map( fn( $p ) => $p->post_content, $posts ) );

        return [
            'prompt' => "Summarize this author's recent work:\n\n{$context}",
        ];
    }

    public function config(): array {
        return [];
    }
}

class CallOpenAIHandler implements Step {
    public function handle( array $state ): array {
        $response = wp_remote_post( 'https://api.openai.com/v1/chat/completions', [
            'timeout' => 120,
            'headers' => [
                'Authorization' => 'Bearer ' . OPENAI_API_KEY,
                'Content-Type'  => 'application/json',
            ],
            'body' => json_encode( [
                'model'    => 'gpt-4',
                'messages' => [ [ 'role' => 'user', 'content' => $state['prompt'] ] ],
            ] ),
        ] );

        $body = json_decode( wp_remote_retrieve_body( $response ), true );
        return [ 'summary' => $body['choices'][0]['message']['content'] ];
    }

    public function config(): array {
        return [ 'max_attempts' => 5 ];
    }
}

class SaveSummaryHandler implements Step {
    public function handle( array $state ): array {
        $post_id = wp_insert_post( [
            'post_title'   => "Summary for user #{$state['user_id']}",
            'post_content' => $state['summary'],
            'post_status'  => 'publish',
        ] );
        return [ 'summary_post_id' => $post_id ];
    }

    public function config(): array {
        return [];
    }
}

أطلق مسار المعالجة:

PHP
Queuety::workflow( 'summarize_author' )
    ->then( BuildPromptHandler::class )
    ->then( CallOpenAIHandler::class )
    ->then( SaveSummaryHandler::class )
    ->on_queue( 'llm' )
    ->max_attempts( 5 )
    ->dispatch( [ 'user_id' => 42 ] );

إذا انتهت مهلة استدعاء OpenAI، يعيد العامل تنفيذ تلك الخطوة وحدها. وتكون المطالبة التي أُنشئت في الخطوة 0 محفوظة مسبقًا بأمان في حالة سير العمل.