Atrasos duráveis
Os workflows podem ser pausados por um período fixo entre etapas usando o método de construção delay(). As etapas de atraso são duráveis: o atraso é armazenado no banco de dados, então permanece após reinicializações de workers, implantações e reinicializações do servidor.
O método ->delay()
Adicione uma etapa de atraso em qualquer ponto da cadeia do workflow:
use Queuety\Queuety;
Queuety::workflow( 'drip_campaign' )
->then( SendWelcomeEmailHandler::class )
->delay( days: 1 )
->then( SendFollowUpEmailHandler::class )
->delay( days: 3 )
->then( SendFinalEmailHandler::class )
->dispatch( [ 'user_id' => 42 ] );
O workflow irá:
- Executar
SendWelcomeEmailHandler - Aguardar 1 dia
- Executar
SendFollowUpEmailHandler - Aguardar 3 dias
- Executar
SendFinalEmailHandler
Parâmetros de duração
O método delay() aceita qualquer combinação de parâmetros de duração nomeados:
| Parâmetro | Tipo | Descrição |
|---|---|---|
$seconds |
int |
Segundos de espera |
$minutes |
int |
Minutos de espera |
$hours |
int |
Horas de espera |
$days |
int |
Dias de espera |
Todos os valores são somados. Estes exemplos são equivalentes:
->delay( seconds: 3600 )
->delay( minutes: 60 )
->delay( hours: 1 )
Você pode combiná-los:
->delay( hours: 1, minutes: 30 ) // 90 minutes total
Como funcionam as etapas de atraso
Quando um workflow chega a uma etapa de atraso, Queuety despacha um job interno __queuety_delay com a coluna available_at definida para o horário atual mais a duração do atraso. O job fica no banco de dados e não é reivindicado por nenhum worker até que o atraso termine.
Isso significa que:
- Sem polling. Os workers não verificam repetidamente o atraso. O job simplesmente fica disponível quando chega o momento.
- Sem uso de memória. Nada é executado durante a espera. O atraso existe apenas como uma linha no banco de dados.
- Sobrevive a reinicializações. Se o worker reiniciar, o job de atraso continuará na fila com o timestamp
available_atcorreto.
Quando o job de atraso é reivindicado após o período de espera, o workflow avança automaticamente para a próxima etapa.
Exemplo: notificações atrasadas
Envie um lembrete 1 hora após o cadastro de um usuário, mas somente se ele ainda não tiver concluído a integração:
Queuety::workflow( 'onboarding_reminder' )
->then( CreateAccountHandler::class )
->delay( hours: 1 )
->then( CheckOnboardingHandler::class )
->then( SendReminderHandler::class )
->dispatch( [ 'email' => 'user@example.com' ] );
A etapa CheckOnboardingHandler pode inspecionar o estado e usar a ramificação condicional para ignorar o lembrete se a integração já estiver concluída.
Exemplo: repetição com espera progressiva
Insira atrasos deliberados entre etapas semelhantes a tentativas repetidas:
Queuety::workflow( 'poll_external_api' )
->then( CheckStatusHandler::class, 'check' )
->delay( minutes: 5 )
->then( CheckStatusHandler::class, 'recheck' )
->delay( minutes: 15 )
->then( CheckStatusHandler::class, 'final_check' )
->then( ProcessResultHandler::class )
->dispatch( [ 'external_id' => 'abc-123' ] );
Vários atrasos
Um workflow pode conter qualquer número de etapas de atraso. Cada atraso é independente e rastreado por um nome sequencial (delay_0, delay_1, etc.) no estado do workflow.
Queuety::workflow( 'multi_step_drip' )
->then( StepA::class )
->delay( hours: 2 )
->then( StepB::class )
->delay( days: 1 )
->then( StepC::class )
->delay( minutes: 30 )
->then( StepD::class )
->dispatch( $payload );