fix(ci): tetos de tempo nos serviços efêmeros e por passo no job backend [INFRA-68352] #39
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/INFRA-68352-timeouts-servicos-efemeros"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
⚠️ Leia antes de aprovar
ci.ymlCOMPARTILHADO (jobbackend), então afeta todos os produtos que usam o CI único, não só o DANI.timeout-minutespor passo foi conferido só por LEITURA do código do runner, NÃO executado. Nenhum workflow da frota usava a chave em passo. Noforgejo/runnerv12.12.0 o campo existe (Step.TimeoutMinutes) e é aplicado (context.WithTimeout), mas não rodei isso num Forgejo real. Um erro aqui afetaria todos os produtos (precedente: INFRA-64944).curlsem--max-time) e um padrão de travamento intermitente que ele explicaria. Qual passo travou de fato só se sabe lendo o log de uma execução que estourou (tarcisio/DANI/actions/runs/3122), que ainda não foi lido.Recomendação ao operador: validar primeiro num produto. Depois do merge, repetir (re-run) um PR do DANI e olhar o passo a passo do novo log (cada passo agora aparece com o seu tempo e teto) antes de seguir para os outros produtos.
Problema
O job
CI / backend (pull_request)do DANI estoura os 30 min de forma intermitente (≥ 8 em ~130 execuções, ~6%), e o mesmo commit passa em 9 a 11 min quando repetido. Não é fila de runner (três dos seis estouros visíveis tiveram 1 a 3 runs ativos; a duração não correlaciona com a carga, r = −0,01) nem teste que trava (opytest.initemtimeout = 120e opytest-timeoutestá instalado). Detalhes e números: INFRA-68352.O ponto sem limite verificado:
api() { curl -s ... }doservicos-efemeros.sh, sem--max-time, usado nopulldas imagens de Postgres e Redis e nocreate/startdos contêineres pelo daemon do host. Um daemon que emperra pendurava o passo até o teto do job.O que muda
scripts/servicos-efemeros.shapi():-sS,--connect-timeout 10,--max-time 60.api_pull():--max-time 600e aborta se ficar 90 s sem receber um byte./_ping, 15 s) no início doup: daemon mudo ou socket ausente falha em segundos, com::error::dizendo ocurl rc(28 = sem resposta, 7 = socket ausente) e o socket, sem criar nada.::warning::com o código; falha decurlnocreate/startnão aborta mais calada.0desliga), usados nos testes..forgejo/workflows/ci.yml(só o jobbackend) —timeout-minutespor passo: checkout 5, Infisical 5, PyPI 3, ci-shared 5, serviços 10, dependências 15, pip-audit 10, pré-teste 5, testes 25, smoke 10, derrubar 3. O teto do job continua 30. Os jobsfrontend,gatesechangesnão foram alterados (há teste).Prova
Daemon falso em socket Unix que aceita a conexão e nunca responde:
upfalha em menos de 10 s, com a mensagem.0faz o script pendurar.main(só trocando o socket): pendura nos dois cenários; no de pull travado para exatamente depois de imprimir oenvdo Postgres, ou seja, nopull.rc 7); pull travado aborta por falta de progresso e diz o código.tests/ci-config88 OK,ci-unico39,infisical-secrets9.Limites
Refs: INFRA-68352 (investigação e correção), INFRA-68349 (build da imagem de QA do DANI, outro job).
🤖 Generated with Claude Code
https://claude.ai/code/session_01UdMSC8CGmShbesE5rfVNfe
O job backend do DANI estourava os 30 min de forma INTERMITENTE em ~6% das execucoes, e o MESMO commit passava em 9-11 min quando repetido; nao era fila (3 dos 6 estouros com 1-3 runs ativos) nem teste (pytest-timeout=120 instalado). Ponto sem limite verificado: api() { curl -s ... } do servicos-efemeros.sh, sem --max-time, usado no pull e no create/start dos conteineres pelo daemon. 1) servicos-efemeros.sh - api(): -sS, --connect-timeout 10 e --max-time 60; api_pull(): --max-time 600 e aborta sem progresso por 90 s (--speed-limit 1 --speed-time 90). - sonda de vida do daemon (/_ping, 15 s) no inicio do up: daemon mudo ou socket ausente falha em segundos com ::error:: dizendo o curl rc (28/7) e o socket, sem criar nada. - pull que falha vira :⚠️: com o rc; create/start com falha de curl nao abortam calados. - tetos e o socket ajustaveis por env (TMF_DOCKER_SOCK, TMF_API_*, TMF_PING_MAX_TIME, TMF_PULL_*, TMF_RETRY_SLEEP; 0 desliga). /etc/hostname com fallback p/ hostname. 2) ci.yml, SO o job backend: timeout-minutes por passo (checkout 5, Infisical 5, PyPI 3, ci-shared 5, servicos 10, dependencias 15, pip-audit 10, pre-test 5, testes 25, smoke 10, derrubar 3); o do job continua 30. Orcamentos generosos e ESTIMADOS: nao ha medicao por passo (log ilegivel pela API). O campo e lido e aplicado pelo runner (forgejo/runner v12.12.0: Step.TimeoutMinutes -> context.WithTimeout), conferido no codigo-fonte, nao executado. Prova: daemon FALSO em socket Unix. Mudo: o up falha em <10 s com mensagem; CONTROLE com os limites em 0 o mesmo script pendura; daemon saudavel passa; sem socket falha rapido (rc 7); pull mudo aborta por falta de progresso. O script ANTIGO da main contra o mesmo daemon mudo PENDURA (morto aos 10 s) nos dois cenarios. 12 testes novos; ci-config 88 OK, ci-unico 39, infisical-secrets 9. Limite: o status do commit continua com o texto do JOB ('Failing after Xm'); quem mostra QUAL passo travou e o log/marcacao do passo na UI. Causa nao confirmada: o log do run que estourou nao foi lido. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UdMSC8CGmShbesE5rfVNfe