
# Introduktion

Queuety er et plugin til WordPress, der leverer en hurtig jobkø, en holdbar workflowmotor og et runtime til tilstandsmaskiner. Arbejdere henter jobs direkte fra MySQL og behandler dem i en langkørende WP-CLI-proces. Det PHP-runtime, der indlæser WordPress og WP-CLI, skal have enten `mysqli` eller `pdo_mysql`.

## Hvorfor Queuety?

WordPress har ikke noget egentligt baggrundssystem. `wp_cron` udløses kun ved sidebesøg. Action Schedulers standardrunner kører på WP-Cron og loopback-HTTP-anmodninger, som hver behandler batches i højst 30 sekunder. Et API-kald, der tager 60 sekunder, afbrydes af PHPs timeout på 30 sekunder. Der er ingen måde at køre processer med flere trin, som overlever nedbrud og genoptages, hvor de slap.

Queuety løser dette med tre grundelementer:

1. **Jobs** til baggrundsarbejde, der afvikles uden opfølgning
2. **Workflows** til holdbare processer med flere trin og vedvarende tilstand
3. **State machines** til langvarig, hændelsesdrevet livscyklustilstand

## Hurtigt eksempel

Send et job med den moderne API:

```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!' );
```

Eller brug den klassiske metode med et handlernavn:

```php
use Queuety\Queuety;

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

Kør et holdbart workflow:

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

Modellér en langvarig session med en state machine:

```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 ] );
```

Start en worker:

```bash
wp queuety work
```

Hvis du bygger et agentbaseret system, så begynd med [Agent Orchestration](https://queuety.inline0.dev/da/docs/workflows/agent-orchestration). Her kan du se, hvordan planner/executor-forløb, menneskelige godkendelsestrin og ventetider på tværs af workflows hænger sammen.

Hvis systemet er hændelsesdrevet og langvarigt, så begynd med [State Machines](https://queuety.inline0.dev/da/docs/state-machines) sammen med workflows.

Hvis du vil se eksempler på integration fra ende til anden, kan du se [Examples](https://queuety.inline0.dev/da/docs/examples), som nu indeholder Neuron-baserede mønstre til skift mellem udbydere, streaming, gentagne gennemgange med hukommelse og afhængige workflows.

Hvis du vil starte workflows ud fra domænehændelser fra WordPress som `save_post`, kan du se [Action Triggers](https://queuety.inline0.dev/da/docs/features/action-triggers).

Hvis du vil bruge den databasebaserede runtime uden for WordPress, kan du se [Standalone Use](https://queuety.inline0.dev/da/docs/features/standalone-use).

## Vigtigste forskelle

- **Hurtig afvikling.** Workers har direkte adgang til MySQL-køen og undgår cron-mønstret pr. anmodning, som gør baggrundsarbejde langsommere i WordPress.
- **Holdbare workflows.** Processer med flere trin og vedvarende tilstand, der overlever PHP-timeouts, nedbrud og gentagne forsøg. Hvert trin er en atomisk MySQL-transaktion.
- **Tydelige state machines.** Modellér chatsessioner, godkendelser og andre langvarige livscyklusser med navngivne tilstande, beskyttede overgange, kølagte handlinger ved tilstandsindtræden og holdbare hændelsesforløb.
- **Moderne dispatch-API.** Selvstændige jobklasser med `Dispatchable`-traitet, typede konstruktøregenskaber som payload samt `$tries`/`$timeout`/`$backoff` erklæret i klassen. En `readonly`-klasse kan ikke give disse egenskaber standardværdier, så erklær dem i en almindelig klasse med readonly-promoverede konstruktøregenskaber.
- **Middleware-pipeline.** Middleware i løgstil til hastighedsbegrænsning, begrænsning af undtagelser, unikke jobs og brugerdefineret logik. Erklæres pr. job via en `middleware()`-metode.
- **Streamingtrin.** `StreamingStep`-grænsefladen udsender dele, der straks gemmes i databasen. Ved gentagne forsøg overføres tidligere gemte dele, så streamen kan fortsætte, hvor den slap. Velegnet til LLM-svar og store downloads.
- **Udskifteligt cachelag.** `CacheFactory` registrerer automatisk APCu eller bruger en cache i hukommelsen som fallback. Brugerdefinerede backends implementerer `Contracts\Cache`. Bruges internt til opslag i hastighedsbegrænseren og til køtilstand.
- **Batchbehandling og kæder.** Send grupper af jobs med `then`/`catch`/`finally`-callbacks og statussporing, eller kæd jobs sekventielt, så hvert job afhænger af, at det foregående er fuldført.
- **Holdbare forsinkelser og ventetider.** `delay()` tilføjer forsinkelser, der tåler genstart af processen. `wait_for_signal()`, `wait_for_signals()`, `wait_for_approval()`, `wait_for_input()` og `wait_for_workflow()` lader workflows vente på eksterne hændelser eller andre workflows uden at holde PHP aktiv.
- **Dynamisk for-each.** `for_each()` udvider forgreninger, der opdages under kørslen, ud fra workflowets tilstand og understøtter fuldførelsestilstandene alle lykkes, første lykkes og quorum.
- **Asynkrone workflow-overdragelser.** `start_workflows()` omdanner elementer, der opdages under kørslen, til uafhængige workflows på øverste niveau, som kan afventes senere.
- **WordPress-handlingsudløsere.** `on_action()` knytter handlingshooks fra kernen eller plugins til holdbare workflow-dispatches med betingelser og idempotens.
- **Holdbare artefakter.** Gem navngivne workflowresultater uden for den primære tilstandsbeholder, og medtag dem i status, CLI-inspektion, eksport og genafspilning.
- **Sikkerhedsforanstaltninger for workflows.** `version()`, en deterministisk definitionshash, idempotente dispatchnøgler og workflowbudgetter gør agentbaserede kørsler lettere at inspicere og sværere at duplikere eller lade løbe løbsk ubemærket.
- **Ressourcestyring.** Samtidighedsgrupper, omkostningsenheder, workflowbudgetter og worker-adgangskontrol hjælper med at holde dyrt agentbaseret arbejde inden for fastlagte rammer.
- **Kompensation for trin.** `compensate_with()` og `compensate_on_failure()` leverer rollback-hooks for fuldførte trin, når workflows annulleres eller mislykkes.
- **Heartbeats.** Langvarige trin sender heartbeats for at forhindre systemet til genoprettelse af forældede jobs i at overtage aktivt arbejde.
- **Workflow-sporing.** Hver trinændring registreres med input, output, tilstand før og efter, kontekst, artefakter, dele, fejl og fejlsøgning med tidsrejse via `workflow_state_at()`.
- **Parallelle trin.** Kør trin samtidigt, og vent på, at alle er fuldført, før du fortsætter.
- **Betinget forgrening.** Gå videre til navngivne trin baseret på tidligere tilstand med `_next_step`.
- **Kør workflows.** Start underordnede workflows, der sender resultater tilbage til det overordnede workflow.
- **Prioritetskøer.** Fire niveauer (Low, Normal, High, Urgent) via typesikre PHP-enumtyper.
- **Workers med flere køer.** Behandl flere køer med streng prioritering i én worker.
- **Hastighedsbegrænsning.** Begrænsninger for afvikling pr. handler med glidende tidsvindue.
- **Gentagne jobs.** Intervalbaseret og cron-baseret planlægning med konfigurerbare politikker for overlap (Allow, Skip, Buffer).
- **Annullering af workflows.** Annullér kørende workflows, og udløs registrerede oprydningshandlere.
- **Tilstandsrensning.** Fjern automatisk gamle trinresultater for at holde store workflowtilstande håndterbare.
- **Worker-samtidighed.** `--workers=N` starter flere processer med automatisk genstart efter nedbrud.
- **Fuld indsigt.** Logning i databasen, målinger pr. handler og hændelseswebhooks.
- **Testværktøjer.** `QueueFake` registrerer afsendte jobs og batches til assertions i enhedstests.
- **PHP-attributter.** `#[QueuetyHandler('name')]` til registrering af handlere uden konfiguration.

## Sådan fungerer det

Workers kører i en langvarig WP-CLI-proces og henter jobs direkte fra MySQL. Køposter, workflowtilstand, logfiler, batches, signaler og streamingdele ligger alle i MySQL, så genstart af workers ikke medfører tab af orkestreringstilstand.

Workflows opdeler langvarigt arbejde i trin. Hvert trin gemmer sit resultat i en fælles tilstandsbeholder i databasen. Hvis PHP dør midt i et trin, gentager workeren trinnet med al tidligere tilstand intakt. Trinets grænse er én enkelt MySQL-transaktion: tilstandsopdatering, jobfuldførelse og kølægning af næste trin sker atomisk.

```
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
```

## Krav

- PHP 8.2 eller nyere
- WordPress 6.4 eller nyere
- MySQL 8.0+ eller MariaDB 10.6+, fordi workers henter jobs med `SELECT ... FOR UPDATE SKIP LOCKED`
- `mysqli` eller `pdo_mysql` i det PHP-runtime, der indlæser WordPress og WP-CLI
- WP-CLI til at køre dedikerede workers med `wp queuety work`
- Udvidelserne `pcntl` og `posix` PHP til worker-pools (`--workers`, `--min-workers`, `--max-workers`)

Se [Getting Started](https://queuety.inline0.dev/da/docs/getting-started) for installation.
