Zum Inhalt springen

Workflows aus einzelnen Dateien

Ein Workflow kann vollständig in einer einzelnen PHP-Datei enthalten sein. Definiere die Schrittklassen zusammen mit dem Builder, lege die Datei in einem Verzeichnis ab und lade dieses Verzeichnis mit Queuety::load_workflows() (siehe unten). Queuety durchsucht selbstständig kein Verzeichnis.

PHP
// workflows/onboard-user.php
use Queuety\Queuety;

class CreateAccount implements \Queuety\Step {
    public function handle(array $state): array {
        $user = create_user($state['email']);
        return ['user_id' => $user->id, 'user_name' => $user->name];
    }
    public function config(): array {
        return ['max_attempts' => 3];
    }
}

class SendWelcome implements \Queuety\Step {
    public function handle(array $state): array {
        wp_mail($state['email'], 'Welcome ' . $state['user_name'], '...');
        return ['welcomed' => true];
    }
    public function config(): array {
        return [];
    }
}

return Queuety::define_workflow('onboard_user')
    ->then(CreateAccount::class, 'create_account')
    ->then(SendWelcome::class, 'send_welcome');

Die Datei gibt ein WorkflowBuilder zurück. Jede Schrittklasse wird inline definiert. Beim Laden der Datei werden die Klassen verfügbar und der Workflow als Vorlage registriert.

Workflows laden

Lade alle Workflow-Dateien aus einem Verzeichnis:

PHP
// Load all .php files from the workflows directory
$count = Queuety::load_workflows(__DIR__ . '/workflows/');

Oder lade eine einzelne Datei:

PHP
$template = Queuety::load_workflow_file(__DIR__ . '/workflows/onboard-user.php');

Verteile anschließend nach Namen:

PHP
$workflow_id = Queuety::run_workflow('onboard_user', ['email' => 'user@example.com']);

Rekursives Laden

Übergib true als zweites Argument, um Unterverzeichnisse zu durchsuchen:

PHP
Queuety::load_workflows(__DIR__ . '/workflows/', recursive: true);

So kannst du Workflows in Ordnern organisieren:

Code
workflows/
├── onboarding/
│   ├── new-user.php
│   └── trial-upgrade.php
├── reports/
│   ├── daily-summary.php
│   └── weekly-digest.php
└── notifications/
    └── digest-email.php

Alle Workflow-Funktionen nutzen

Datei-Workflows unterstützen alle Funktionen des Builders außer idempotency_key(), da diese nicht in der Vorlage gespeichert wird. Übergib sie stattdessen beim Dispatch mit Queuety::run_workflow( $name, $payload, [ 'idempotency_key' => '...' ] ). Verzögerungen, Signale, parallele Schritte, bedingte Verzweigungen, das Starten von Workflows, Abbruch-Handler und das Bereinigen des Status funktionieren:

PHP
// workflows/approval-flow.php
use Queuety\Queuety;

class SubmitRequest implements \Queuety\Step {
    public function handle(array $state): array {
        return ['submitted_at' => date('Y-m-d H:i:s')];
    }
    public function config(): array { return []; }
}

class ProcessApproval implements \Queuety\Step {
    public function handle(array $state): array {
        return [
            'approved_by' => $state['approved_by'],
            'processed' => true,
        ];
    }
    public function config(): array { return []; }
}

class CleanupRequest implements \Queuety\Handler {
    public function handle(array $payload): void {
        delete_pending_request($payload['request_id']);
    }
    public function config(): array { return []; }
}

return Queuety::define_workflow('approval_flow')
    ->then(SubmitRequest::class)
    ->delay(hours: 24)
    ->wait_for_signal('approved')
    ->then(ProcessApproval::class)
    ->on_cancel(CleanupRequest::class)
    ->prune_state_after(2);

Wann Datei-Workflows sinnvoll sind

Datei-Workflows eignen sich besonders, wenn:

  • ein LLM oder Codegenerator Workflows programmgesteuert erstellt
  • ein Workflow einfach genug ist, um in eine Datei zu passen
  • du die Schrittlogik nahe an der Workflow-Definition halten möchtest
  • du Prototypen erstellst und schnell iterieren möchtest

Bei größeren Workflows mit gemeinsam genutzten Schrittklassen, komplexer Middleware oder Schritten, die in mehreren Workflows wiederverwendet werden, ist der Standardansatz mit separaten Klassendateien und PSR-4-Autoloading einfacher zu warten.

So funktioniert es

Unter der Oberfläche verwenden Datei-Workflows dieselbe Engine wie der Builder API. Jeder Schritt ist ein separater Job in der Datenbank. Der Status wird über die Tabelle queuety_workflows weitergegeben. Es gibt keine Wiedergabe, keine Determinismusanforderung und keinen Leistungsunterschied.

Jeder Ladeaufruf requiret die Datei, statt sie zu require_once. Lade daher jede Datei einmal pro Anfrage. Wird sie zweimal geladen, werden ihre Klassen erneut deklariert und es tritt ein Fehler auf. Das zurückgegebene WorkflowBuilder wird in ein WorkflowTemplate umgewandelt und im WorkflowRegistry gespeichert. Dispatch und Ausführung funktionieren wie bei jedem anderen Workflow.