Inteligência Artificial

Timeout do PHP-FPM na chamada de IA: tire do request e jogue no CLI

A tela fica girando e cai num 504 Gateway Time-out. No error.log do nginx aparece upstream timed out (110: Connection timed out) while reading response header from upstream. A API de IA levou 70 segundos para responder e o nginx desistiu aos 60, que é o padrão do fastcgi_read_timeout. Subir o max_execution_time não muda nada aqui: no Linux ele não conta o tempo parado esperando o socket responder. A saída é tirar a chamada de dentro do request.

Grave o pedido e devolva o id na hora

CREATE TABLE ia_jobs (
  id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  entrada TEXT NOT NULL,
  saida LONGTEXT NULL,
  status ENUM('fila','rodando','pronto','erro') NOT NULL DEFAULT 'fila',
  criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_status_id (status, id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

O controller faz um INSERT com status fila e responde o id em milissegundos. O front pergunta o status de tempos em tempos num endpoint que só faz um SELECT por id.

O worker roda no CLI, onde o tempo é seu

sudo -u www-data crontab -e

# tudo em UMA linha: crontab não aceita barra invertida para quebrar comando
* * * * * /usr/bin/flock -n /tmp/ia-worker.lock /usr/bin/php8.3 /var/www/app/worker.php >> /var/log/ia-worker.log 2>&1

No CLI o max_execution_time vale 0 por padrão, então nada mata o processo no meio. O flock -n garante que o cron do minuto seguinte desiste em vez de subir um segundo worker em cima do mesmo job. Só confira que o www-data consegue escrever no arquivo de log, senão o cron falha calado.

Insistir no timeout maior sai caro: cada request parada segura um processo do pool, e com pm.max_children = 20 bastam vinte pessoas clicando para o site inteiro parar de responder. Pior, quem se cansa aperta F5 e dispara a chamada de novo, pagando duas vezes pelo mesmo texto. Ainda vale deixar o request_terminate_timeout do pool acima do fastcgi_read_timeout para não trocar 504 por 502 sem log, mas isso é remendo, não a solução.

Post Recentes

Erro 500 no Magento 2: achar o relatório em var/report pelo ID da tela

O hash que o Magento mostra junto do erro é o nome de um arquivo em var/report. Veja como abrir,…

23 horas atrás

Campo extra no checkout em blocos do WooCommerce sem voltar pro shortcode

Seu snippet com woocommerce_checkout_fields parou de aparecer no checkout em blocos. Registre o campo pela API nova e leia o…

2 dias atrás

Fuso horário no PHP 8.3: log com 3 horas de diferença no servidor

O pedido entrou às 21h e o relatório mostra 00h do dia seguinte. Onde setar date.timezone no PHP 8.3 e…

2 dias atrás

Magento 2 não envia e-mail de pedido: async sending e cron parado

O pedido entra na loja e o e-mail nunca sai: antes de culpar o SMTP, veja o envio assíncrono, a…

3 dias atrás

cron_schedules WordPress: intervalo de 5 minutos no WP-Cron

O WordPress só oferece hourly, twicedaily, daily e weekly. Use o filtro cron_schedules para criar um intervalo de 5 minutos…

4 dias atrás

E-mails do WooCommerce não chegam: como testar o envio de um pedido real

Dispare pela linha de comando o e-mail de um pedido que já existe na loja e descubra se a falha…

4 dias atrás