
# Avbrytning av arbetsflöden

Arbetsflöden kan avbrytas programmatiskt eller via CLI. När ett arbetsflöde avbryts anger Queuety dess status till `cancelled`, begraver väntande jobb och jobb som håller på att bearbetas samt kör en valfri städningshanterare.

## Registrera en städningshanterare

Använd `on_cancel()` på arbetsflödesbyggaren för att registrera en klass som körs när arbetsflödet avbryts. Hanterarklassen måste implementera en `handle( array $state ): void`-metod.

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

Städningshanteraren får arbetsflödets offentliga tillstånd (alla nycklar som inte börjar 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.'
        );
    }
}
```

## Avbrytning via PHP

Anropa `Queuety::cancel_workflow()` med arbetsflödets ID:

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

Den här metoden:

1. Låser arbetsflödesraden
2. Anger arbetsflödets status till `cancelled`
3. Begrav alla väntande jobb och jobb som bearbetas för arbetsflödet med meddelandet "Arbetsflödet har avbrutits"
4. Loggar en händelse av typen `workflow_cancelled` och genomför transaktionen
5. Kör kompensationsåtgärder för slutförda steg i omvänd ordning (om några har registrerats via `compensate_with()`)
6. Kör städningshanteraren `on_cancel` (om den har registrerats)

Ett `RuntimeException` kastas om arbetsflödet redan är `completed` eller `cancelled`.

## Avbrytning via CLI

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

| Alternativ | Beskrivning |
|---|---|
| `<id>` | Arbetsflödes-ID att avbryta (krävs) |

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

## Vad händer vid avbrytning?

När ett arbetsflöde avbryts:

- **Status** ändras till `cancelled`
- **Kompensationsåtgärder för steg** körs i omvänd slutförandeordning om du kopplade dem med `compensate_with()`
- **Städningshanteraren** körs efter att arbetsflödesraden har markerats som `cancelled`
- **Väntande jobb** för arbetsflödet begravs omedelbart
- **Jobb som bearbetas** för arbetsflödet begravs; när den pågående hanteraren är klar kastas dess utdata och arbetsflödet går inte vidare
- **Slutförda jobb** från tidigare steg lämnas som de är
- **En loggpost** med händelsen `workflow_cancelled` registreras

## Avbrutet jämfört med misslyckat

| Egenskap | Misslyckat | Avbrutet |
|---|---|---|
| Utlösare | Ett steg har förbrukat sina omförsök | Uttryckligt anrop till `cancel_workflow()` |
| Status | `failed` | `cancelled` |
| Kan göras om | Ja, via `retry_workflow()`, såvida arbetsflödet inte redan har kompenserats | Nej |
| Städningshanterare | Körs inte | Körs om den har registrerats via `on_cancel()` |
| Logghändelse | `workflow_failed` | `workflow_cancelled` |

## Exempel: avbrytning med bekräftelse

Ett vanligt mönster är att kontrollera arbetsflödets status före avbrytning:

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