
# Dipendenze tra workflow

Usate le attese sulle dipendenze tra workflow quando un workflow di primo livello deve proseguire solo dopo il completamento di altri workflow. In questo modo potete coordinare più workflow senza concentrare tutto in un'unica definizione enorme.

Queste attese si combinano particolarmente bene con [Passaggi asincroni](https://queuety.inline0.dev/it/docs/workflows/async-handoffs), in cui un workflow avvia prima workflow secondari indipendenti e attende poi il loro completamento.

Per esempi più completi di pianificazione ed esecuzione, consultate [Orchestrazione degli agenti](https://queuety.inline0.dev/it/docs/workflows/agent-orchestration).

Queuety fornisce tre metodi del generatore:

- `wait_for_workflow()` per un workflow
- `wait_for_workflows()` per più workflow con semantica `all`, `any` o `quorum`
- `wait_for_workflow_group()` quando gli ID dei workflow provengono da un gruppo avviato in precedenza

## Attendere un workflow

```php
$research_id = Queuety::workflow( 'research_run' )
    ->then( PlanResearchStep::class )
    ->for_each( 'tasks', ExecuteResearchTask::class, 'results' )
    ->dispatch( [ 'brief_id' => 42 ] );

$editorial_id = Queuety::workflow( 'editorial_run' )
    ->wait_for_workflow( $research_id, 'research' )
    ->then( DraftBriefStep::class )
    ->dispatch();
```

Quando `research_run` viene completato, `editorial_run` riprende. Se impostate `result_key`, lo stato della dipendenza completata viene salvato con quella chiave:

```php
$state['research']; // public state from the completed research workflow
```

Senza un `result_key`, lo stato pubblico del workflow da cui dipende viene unito allo stato di primo livello del workflow in attesa.

## Attendere più workflow

```php
use Queuety\Enums\WaitMode;

Queuety::workflow( 'synthesis_run' )
    ->wait_for_workflows(
        [ $research_id, $editorial_id, $legal_id ],
        WaitMode::All,
        'dependencies'
    )
    ->then( PublishPacketStep::class )
    ->dispatch();
```

- `WaitMode::All` riprende solo quando tutti i workflow elencati sono stati completati.
- `WaitMode::Any` riprende quando viene completato il primo workflow dell'elenco.
- `WaitMode::Quorum` riprende quando un numero necessario di workflow è stato completato correttamente.

```php
Queuety::workflow( 'synthesis_run' )
    ->wait_for_workflows(
        [ $research_id, $editorial_id, $legal_id ],
        WaitMode::Quorum,
        'dependencies',
        quorum: 2,
    )
    ->then( PublishPacketStep::class )
    ->dispatch();
```

Con `result_key`, le attese di più workflow salvano lo stato delle dipendenze completate usando l'ID del workflow come chiave:

```php
[
    '42' => [ 'summary' => '...' ],
    '43' => [ 'summary' => '...' ],
]
```

Senza un `result_key`, lo stato delle dipendenze completate viene unito allo stato di primo livello del workflow in attesa, nell'ordine delle dipendenze.

## Risolvere gli ID delle dipendenze dallo stato del workflow

Potete rimandare la definizione dell'elenco delle dipendenze fino all'esecuzione, leggendo gli ID dei workflow dallo stato pubblico:

```php
Queuety::workflow( 'agent_follow_up' )
    ->wait_for_workflow( 'parent_workflow_id', 'parent' )
    ->then( FinalizeAgentRunStep::class )
    ->dispatch( [ 'parent_workflow_id' => $workflow_id ] );
```

Per più dipendenze:

```php
Queuety::workflow( 'aggregator' )
    ->wait_for_workflows( 'dependency_ids', WaitMode::Any, 'winner' )
    ->dispatch( [ 'dependency_ids' => [ 12, 18, 22 ] ] );
```

## Attendere un gruppo di workflow già avviato

Se un passaggio `start_workflows()` o `start_agents()` precedente ha salvato una chiave di gruppo persistente, potete attendere direttamente quel gruppo, senza dover trasferire manualmente gli ID dei workflow nello stato pubblico.

```php
Queuety::workflow( 'brief_research' )
    ->then( PlanTopicsStep::class )
    ->start_agents( 'agent_tasks', $agent_run, group_key: 'researchers' )
    ->wait_for_agent_group( 'researchers', WaitMode::Quorum, 2, 'agent_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch();
```

## Cosa accade durante l'attesa

Quando un workflow raggiunge uno di questi passaggi, passa allo stato `waiting_for_workflows`. Nessun worker rimane associato al workflow durante l'attesa.

```php
$state = Queuety::workflow_status( $workflow_id );
echo $state->status->value; // 'waiting_for_workflows'
echo $state->wait_type;     // 'workflow'
print_r( $state->waiting_for ); // ['42', '43']
```

Se una dipendenza è già stata completata prima che venga raggiunto il passaggio di attesa, il workflow prosegue immediatamente.

## Semantica degli errori

Le attese sulle dipendenze tra workflow privilegiano il completamento corretto:

- `wait_for_workflow()` e `WaitMode::All` non riescono se una qualsiasi dipendenza richiesta non riesce o viene annullata.
- `WaitMode::Any` non riesce solo quando tutte le dipendenze hanno raggiunto uno stato terminale e nessuna è stata completata correttamente.
- `WaitMode::Quorum` non riesce quando i workflow ancora attivi non possono più soddisfare il quorum richiesto.

Questo rende le attese tra workflow utili nei sistemi di pianificazione ed esecuzione, in cui un workflow può distribuire il lavoro e un altro può attendere i risultati `all` o il completamento del primo ramo riuscito.
