
# Dependências de workflows

Use esperas por dependências de workflow quando um workflow de nível superior só deve continuar após a conclusão de outros workflows. Isso permite coordenar workflows sem forçar tudo a caber em uma única definição gigantesca.

Essas esperas combinam especialmente bem com [Transferências assíncronas](https://queuety.inline0.dev/pt/docs/workflows/async-handoffs), em que um workflow primeiro inicia workflows filhos independentes e depois aguarda por eles.

Para exemplos mais completos de planejador/executor, consulte [Orquestração de agentes](https://queuety.inline0.dev/pt/docs/workflows/agent-orchestration).

Queuety fornece três métodos de construção:

- `wait_for_workflow()` para um workflow
- `wait_for_workflows()` para vários workflows com semântica `all`, `any` ou `quorum`
- `wait_for_workflow_group()` quando os IDs dos workflows vêm de um grupo iniciado anteriormente

## Aguardar um 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` é concluído, `editorial_run` retoma a execução. Com `result_key` definido, o estado da dependência concluída é armazenado sob essa chave:

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

Sem um `result_key`, o estado público do workflow dependente é mesclado ao estado de nível superior do workflow que está aguardando.

## Aguardar vários workflows

```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` retoma a execução somente quando todos os workflows listados forem concluídos.
- `WaitMode::Any` retoma a execução quando o primeiro workflow listado for concluído.
- `WaitMode::Quorum` retoma a execução quando o número exigido de workflows for concluído com sucesso.

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

Com `result_key`, as esperas por vários workflows armazenam o estado das dependências concluídas indexado pelo ID do workflow:

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

Sem um `result_key`, o estado das dependências concluídas é mesclado ao estado de nível superior do workflow que está aguardando, na ordem das dependências.

## Resolver IDs de dependência a partir do estado do workflow

Você pode adiar a lista de dependências até o tempo de execução, lendo os IDs dos workflows do estado público:

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

Para várias dependências:

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

## Aguardar um grupo de workflows iniciado

Se uma etapa anterior `start_workflows()` ou `start_agents()` tiver armazenado uma chave de grupo durável, você pode aguardar diretamente esse grupo em vez de passar os IDs dos workflows pelo estado público.

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

## O que acontece durante a espera

Quando um workflow chega a uma dessas etapas, ele passa para o status `waiting_for_workflows`. Nenhum worker permanece associado a ele enquanto aguarda.

```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 uma dependência já tiver sido concluída antes de a etapa de espera ser alcançada, o workflow continua imediatamente.

## Semântica de falha

As esperas por dependências de workflow priorizam o sucesso:

- `wait_for_workflow()` e `WaitMode::All` falham se qualquer dependência necessária falhar ou for cancelada.
- `WaitMode::Any` falha somente quando todas as dependências chegam a um estado terminal e nenhuma é concluída com sucesso.
- `WaitMode::Quorum` falha quando os workflows ativos restantes já não podem satisfazer o quórum exigido.

Isso torna as esperas por workflows úteis em sistemas de planejador/executor, nos quais um workflow pode executar cada unidade de trabalho e outro pode aguardar os resultados `all` ou o primeiro ramo bem-sucedido a terminar.
