
# Zrušení workflow

Workflow lze zrušit programově nebo prostřednictvím CLI. Při zrušení workflow nastaví Queuety jeho stav na `cancelled`, odloží všechny čekající nebo zpracovávané úlohy a spustí volitelnou obslužnou rutinu pro úklid.

## Registrace obslužné rutiny pro úklid

Pomocí `on_cancel()` v builderu workflow zaregistrujete třídu, která se spustí při zrušení workflow. Třída obslužné rutiny musí implementovat metodu `handle( array $state ): void`.

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

Obslužná rutina pro úklid obdrží veřejný stav workflow (všechny klíče, které nezačínají na `_`):

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

## Zrušení pomocí PHP

Zavolejte `Queuety::cancel_workflow()` s ID workflow:

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

Tato metoda:

1. Zamkne řádek workflow
2. Nastaví stav workflow na `cancelled`
3. Odloží všechny čekající a zpracovávané úlohy workflow se zprávou "Workflow cancelled"
4. Zapíše událost `workflow_cancelled` a potvrdí transakci
5. Spustí kompenzační rutiny dokončených kroků v opačném pořadí (pokud byly zaregistrovány pomocí `compensate_with()`)
6. Spustí obslužnou rutinu pro úklid `on_cancel` (pokud je zaregistrována)

Pokud je workflow už ve stavu `completed` nebo `cancelled`, vyvolá se `RuntimeException`.

## Zrušení pomocí CLI

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

| Možnost | Popis |
|---|---|
| `<id>` | ID pracovního postupu ke zrušení (povinné) |

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

## Co se stane při zrušení

Při zrušení workflow:

- **Stav** se změní na `cancelled`
- **Kompenzační rutiny kroků** se spustí v opačném pořadí dokončení, pokud jste je připojili pomocí `compensate_with()`
- **Obslužná rutina pro úklid** se spustí poté, co je řádek workflow označen stavem `cancelled`
- **Čekající úlohy** workflow se okamžitě odloží
- **Zpracovávané úlohy** workflow se odloží; po dokončení právě probíhající obslužné rutiny se její výstup zahodí a workflow nepokračuje
- **Dokončené úlohy** z předchozích kroků zůstanou beze změny
- **Záznam v protokolu** s událostí `workflow_cancelled` se uloží

## Zrušení a selhání

| Vlastnost | Selhání | Zrušení |
|---|---|---|
| Spouštěč | Krok vyčerpá počet pokusů o opakování | Výslovné zavolání `cancel_workflow()` |
| Stav | `failed` | `cancelled` |
| Lze opakovat | Ano, pomocí `retry_workflow()`, pokud už ve workflow neproběhla kompenzace | Ne |
| Obslužná rutina pro úklid | Nespustí se | Spustí se, pokud je zaregistrovaná pomocí `on_cancel()` |
| Událost v protokolu | `workflow_failed` | `workflow_cancelled` |

## Příklad: zrušení s potvrzením

Běžným postupem je před zrušením zkontrolovat stav workflow:

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