English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

visitante
1 / ?

Forma 1: Reparo de Estado. Forma 2: Relatório Desperdiçado.

Um Coração Medido bate no relógio. Não na necessidade. Não na mudança. Em um temporizador.

Duas formas, uma causa raiz: um job agendado substituindo o design correto.

Forma 1: Reparo de Estado

Uma transição de estado falha em completar de forma atômica. Em vez de corrigir a transição, um job em segundo plano executa após um atraso e reconcilia. Usuários veem estado corrompido durante a janela de reconciliação.

Exemplo do GitHub (2026-04-08): Um pull request teve seu repositório upstream tornado privado. O GitHub tentou uma transição de estado: fechar o PR, atualizar o status do branch, limpar o status de merge. A transição não foi concluída de forma atômica. O status do PR mostrou simultaneamente 'branch-forced-closed' e 'Merge status cannot be loaded'. Um job em background do Sidekiq executou minutos depois e completou a reconciliação. Observadores viram o estado inconsistente durante toda a janela.

The Metered Heart: o job do Sidekiq executava em um agendamento. Não executava porque o GitHub detectou estado inconsistente; executava porque o timer disparava. Um usuário observando o PR em tempo real via um PR que se contradizia até a próxima execução do job.

Form 2: Relatório Desperdiçado

Um relatório ou agregação é recalculado do zero em um intervalo fixo. Sem verificação de cache. Sem guarda de idempotência. Sem atualização incremental. Cada execução: uma varredura completa.

Exemplos: um cron job noturno que recalcula o valor total de compras de cada usuário escaneando todos os pedidos desde o início. Um job diário de analytics que regenera um dashboard a partir de logs brutos de eventos. Um e-mail semanal de resumo que consulta todas as linhas da tabela de atividades.

Cada um executa independentemente de haver ou não alterações desde a última execução. Cada um varre o histórico completo mesmo quando apenas as últimas 24 horas contêm dados novos. Cada um substitui o design incremental por repetição agendada.

A Raiz Compartilhada

Um Metered Heart não consegue dizer a verdade sobre seu próprio estado. Ele só conhece o relógio. Form 1: o job de reparo de estado executa em T+5 minutos independentemente de o estado estar quebrado em T+0. Form 2: o job de relatório executa às 2h independentemente de haver ou não alterações desde o dia anterior.

O relógio não carrega informação sobre o que precisa ser feito. Um evento carrega essa informação: 'uma transição de estado acabou de falhar', 'novos pedidos acabaram de chegar'. Um Metered Heart descarta essa informação e a substitui por um agendamento.

Drenagem de Capital

Um Metered Heart drena capital vivo: engenheiros de prontidão para incidentes de estado quebrado. Erode a confiança social: usuários veem dados inconsistentes e relatam defeitos que se resolvem sozinhos. Amplifica outros MOADs: um trabalho de reparo de estado que varre todos os registros para encontrar estado quebrado frequentemente contém MOAD-0001 (varredura O(N²)). Um trabalho de relatório que recalcula dados frios pode disparar MOAD-0005 (cache stampede). MOAD-0009 agrava outros defeitos.

A Raiz Compartilhada

Form 1 e Form 2 parecem diferentes na superfície: um repara estado, outro recalcula dados. A causa raiz os conecta.

Form 1 e Form 2 compartilham uma causa raiz. Descreva-a em uma frase. Depois, dê um exemplo de cada forma em software que você já usou.

Dispara na Mudança, Não no Relógio

O design orientado a eventos dispara quando algo muda. A mudança de estado é o evento. O evento é o gatilho.

Forma 1: a transição atômica substitui o job de reparo.

Se uma transição de estado pode deixar o sistema em um estado intermediário quebrado, o defeito está na transição, não na ausência de um job de reparo. Corrija a transição para que seja concluída de forma atômica (ou transacional). Quando a transição é concluída de forma atômica, o estado quebrado nunca existe. O job de reparo não tem nada para reparar.

# DEFEITO: transição não atômica deixa o estado quebrado
def close_pr_on_repo_private(pr_id):
pr = PR.get(pr_id)
pr.status = 'branch-forced-closed'   # passo 1: estado parcial
pr.save()                             # visível para os usuários AGORA
# ... outras etapas podem falhar ...
pr.merge_status = 'not_applicable'
pr.save()                             # passo 2: agora consistente
# Job do Sidekiq reconcilia se o passo 2 falhar
# CORREÇÃO: transição atômica; nenhum estado intermediário visível
def close_pr_on_repo_private(pr_id):
with db.transaction():
pr = PR.get(pr_id)
pr.status = 'branch-forced-closed'
pr.merge_status = 'not_applicable'
pr.save()   # ambos os campos são salvos atomicamente; nunca ficam parcialmente gravados

Forma 2: a atualização incremental substitui o recálculo completo.

Um relatório que recalcula do zero é disparado porque dados antigos + novos dados = novo resultado. Mas resultado antigo + delta = mesmo novo resultado, calculado de forma incremental. O evento: novos dados chegaram. O gatilho: atualizar o agregado apenas para os novos dados.

# DEFEITO: recálculo completo em agendamento
def nightly_totals_job():
for user in all_users():
total = sum(o.amount for o in user.orders)  # varre todo o histórico
user.total_purchases = total
user.save()

# CORREÇÃO: atualização incremental orientada a eventos
def on_order_placed(order):
order.user.total_purchases += order.amount   # apenas o delta
order.user.save()

A atualização incremental é disparada quando um pedido chega, não às 2h da manhã. Ela atualiza apenas o usuário afetado. Ela lê apenas o novo pedido, não todos os pedidos de todos os tempos. O job noturno desaparece.

Por que o Formulário 1 Revela uma Transição Quebrada

Um Formulário 1 Metered Heart revela que uma transição de estado foi deixada incompleta. O job de reparo existe porque um engenheiro notou um estado quebrado e adicionou um mecanismo de reconciliação em vez de corrigir a transição. O job de reparo: um remendo sobre uma decisão arquitetural quebrada.

MOAD-0009 como Amplificador

MOAD-0009 amplifica outros MOADs. Um job de reparo de estado que varre todos os registros para encontrar estado quebrado: MOAD-0001 (varredura O(N) ou O(N²) por execução do job). Um job de relatório que recalcula tudo do zero: MOAD-0005 (stampede de cache quando o job inicia e atinge um upstream aquecido). MOAD-0009 não prejudica apenas por si só; ele entrega outros MOADs em um agendamento.

Diagnosticar e Redesenhar

Uma equipe executa um cron job noturno às 2h da manhã. O job varre todos os pedidos de todos os usuários e recalcula do zero o valor total de compras de cada usuário. O job leva 4 horas. Às 6h da manhã, o dashboard exibe os totais atualizados. Entre 2h e 6h da manhã, o dashboard exibe os totais de ontem.

Qual forma de MOAD-0009 é esta? Qual evento deve disparar a recomputação? Qual estrutura de dados intermediária torna a atualização incremental?