
# Annullering af arbejdsgange

Arbejdsgange kan annulleres programmatisk eller via CLI. Når en arbejdsgang annulleres, sætter Queuety dens status til `cancelled`, begraver eventuelle afventende eller igangværende jobs og kører en valgfri oprydningsfunktion.

## Registrering af en oprydningsfunktion

Brug `on_cancel()` på arbejdsgangens builder til at registrere en klasse, der køres, når arbejdsgangen annulleres. Handler-klassen skal implementere en `handle( array $state ): void`-metode.

```php
use Queuety\Queuety;

Queuety::workflow( 'import_data' )
    ->then( FetchDataHandler::class )
    ->then( TransformDataHandler::class )
    ->then( LoadDataHandler::class )
    ->on_cancel( ImportCleanupHandler::class )
    ->dispatch( [ 'source_url' => $url ] );
```

Oprydningsfunktionen modtager den offentlige arbejdsgangstilstand (alle nøgler, der ikke starter med `_`):

```php
class ImportCleanupHandler {

    public function handle( array $state ): void {
        // Clean up any partial imports.
        if ( isset( $state['temp_table'] ) ) {
            global $wpdb;
            $wpdb->query( "DROP TABLE IF EXISTS {$state['temp_table']}" );
        }

        // Notify the user.
        wp_mail(
            $state['notify_email'] ?? '',
            'Import cancelled',
            'Your data import was cancelled.'
        );
    }
}
```

## Annullering via PHP

Kald `Queuety::cancel_workflow()` med arbejdsgangens ID:

```php
Queuety::cancel_workflow( $workflow_id );
```

Denne metode:

1. Låser arbejdsgangsrækken
2. Sætter arbejdsgangens status til `cancelled`
3. Begraver alle afventende og igangværende jobs for arbejdsgangen med meddelelsen "Workflow cancelled"
4. Logger en hændelse af typen `workflow_cancelled` og gemmer
5. Kører kompensationer for afsluttede trin i omvendt rækkefølge (hvis nogen blev registreret via `compensate_with()`)
6. Kører oprydningsfunktionen `on_cancel` (hvis den er registreret)

Der kastes en `RuntimeException`, hvis arbejdsgangen allerede er `completed` eller `cancelled`.

## Annullering via CLI

```bash
wp queuety workflow cancel <id>
```

| Valgmulighed | Beskrivelse |
|---|---|
| `<id>` | Workflow-id, der skal annulleres (påkrævet) |

```bash
wp queuety workflow cancel 42
```

## Hvad sker der ved annullering

Når en arbejdsgang annulleres:

- **Status** ændres til `cancelled`
- **Trinkompensationer** køres i omvendt afslutningsrækkefølge, hvis du har tilføjet dem med `compensate_with()`
- **Oprydningsfunktion** køres, efter arbejdsgangsrækken er markeret som `cancelled`
- **Afventende jobs** for arbejdsgangen begraves straks
- **Igangværende jobs** for arbejdsgangen begraves; når den aktuelle handler er færdig, kasseres dens output, og arbejdsgangen fortsætter ikke
- **Afsluttede jobs** fra tidligere trin forbliver uændrede
- **En logpost** med hændelsen `workflow_cancelled` registreres

## Annulleret eller mislykket

| Egenskab | Mislykket | Annulleret |
|---|---|---|
| Udløser | Et trin opbruger sine genforsøg | Eksplicit kald til `cancel_workflow()` |
| Status | `failed` | `cancelled` |
| Kan prøves igen | Ja, via `retry_workflow()`, medmindre arbejdsgangen allerede er kompenseret | Nej |
| Oprydningsfunktion | Køres ikke | Køres, hvis den er registreret via `on_cancel()` |
| Loghændelse | `workflow_failed` | `workflow_cancelled` |

## Eksempel: annullering med bekræftelse

Et almindeligt mønster er at kontrollere arbejdsgangens status, før den annulleres:

```php
$status = Queuety::workflow_status( $workflow_id );

if ( null === $status ) {
    throw new \RuntimeException( 'Workflow not found.' );
}

if ( 'running' === $status->status->value || 'paused' === $status->status->value ) {
    Queuety::cancel_workflow( $workflow_id );
}
```
