Zum Inhalt springen

Einführung

Queuety ist ein WordPress-Plugin mit einer schnellen Job-Warteschlange, einer dauerhaften Workflow-Engine und einer Laufzeitumgebung für dauerhafte Zustandsautomaten. Worker beanspruchen Jobs direkt aus MySQL und verarbeiten sie in einem lang laufenden WP-CLI-Prozess. Die Laufzeitumgebung PHP, die WordPress und WP-CLI lädt, benötigt entweder mysqli oder pdo_mysql.

Warum Queuety?

WordPress verfügt über kein echtes Hintergrund-Jobsystem. wp_cron wird nur bei Seitenaufrufen ausgeführt. Der Standard-Runner von Action Scheduler basiert auf WP-Cron und Loopback-HTTP-Anfragen und arbeitet dabei Batches von jeweils höchstens 30 Sekunden ab. Ein LLM-API-Aufruf, der 60 Sekunden dauert, wird durch das 30-Sekunden-Timeout von PHP beendet. Mehrstufige Prozesse, die Abstürze überstehen und dort fortgesetzt werden, wo sie unterbrochen wurden, sind nicht möglich.

Queuety löst das Problem mit drei Grundbausteinen:

  1. Jobs für Hintergrundarbeit, die ohne Rückmeldung ausgeführt wird
  2. Workflows für dauerhafte mehrstufige Prozesse mit gespeichertem Zustand
  3. Zustandsautomaten für langlebige, ereignisgesteuerte Abläufe

Schnellstart-Beispiel

Löse einen Job mit dem modernen API aus:

PHP
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

readonly class SendEmailJob implements Job {
    use Dispatchable;

    public function __construct(
        public string $to,
        public string $subject,
        public string $body,
    ) {}

    public function handle(): void {
        wp_mail( $this->to, $this->subject, $this->body );
    }
}

SendEmailJob::dispatch( 'user@example.com', 'Welcome', 'Hello from Queuety!' );

Oder verwende den klassischen Ansatz mit Handler-Namen:

PHP
use Queuety\Queuety;

Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );

Führe einen dauerhaften Workflow aus:

PHP
Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );

Bilde eine langlebige Sitzung mit einem Zustandsautomaten ab:

PHP
use Queuety\Enums\StateMachineStatus;

Queuety::machine( 'agent_session' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( PlanSessionAction::class )
    ->on( 'planned', 'completed' )
    ->state( 'completed', StateMachineStatus::Completed )
    ->dispatch( [ 'thread_id' => 42 ] );

Starte einen Worker:

Shell
wp queuety work

Wenn du ein System mit Agenten entwickelst, beginne mit Agent Orchestration. Dort erfährst du, wie Planner-/Executor-Abläufe, Prüfpunkte für menschliche Kontrolle und workflowübergreifende Wartezeiten zusammenspielen.

Wenn dein System ereignisgesteuert und langlebig ist, beginne parallel zu den Workflows mit State Machines.

End-to-End-Integrationsbeispiele findest du unter Examples. Sie enthalten jetzt auch Neuron-basierte Muster für den Wechsel zwischen Anbietern, Streaming, wiederholte Prüfungen mit gespeicherten Erinnerungen und abhängige Workflows.

Wenn Workflows durch WordPress-Domänenereignisse wie save_post gestartet werden sollen, siehe Action Triggers.

Wenn du die datenbankgestützte Laufzeitumgebung außerhalb von WordPress verwenden möchtest, siehe Standalone Use.

Die wichtigsten Merkmale

  • Schnelle Ausführung. Worker greifen direkt auf die MySQL-Warteschlange zu und vermeiden das cron-Muster pro Anfrage, das Hintergrundarbeit in WordPress verlangsamt.
  • Dauerhafte Workflows. Mehrstufige Prozesse mit gespeichertem Zustand überstehen PHP-Timeouts, Abstürze und Wiederholungen. Jede Step-Grenze ist eine atomare MySQL-Transaktion.
  • Explizite Zustandsautomaten. Bilde Chat-Sitzungen, Genehmigungen und andere langlebige Abläufe mit benannten Zuständen, geschützten Übergängen, eingeplanten Aktionen beim Zustandswechsel und dauerhaften Ereignisverläufen ab.
  • Moderne Job-Auslösung API. Eigenständige Job-Klassen mit dem Trait Dispatchable, typisierten Konstruktor-Eigenschaften als Payload sowie $tries/$timeout/$backoff, die in der Klasse deklariert werden. Eine readonly-Klasse kann diesen Eigenschaften keine Standardwerte zuweisen; deklariere sie daher in einer regulären Klasse mit schreibgeschützten, per Konstruktor-Promotion definierten Eigenschaften.
  • Middleware-Pipeline. Middleware im Onion-Stil für Ratenbegrenzung, Drosselung bei Ausnahmen, eindeutige Jobs und eigene Logik. Wird pro Job über eine middleware()-Methode deklariert.
  • Streaming-Steps. Das Interface StreamingStep liefert Chunks, die sofort in der Datenbank gespeichert werden. Bei einem erneuten Versuch werden die zuvor gespeicherten Chunks bereitgestellt, damit der Stream dort fortgesetzt werden kann, wo er unterbrochen wurde. Ideal für LLM-Antworten und große Downloads.
  • Erweiterbare Cache-Schicht. CacheFactory erkennt APCu automatisch oder greift auf einen In-Memory-Cache zurück. Benutzerdefinierte Backends implementieren Contracts\Cache. Intern für Abfragen des Ratenbegrenzers und den Zustand der Warteschlange verwendet.
  • Batching und Verkettung. Löse Jobgruppen mit then/catch/finally-Callbacks und Fortschrittsverfolgung aus oder verkette Jobs der Reihe nach, sodass jeder erst nach Abschluss des vorherigen ausgeführt wird.
  • Dauerhafte Verzögerungen und Wartezeiten. delay() fügt Verzögerungen hinzu, die Prozessneustarts überstehen. Mit wait_for_signal(), wait_for_signals(), wait_for_approval(), wait_for_input() und wait_for_workflow() können Workflows auf externe Ereignisse oder andere Workflows warten, ohne PHP am Leben zu halten.
  • Dynamisches For-each. for_each() erstellt zur Laufzeit aus dem Workflow-Zustand ermittelte Zweigaufgaben und unterstützt die Abschlussmodi „alle erfolgreich“, „erster Erfolg“ und „Quorum“.
  • Asynchrone Workflow-Übergaben. start_workflows() macht zur Laufzeit ermittelte Elemente zu unabhängigen Top-Level-Workflows, auf die später gewartet werden kann.
  • WordPress-Action-Trigger. on_action() bildet Core- oder Plugin-Action-Hooks mit Bedingungen und Idempotenz auf dauerhafte Workflow-Auslösungen ab.
  • Dauerhafte Artefakte. Speichere benannte Workflow-Ausgaben außerhalb des zentralen Zustandsobjekts und führe sie durch Status, CLI-Inspektion, Export und Replay.
  • Schutzmechanismen für Workflows. version(), ein deterministischer Definitions-Hash, idempotente Auslösungsschlüssel und Workflow-Budgets machen Agentenabläufe leichter überprüfbar und erschweren Duplikate oder unbemerktes endloses Weiterlaufen.
  • Ressourcenverwaltung. Nebenläufigkeitsgruppen, Kosteneinheiten, Workflow-Budgets und die Worker-Aufnahme helfen, aufwendige Agentenarbeit innerhalb eines festgelegten Rahmens zu halten.
  • Kompensation von Steps. compensate_with() und compensate_on_failure() bieten Rollback-Hooks für abgeschlossene Steps, wenn Workflows abgebrochen werden oder fehlschlagen.
  • Heartbeats. Lang laufende Steps senden Heartbeats, damit die Wiederherstellung veralteter Jobs aktive Arbeit nicht erneut beansprucht.
  • Workflow-Nachverfolgung. Jeder Step-Übergang wird mit Eingabe, Ausgabe, Zustand davor und danach, Kontext, Artefakten, Chunks und Fehlern protokolliert. Über workflow_state_at() ist außerdem zeitliche Rückwärtsanalyse möglich.
  • Parallele Steps. Führe Steps gleichzeitig aus und warte auf ihren Abschluss, bevor es weitergeht.
  • Bedingte Verzweigungen. Springe mit _next_step abhängig vom vorherigen Zustand zu benannten Steps.
  • Workflows ausführen. Starte untergeordnete Workflows, deren Ergebnisse an den übergeordneten Workflow zurückgegeben werden.
  • Prioritätswarteschlangen. Vier Stufen (Low, Normal, High, Urgent) über typsichere PHP-Enums.
  • Worker für mehrere Warteschlangen. Verarbeite mehrere Warteschlangen in einem Worker mit strikter Prioritätsreihenfolge.
  • Ratenbegrenzung. Ausführungslimits pro Handler mit gleitendem Zeitfenster.
  • Wiederkehrende Jobs. Intervallbasierte und cron-basierte Zeitplanung mit konfigurierbaren Überschneidungsrichtlinien (Allow, Skip, Buffer).
  • Workflow-Abbruch. Brich laufende Workflows ab und löse registrierte Bereinigungshandler aus.
  • Zustandsbereinigung. Entferne alte Step-Ausgaben automatisch, damit große Workflow-Zustände überschaubar bleiben.
  • Worker-Nebenläufigkeit. --workers=N startet mehrere Prozesse mit automatischem Neustart nach einem Absturz.
  • Umfassende Beobachtbarkeit. Datenbankprotokollierung, Metriken pro Handler und Ereignis-Webhooks.
  • Testwerkzeuge. QueueFake zeichnet ausgelöste Jobs und Batches für Assertions in Unit-Tests auf.
  • PHP-Attribute. #[QueuetyHandler('name')] für die Registrierung von Handlern ohne Konfiguration.

So funktioniert es

Worker laufen in einem lang lebenden WP-CLI-Prozess und beanspruchen Jobs direkt aus MySQL. Zeilen der Warteschlange, Workflow-Zustand, Protokolle, Batches, Signals und Streaming-Chunks liegen alle in MySQL, sodass Worker-Neustarts den Orchestrierungszustand nicht verlieren lassen.

Workflows teilen lang laufende Aufgaben in Steps auf. Jeder Step speichert seine Ausgabe in einem gemeinsamen Zustandsobjekt in der Datenbank. Wenn PHP mitten in einem Step abstürzt, wiederholt der Worker diesen Step mit dem gesamten vorherigen Zustand. Die Step-Grenze ist eine einzelne MySQL-Transaktion: Zustandsaktualisierung, Jobabschluss und Einreihung des nächsten Steps erfolgen atomar.

Code
Workflow: generate_report (3 steps)

Step 0: fetch_data     -> state: {user_data: {...}}
Step 1: call_llm       -> PHP dies -> retry -> state: {user_data: {...}, llm_response: "..."}
Step 2: format_output  -> state: {user_data: {...}, llm_response: "...", report_url: "/reports/42.pdf"}

Workflow: completed

Voraussetzungen

  • PHP 8.2 oder höher
  • WordPress 6.4 oder höher
  • MySQL 8.0+ oder MariaDB 10.6+, da Worker Jobs mit SELECT ... FOR UPDATE SKIP LOCKED beanspruchen
  • mysqli oder pdo_mysql in der PHP-Laufzeitumgebung, die WordPress und WP-CLI lädt
  • WP-CLI zum Ausführen dedizierter Worker mit wp queuety work
  • Die Erweiterungen pcntl und posix PHP für Worker-Pools (--workers, --min-workers, --max-workers)

Hinweise zur Installation findest du unter Getting Started.