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.
// 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:
// Load all .php files from the workflows directory
$count = Queuety::load_workflows(__DIR__ . '/workflows/');
Oder lade eine einzelne Datei:
$template = Queuety::load_workflow_file(__DIR__ . '/workflows/onboard-user.php');
Verteile anschließend nach Namen:
$workflow_id = Queuety::run_workflow('onboard_user', ['email' => 'user@example.com']);
Rekursives Laden
Übergib true als zweites Argument, um Unterverzeichnisse zu durchsuchen:
Queuety::load_workflows(__DIR__ . '/workflows/', recursive: true);
So kannst du Workflows in Ordnern organisieren:
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:
// 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.