Processos persistentes: workers de filas, Horizon e os seus programas sempre em execução
Há aplicações que precisam de algo que não existia num alojamento partilhado: um programa que nunca termine. Um worker que processe a fila assim que chega um trabalho, o Horizon, um consumidor de mensagens ou um bot.
Até agora, a solução era uma tarefa cron. No Laravel, o scheduler lança a cada minuto um queue:work --stop-when-empty, que processa o que está pendente e para. Funciona, mas um email de boas-vindas pode demorar até um minuto a sair, e o que tem de estar ativo o tempo todo, como o Horizon, não tinha onde ficar.
Agora, nos planos Avanza, Max e Elastic, tem processos persistentes: programas que a sua conta mantém sempre em execução.
O que pode deixar a correr
Em Alojamento → o seu serviço → Ferramentas → Processos há um bloco novo, Processos persistentes. Clique em Adicionar processo e escolha:
- Worker de filas:
php artisan queue:workcom as filas que indicar, por ordem de prioridade. Se os trabalhos se acumularem, pode pôr vários sobre as mesmas filas. - Horizon:
php artisan horizon, que distribui os seus próprios workers e traz o seu painel e as suas métricas. - Comando próprio: uma linha de shell para o Symfony Messenger, um consumidor de mensagens, um bot ou qualquer programa que trabalhe em segundo plano.
Indique a pasta da aplicação e, no worker e no Horizon, a versão de PHP com que têm de correr. Em menos de um minuto, o processo passa de A arrancar para Em curso.
O Avanza admite 3 processos, o Max 5 e o Elastic 8.
Se cair, volta a arrancar sozinho
Um vigilante verifica a cada minuto os processos da conta e arranca o que estiver em baixo. Se o programa terminar por si, por exemplo quando um worker chega ao seu --max-time para libertar memória, volta a arrancar num segundo e carrega a versão publicada nesse momento.
O que não faz é insistir sem fim. Se um processo cair cinco vezes seguidas logo após arrancar, fica Com falha e espera que o reinicie, para não gastar a CPU da sua conta em algo que não consegue arrancar.
Para saber porquê, cada processo tem o seu registo, com uma linha sempre que arranca e outra sempre que termina. Quase sempre, a linha anterior a cada queda explica a causa: uma pasta mal escrita, uma extensão de PHP em falta ou um serviço a que a aplicação não chega. Corrija-o e clique em Reiniciar.
A partir do mesmo painel, pode pará-los, arrancá-los, editá-los ou apagá-los. Tudo corre com o utilizador da sua conta e dentro dos seus recursos, os mesmos que os seus sites usam.
Com o Deploy+, sem se lembrar de reiniciar
Um worker carrega o código ao arrancar e mantém-no em memória, por isso, depois de publicar uma versão nova, é preciso reiniciá-lo. Com o Deploy+ não tem de fazer nada: no fim de cada implementação, e também ao voltar a uma versão anterior, reinicia os processos persistentes dessa aplicação. Cada worker termina o trabalho que tem em mãos e arranca com o código novo, e o registo da implementação indica como ficou cada um.
Se ligar um projeto Laravel, o próprio assistente do Deploy+ propõe-lhe deixar o seu worker de filas a correr, com a pasta já preenchida.
O que não cobre
Um processo persistente é para trabalho em segundo plano. Não é para programas que escutam numa porta, como um servidor Node.js, uma aplicação Python ou o Laravel Reverb. Para WebSockets no Laravel, recomendamos um serviço compatível com Pusher, como o Ably ou o próprio Pusher, que o Laravel suporta de origem; explicamo-lo em WebSockets no Laravel. Se o seu projeto precisar do seu próprio servidor, o que precisa é de um VPS.
No Inicia, no Webmaster e nas contas de um alojamento multiconta não há processos persistentes. As filas podem continuar a ser processadas com o scheduler, com até um minuto de espera.
Se usa o Horizon ou quer as filas no Redis, veja também o Redis persistente, que chega ao mesmo tempo. E tem o passo a passo, com os estados, as opções de cada tipo e o que fazer se um ficar com falha, no guia de processos persistentes.