Repository navigation
PAV-178: [Jobs Processor] Otimizar agendamento e distribuição de carga dos providers - #332
Merged
Conversation
Benevanio
approved these changes
Nov 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Descricao
Distribui os oito providers em 21 janelas automáticas diárias, com seleção efetiva por ProviderID e coordenação pelo lock global existente. Implementa grupos fixos Greenhouse, deadline absoluto, cobertura de keywords LinkedIn/Adzuna e orçamentos operacionais Gupy/Jooble. Preserva resultados parciais no catálogo PostgreSQL e na projeção Valkey, com status operacional compatível com falhas e timeouts. A integração foi validada com serviços descartáveis; a ativação automática em DEV permanece condicionada à configuração e à validação operacional.
Linear
PAV-178
Close PAV-178
Como foi testado
Resultados comprovados nas rodadas anteriores:
cronjoberunlockcom-raceEsses números representam execuções distintas e não devem ser somados como casos únicos.
Na preparação deste PR, os comandos
npm testde backend e frontend foram tentados conforme a skill. Ambos terminaram antes de executar casos, com código 127 evitest: not found, pois esta worktree está sem dependências locais. Não foram instaladas dependências nem repetidas as integrações anteriores.Reprodução direcionada
Com dependências instaladas e sem apontar configurações de teste para serviços compartilhados:
Para as integrações, configurar
PAV125_TEST_DATABASE_URLePAV125_TEST_VALKEY_URLexclusivamente para instâncias descartáveis dedicadas:A integração backend de busca versionada utiliza:
cd backend npx --no-install vitest run tests/integration/jobs.valkey.test.ts npx --no-install tsc --noEmit -p tsconfig.jsonNão executar seeds ou scrapers reais como parte desses testes.
Objetivo
Reduzir concentração de carga entre providers e distribuir a atualização do catálogo ao longo do dia, preservando os controles existentes de concorrência, persistência e coordenação.
A grade é a configuração operacional acordada. A caracterização completa de duração, CPU, memória e volume dos oito providers ainda deverá ser medida em DEV; este PR não apresenta essa capacidade como comprovada.
Resumo das alterações
bf554a5284d1c985793e5814026a9fad87295e4e34A branch também inclui os commits anteriores da PAV-178: seleção por ProviderID, controle de ativação, preservação parcial, bloqueio de seeds demonstrativos, otimizações e observabilidade do pipeline.
Arquivos e módulos afetados
scraper-go/internal/config/, incluindoprovider_schedule.go.scraper-go/internal/cronjob/, incluindo despacho, manifesto Greenhouse, cursor Gupy e Retry-After.scraper-go/internal/runlock/.pipeline/,catalog/,catalogops/,jobstore/,jobindex/,classifier/emetrics/.scraper-go/cmd/server/.docker/docker-compose.app.ymledocker/docker-compose.migrate.yml.docs/PAV-178-dev.md,docs/PAV-178-PR.mde documentação técnica do Processor.Nenhuma alteração da PAV-181 integra este PR.
Arquitetura e funcionamento do scheduler
O preset
SCRAPER_PROVIDER_WINDOWS=pav178reutiliza o scheduler e o lock distribuído existentes. A configuração de janelas substitui o acionamento periódico legado nesse modo.Todos os horários abaixo são locais em
America/Sao_Paulo:São 21 ocorrências diárias, com IDs estáveis e claims persistidos por data local.
missed:admission_late, sem executar o provider.Cobertura dos providers
Cobertura planejada não significa conclusão garantida quando a fonte limita requisições ou o deadline é atingido.
Validações realizadas
Foram cobertos seleção exclusiva, horários locais, deduplicação após reinício, sobreposição, timeout, cancelamento, resultados parciais, persistência/indexação, quotas e cobertura dos catálogos.
Os testes finais do hotfix simulam a latência da coordenação sem sleeps longos e confirmam:
A comparação com
upstream/developnão apresentou conflitos textuais na simulação de merge. Os testes anteriores foram executados na branch PAV-178, não sobre uma integração com os 34 commits posteriores do destino.Impacto de banco e migrations
Não há nova migration neste PR.
O catálogo PostgreSQL, IDs estáveis, transações e revisões de indexação existentes são preservados. Falhas de indexação deixam pendências identificáveis por
indexed_revision < revision, recuperáveis pelos mecanismos existentes.O deploy deixa de executar automaticamente o seed demonstrativo. Migrations e backfill legítimo de PII continuam no fluxo.
O startup exige o catálogo migrado e recusa estados que demandem backfill/reconstrução explícita. Não há limpeza ou reconstrução automática de índices.
Impacto de configuração e variáveis de ambiente
A origem das configurações do scraper é o
.envglobal da raiz do repositório, não o.envdo backend.O Compose principal inclui os arquivos modulares com
project_directory: .. O serviçoscraper-go:./.envporenv_file;/app/.envcomo somente leitura;environment, que prevalecem sobreenv_file;DATABASE_URLpelo módulo de migrations eVALKEY_URLpela configuração do serviço.O carregamento Go utiliza
godotenv.Load, sem sobrescrever variáveis já presentes no processo.SCRAPER_SCHEDULER_ENABLEDfalseem DEV até ativação controlada. O padrão do código étrue.SCRAPER_PROVIDER_WINDOWSpav178seleciona a grade. Vazio mantém o modo legado quando habilitado.SCRAPER_SCHEDULE_TIMEZONEAmerica/Sao_Paulo; rejeita timezone incompatível.SCRAPER_SCRAPE_TIMEOUT50m; coleta limitada também pelo deadline total e reservas de finalização.GUPY_AUTO_QUERY_LIMIT120, exclusivo do modo automático correspondente.GUPY_AUTO_MAX_PAGES5.GUPY_AUTO_MAX_HTTP_ATTEMPTS600, incluindo retries.JOOBLE_DAILY_HTTP_LIMIT150; aceita valores entre 1 e 150.SCRAPER_GREENHOUSE_BATCH_SIZESCRAPER_SCHEDULER_ENABLED, os três limites automáticos Gupy eJOOBLE_DAILY_HTTP_LIMITchegam peloenv_file, sem override explícito nesses campos do Compose. Timeout, janelas, concorrência, batches e parâmetros do lock possuem entradas explícitas emenvironment.Flags, credenciais e catálogos
ADZUNA_APP_IDeADZUNA_APP_KEY.GUPY_ENABLED=true; preservar as flags de discovery/sweep existentes.INHIRE_ENABLED=true; catálogo indicado porINHIRE_TENANTS_FILE.GREENHOUSE_ENABLED=true; catálogo indicado porGREENHOUSE_COMPANIES_FILE, compatível com o manifesto.LEVER_ENABLED=true; catálogo indicado porLEVER_COMPANIES_FILE. O padrão do Compose éfalse.THEMUSE_API_KEYé opcional no adapter.JOOBLE_API_KEYe Valkey disponível para controle de quota.Com
SCRAPER_PROVIDER_WINDOWS=pav178, os oito providers precisam estar disponíveis no registry mesmo com o scheduler desabilitado, pois a validação ocorre no startup.Também permanecem necessários PostgreSQL/Valkey, configurações de concorrência e parâmetros de lease existentes. Nenhuma credencial ou arquivo
.envestá incluído neste PR.Impacto de contratos e APIs
Preserva o disparo sem seleção explícita e adiciona seleção administrativa por provider, com validação e encaminhamento Node → Go.
O status administrativo expõe resumo da última execução e janelas configuradas. Timeout com vagas persistidas é distinguido de sucesso completo.
A integração mantém tratamento de seleção inválida, conflito de execução, rate limit/Retry-After e indisponibilidade de coordenação.
A busca backend utiliza a versão ativa em
scraper:jobs:index-versione documentos emscraper:jobs:ns:<versao>:job:<id>. Índices legados com IDs sem documentos não recuperam conteúdo perdido.Segurança e privacidade
Mantém autenticação e autorização administrativas existentes no backend. Os endpoints administrativos Go devem permanecer acessíveis pela rede interna prevista.
Não inclui credenciais,
.env, binários ou Compose temporário. Não executa seeds, coletas reais, reconstruções de índice ou alterações em produção.As integrações utilizaram dados e serviços descartáveis.
Riscos e limitações
developatualizado.docs/PAV-178-scheduler-automatico.mdpermanece não rastreado e não integra este PR.Rollback
Manter ou retornar
SCRAPER_SCHEDULER_ENABLED=falsee utilizar a imagem anterior aprovada em DEV, sem apagar catálogo, índices, checkpoints ou volumes.Verificar a compatibilidade dos estados persistidos antes de voltar a um scheduler legado. Não remover claims ou contornar locks para recuperar ocorrências perdidas.
Rollback de namespace do índice, quando necessário, exige procedimento separado e validação dos documentos existentes.
Fora do escopo
Deploy, ativação automática, merge, mudanças da PAV-181, reconstrução de índices em produção, remoção de dados demonstrativos já existentes e novas migrations.
Também ficam fora do escopo novas políticas de frequência, aumento de concorrência e um dashboard/histórico completo de execuções — relacionado à PAV-179.
Checklist final
-race.developatualizado.