From f4b1929b2ba2859e373e88adb94f54a6b3b6e2c6 Mon Sep 17 00:00:00 2001 From: "Rondineli G. Saad" Date: Fri, 3 Jul 2026 12:21:28 -0300 Subject: [PATCH] Garante reprocessamento de colecoes com falha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O que esse PR faz? Adiciona uma fila persistente para colecoes que falham durante o processamento. Quando uma colecao falha, o run.sh registra o acronimo em failed_collections.queue no diretorio de logs; na proxima execucao, essas colecoes sao priorizadas antes da lista normal e removidas da fila quando forem processadas com sucesso. Isso evita que falhas transitorias, como indisponibilidade do ArticleMeta thriftserver, facam uma colecao ficar sem nova tentativa ate alguem intervir manualmente. Onde a revisão poderia começar? Comece por run.sh, nas funcoes normalize_collection_list, load_failed_collections, record_failed_collection e clear_failed_collection, e depois veja o fluxo em main. A documentacao complementar esta em README.md na secao Kubernetes / Argo. Como este poderia ser testado manualmente? 1. Definir LOG_DIR para um diretorio temporario e criar um failed_collections.queue com um acronimo valido, por exemplo arg-AR. 2. Executar run.sh com uma lista que nao comece por essa colecao e observar no log a mensagem de reprocessamento das colecoes pendentes. 3. Simular falha de uma colecao e confirmar que o acronimo e registrado em failed_collections.queue. 4. Executar novamente com a colecao corrigida e confirmar que ela e removida da fila apos sucesso. Algum cenário de contexto que queira dar? O workflow do Argo executa colecoes em sequencia e, em ambiente agendado, usa EXIT_ON_FAILURE=false para nao bloquear proximas execucoes. Antes desta mudanca, uma falha apos as tentativas locais apenas seguia para a proxima colecao e dependia da proxima rodada completa ou de acao manual. A fila persistente usa o volume de logs ja montado para manter memoria das colecoes pendentes entre execucoes. Screenshots Nao aplicavel; mudanca sem interface grafica. Quais são tickets relevantes? Nao informado. Referências PR 98 aplicado antes desta mudanca: https://github.com/scieloorg/processing/pull/98/commits. Contexto operacional: erro de conexao ConnectionResetError ao consultar ArticleMeta thriftserver. --- README.md | 6 ++++++ run.sh | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c91dc86..263014e 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,12 @@ processing-data -> /var/www/static_scielo_org/tabs processing-logs -> /var/log/processing ``` +Quando uma coleção falha, o `run.sh` registra o acrônimo em +`/var/log/processing/failed_collections.queue` por padrão. Na próxima execução, +essa fila é carregada antes da lista normal de coleções; coleções processadas +com sucesso são removidas da fila. O caminho pode ser alterado com +`FAILED_COLLECTIONS_FILE`. + Aplicação: ```bash diff --git a/run.sh b/run.sh index 68d8ab7..aec548c 100755 --- a/run.sh +++ b/run.sh @@ -24,6 +24,7 @@ readonly TIMESTAMP="$(date +%Y%m%d_%H%M%S)" readonly REPORT_DATE="$(date +%F)" readonly MASTER_LOG="$LOG_DIR/master_$TIMESTAMP.log" readonly SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-}" +readonly FAILED_COLLECTIONS_FILE="${FAILED_COLLECTIONS_FILE:-$LOG_DIR/failed_collections.queue}" readonly DEFAULT_ACRONYMS=( "scl-BR" "arg-AR" "bol-BO" "chl-CL" "cub-CU" "col-CO" @@ -76,6 +77,37 @@ log_success() { log_message "$1" "SUCCESS" } +normalize_collection_list() { + awk 'NF && !seen[$0]++ { print $0 }' +} + +load_failed_collections() { + [[ -f "$FAILED_COLLECTIONS_FILE" ]] || return 0 + normalize_collection_list < "$FAILED_COLLECTIONS_FILE" +} + +record_failed_collection() { + local item=$1 + mkdir -p "$(dirname "$FAILED_COLLECTIONS_FILE")" + { + [[ -f "$FAILED_COLLECTIONS_FILE" ]] && cat "$FAILED_COLLECTIONS_FILE" + echo "$item" + } | normalize_collection_list > "${FAILED_COLLECTIONS_FILE}.tmp" + mv "${FAILED_COLLECTIONS_FILE}.tmp" "$FAILED_COLLECTIONS_FILE" +} + +clear_failed_collection() { + local item=$1 + [[ -f "$FAILED_COLLECTIONS_FILE" ]] || return 0 + + grep -Fxv "$item" "$FAILED_COLLECTIONS_FILE" > "${FAILED_COLLECTIONS_FILE}.tmp" || true + if [[ -s "${FAILED_COLLECTIONS_FILE}.tmp" ]]; then + mv "${FAILED_COLLECTIONS_FILE}.tmp" "$FAILED_COLLECTIONS_FILE" + else + rm -f "${FAILED_COLLECTIONS_FILE}.tmp" "$FAILED_COLLECTIONS_FILE" + fi +} + validate_prerequisites() { mkdir -p "$LOG_DIR" "$TABS_DIR" @@ -273,16 +305,34 @@ main() { IFS=' ' read -ra acronyms_to_process <<< "$1" fi + local pending_failed_collections=() + while IFS= read -r item; do + pending_failed_collections+=("$item") + done < <(load_failed_collections) + + if [[ ${#pending_failed_collections[@]} -gt 0 ]]; then + log_message "Reprocessando coleções pendentes de falha anterior: ${pending_failed_collections[*]}" + acronyms_to_process=("${pending_failed_collections[@]}" "${acronyms_to_process[@]}") + mapfile -t acronyms_to_process < <(printf '%s\n' "${acronyms_to_process[@]}" | normalize_collection_list) + fi + local counter=0 local failed_collections=() for item in "${acronyms_to_process[@]}"; do counter=$((counter + 1)) - process_collection "$item" "$is_network_mode" "$counter" || failed_collections+=("$item") + if process_collection "$item" "$is_network_mode" "$counter"; then + clear_failed_collection "$item" + else + record_failed_collection "$item" + failed_collections+=("$item") + fi done if [[ "$is_network_mode" == "true" ]]; then - process_network_zip || failed_collections+=("network") + if ! process_network_zip; then + failed_collections+=("network") + fi fi end_time=$(date +%s)