
# Creazione di fork del flusso di lavoro

Queuety può creare un fork completamente indipendente di un flusso di lavoro in esecuzione. Il flusso di lavoro derivato inizia dallo stesso passaggio e con lo stesso stato dell'originale, ma da quel momento i due flussi procedono in modo indipendente. Le modifiche apportate a uno non influiscono sull'altro.

## Creare un fork di un flusso di lavoro

### PHP API

Chiamate `Queuety::fork_workflow()` con l'ID del flusso di lavoro. Restituisce il nuovo ID del flusso di lavoro:

```php
use Queuety\Queuety;

$forked_id = Queuety::fork_workflow( $workflow_id );
```

### CLI

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

| Opzione | Descrizione |
|---|---|
| `<id>` | ID del workflow da duplicare (obbligatorio) |

```bash
wp queuety workflow fork 42
# Success: Workflow #42 forked. New workflow ID: 43.
```

## Come funziona

Quando create un fork di un flusso di lavoro:

1. La riga del flusso di lavoro originale viene bloccata e letta
2. Viene inserita una nuova riga del flusso di lavoro con lo stesso stato, le stesse definizioni dei passaggi e il passaggio corrente
3. Il nuovo flusso di lavoro si chiama `{original_name}_fork_{timestamp}`
4. Il passaggio corrente viene inserito in coda per il flusso di lavoro derivato
5. Su entrambi i flussi di lavoro viene registrato un evento di log `workflow_forked`
6. Il flusso di lavoro originale continua la sua normale elaborazione

Il flusso di lavoro derivato è completamente indipendente. Ha un proprio ID, una propria copia dello stato e proprie voci nella coda dei job. Dal momento del fork, i due flussi di lavoro possono evolvere in modo diverso.

## Casi d'uso

### Test A/B dei gestori dei passaggi

Create un fork di un flusso di lavoro per testare due implementazioni diverse di un passaggio imminente:

```php
// Original workflow will use the existing CallLLMHandler (GPT-4).
// Fork it to test with a different handler.
$forked_id = Queuety::fork_workflow( $workflow_id );

// Modify the forked workflow's state to use a different model.
// (Update the state via a custom step or direct DB update.)
```

### Analisi ipotetica

Create un fork di un flusso di lavoro in corrispondenza di una decisione per esplorare rami diversi:

```php
// Workflow is at step 3, about to process data.
// Fork it so we can try two different processing strategies.
$fork_a = Queuety::fork_workflow( $workflow_id );
$fork_b = Queuety::fork_workflow( $workflow_id );
```

Ogni fork procede con lo stesso stato di input, ma può essere modificato per seguire percorsi diversi.

### Sperimentazione parallela

Quando un flusso di lavoro raggiunge un punto in cui volete provare più approcci in parallelo, create un fork per ciascun approccio e confrontate i risultati quando tutti i fork sono completati.

## Tracciare i fork

L'evento di log di ciascun flusso di lavoro include un riferimento all'altro:

- Nell'originale: `context.forked_workflow_id` rimanda al nuovo flusso di lavoro
- Nel fork: `context.forked_from_workflow_id` rimanda all'originale

Consultate i log per trovare tutti i fork di un flusso di lavoro:

```php
$logs = Queuety::logger()->for_workflow( $workflow_id );

foreach ( $logs as $entry ) {
    if ( 'workflow_forked' === $entry['event'] ) {
        $context = json_decode( $entry['context'] ?? '{}', true );
        // $context['forked_workflow_id'] is the new workflow
    }
}
```

## Limitazioni

- Il flusso di lavoro derivato non eredita la cronologia del registro eventi dell'originale. Inizia con un registro eventi vuoto.
- Le relazioni run-workflow non vengono duplicate. Se l'originale aveva un run-workflow in esecuzione, il fork non ne riceve una copia.
- Il fork è un'istantanea dello stato corrente. I job in corso del flusso di lavoro originale non vengono duplicati.
