stamatios
← Voltar ao feed
Tempo em software: além do happy path
Dev & Engenharia

Tempo em software: além do happy path

resumo de ~3 min

O problema

A maioria dos softwares é construída sob condições ideais: relógios sincronizados, rede rápida, jobs que rodam na hora. Em produção, essas premissas falham. Este post da série "Beyond Happy Path Engineering" trata de tempo como uma fronteira de design - não como um detalhe de implementação.

Quatro tipos de tempo

O autor propõe separar o conceito de tempo em quatro categorias distintas:

  • Wall-clock time: o instante no calendário (útil para auditoria e logs).
  • Monotonic time: mede duração sem sofrer correções de relógio (timeouts, latência, retries).
  • Logical time: ordenação de eventos via versões, offsets ou máquinas de estado - não timestamps.
  • Business time: regras de domínio como períodos de cobrança, horários de loja, fusos e daylight saving.

Clock skew e o exemplo da reserva

Um fluxo de checkout reserva um item por 15 minutos. Se o worker de expiração tem um relógio 2 minutos adiantado, ele pode liberar o estoque enquanto o usuário ainda está pagando. A solução: a expiração deve ser uma transição de estado condicional (UPDATE ... WHERE state = 'reserved' AND paymentAuthorizationID IS NULL), não uma simples comparação de timestamp.

Timestamps não provam ordem

Quando eventos vêm de máquinas diferentes, ordenar por timestamp pode contar a história ao contrário. A ordenação correta exige transações, números de versão ou offsets de stream.

Medir duração com relógio monotônico

Subtrair dois wall-clock timestamps pode resultar em duração negativa se o relógio for corrigido durante a operação. Latência, backoff e deadlines devem usar relógio monotônico.

Jobs agendados são workflows

Um cron que roda a cada minuto não garante pontualidade nem execução única. Após uma pausa, o catch-up pode gerar um burst de updates. O design deve incluir batches limitados, claims com ownership, checkpointing e métricas de lag.

Tempo do usuário tem significado de produto

"Ontem" depende de qual fuso. Uma reserva de pickup às 9h em Londres precisa armazenar data local, hora local e a zona Europe/London - não apenas um offset. Offsets descrevem um momento; zonas carregam regras (incluindo DST).

Bugs de tempo se espalham em silêncio

O autor cita um exemplo real: um leaderboard com cache de 12h onde uma mudança de peso na fórmula fez metade dos perfis usar pesos novos e metade usar os antigos - sem nenhum erro nos logs. Cada leitura individual parecia correta; a inconsistência só existia entre elas.

Recomendações práticas

  1. Escolha o tipo de relógio para cada pergunta.
  2. Use monotonic time para durações e deadlines.
  3. Armazene instantes em UTC; exiba datas com contexto de fuso.
  4. Deixe o dono do estado decidir writes concorrentes (conditional updates).
  5. Torne expiração idempotente e reparável.
  6. Trate jobs agendados como workflows com batches, claims e progresso durável.
  7. Trate fusos como dados de domínio, não como formatação.
  8. Observe as premissas de tempo: lag de jobs, decisões perto de fronteiras, writes rejeitados, clock skew.
  9. Tenha um caminho de reconciliação para casos ambíguos que o tempo sozinho não resolve.