Skip to content

Reduz o custo de geração dos metadados de documentos e fontes - #130

Merged
pitangainnovare merged 2 commits into
scieloorg:mainfrom
pitangainnovare:perf/metadata-values-iterator
Aug 29, 2026
Merged

Reduz o custo de geração dos metadados de documentos e fontes#130
pitangainnovare merged 2 commits into
scieloorg:mainfrom
pitangainnovare:perf/metadata-values-iterator

Conversation

@pitangainnovare

Copy link
Copy Markdown
Contributor

O que esse PR faz?

Reduz o custo de geração dos metadados utilizados durante o processamento dos logs de acesso.

Os métodos Document.metadata() e Source.metadata() criavam uma instância Django para cada registro retornado pelo PostgreSQL, apenas para convertê-la imediatamente em um dicionário.

Este PR substitui essa materialização por projeções com values().iterator(), preservando o contrato dos dicionários consumidos pelo URLTranslationManager.

Também foram definidos lotes explícitos de 2.000 registros para a leitura em streaming.

A alteração:

  • reduz a criação de objetos Python e o consumo de CPU;
  • mantém uma consulta SQL para Documents e uma para Sources;
  • preserva os relacionamentos Book–Chapter e Journal–Article;
  • preserva documentos sem pai ou sem fonte;
  • não altera cálculos COUNTER, payloads ou documentos exportados;
  • não altera filas Celery, mappings ou índices do OpenSearch.

A versão da aplicação foi atualizada para 2.2.0.

Onde a revisão poderia começar?

A revisão pode começar nos métodos:

  • Document.metadata() em document/models.py;
  • Source.metadata() em source/models.py.

Em seguida, verificar o contrato completo dos metadados em:

  • document/tests/test_models.py;
  • source/tests/test_services.py.

Como este poderia ser testado manualmente?

Executar os testes focados:

docker compose -f local.yml run --rm django \
  pytest document/tests/test_models.py source/tests/test_services.py -q

Executar os módulos completos:

docker compose -f local.yml run --rm django \
  pytest document/tests source/tests -q

Executar as integrações de métricas:

docker compose -f local.yml run --rm django \
  pytest \
    metrics/tests/integration/test_books_log_to_metrics.py \
    metrics/tests/integration/test_classic_log_to_metrics.py \
    -q

Resultados obtidos:

  • testes focados: 8 aprovados;
  • módulos Document e Source: 17 aprovados;
  • integrações Books e Classic: 12 aprovados e 2 ignorados;
  • Flake8, isort e Black concluídos sem erros;
  • nenhuma migration gerada;
  • Gitleaks não encontrou segredos.

Também foi processado localmente o log real de Books de 1º de agosto de 2026.

Comparação com a implementação anterior:

  • linhas processadas: 19.634 em ambas;
  • linhas válidas: 16.352 em ambas;
  • linhas descartadas: 3.282 em ambas;
  • documentos mensais: 8.849 em ambas;
  • documentos anuais: 16.403 em ambas;
  • consultas PostgreSQL: 30 em ambas;
  • preparação dos metadados: aproximadamente 1,54 s para 0,63 s;
  • processamento e exportação: 29,121 s para 25,867 s.

O payload resultante manteve exatamente o mesmo hash:

b968461e9034394b49f207a9fc9f7ed8d2703a48b54319962c4cd078002ba457

Algum cenário de contexto que queira dar?

Para cada job diário, a aplicação carrega todos os Documents e Sources da coleção para construir os índices utilizados pelo tradutor de URLs.

Mesmo após eliminar as consultas repetidas relacionadas a parent_document, a implementação ainda criava dezenas ou centenas de milhares de instâncias Django.

O impacto tende a ser maior em coleções grandes. A coleção SCL, por exemplo, possui aproximadamente 540 mil documentos. O PostgreSQL local utilizado nos testes não contém os metadados de SCL, portanto o benchmark dessa coleção deverá ser realizado posteriormente no ambiente que contém seu catálogo.

Este PR depende da entrega anterior que elimina as consultas repetidas de parent_document. Caso ela ainda não tenha sido incorporada à main, este PR deve utilizar a branch da Parte 1 como base.

Esta entrega não adiciona cache. O cache versionado por coleção será tratado separadamente.

Screenshots

Não aplicável. A alteração não possui interface gráfica.

Quais são os tickets relevantes?

Não há ticket vinculado no momento.

Referências

  • Document.metadata() em document/models.py;
  • Source.metadata() em source/models.py;
  • URLTranslationManager do pacote scielo_usage_counter;
  • documentação do Django sobre QuerySet.values() e QuerySet.iterator().

Segurança da informação (NSI.04)

Seção obrigatória. Marque as opções aplicáveis e justifique quando necessário. Referência: NSI.04 - Norma de Desenvolvimento Seguro.

Este PR manipula dados sensíveis ou pessoais (LGPD)?

  • Sim — descreva os controles de proteção aplicados:
  • Não

Este PR altera autenticação, autorização, controle de acesso ou gerenciamento de sessão?

  • Sim — descreva o que mudou e por quê:
  • Não

Este PR introduz, atualiza ou remove dependências de terceiros?

  • Sim — as novas dependências foram verificadas no SBOM/Trivy sem vulnerabilidades críticas/altas em aberto?
    • Verificado e aprovado
    • Pendente / vulnerabilidade aceita com justificativa:
  • Não

Este PR foi validado pelo pipeline de segurança (SonarQube / Trivy)?

  • Sim — link do job:
  • Não aplicável a este PR — a alteração é interna e não modifica dependências, imagens, dados sensíveis ou superfícies de acesso.

Este PR concatena, monta ou executa comandos SQL, HTML ou JavaScript a partir de entrada externa?

  • Sim — confirme que há sanitização ou parametrização:
  • Não

Este PR expõe novos endpoints, telas ou serviços?

  • Sim — HTTPS obrigatório está garantido e o acesso segue o princípio de menor privilégio?
  • Não

Algum segredo, senha, chave ou token está sendo adicionado ao código-fonte?

  • Não, nenhum segredo foi commitado
  • Sim (bloquear merge e corrigir antes de prosseguir)

@pitangainnovare
pitangainnovare merged commit 78d5d55 into scieloorg:main Aug 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant