Pular para o conteudo principal

Arquitetura Assíncrona: quando o seu await não é suficiente

Quando o problema deixa de ser “esperar uma promise” e passa a ser coordenar trabalho, falha, repetição e visibilidade entre partes diferentes do sistema.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

O problema

Muita gente aprende:

  • async
  • await
  • Promise.all
  • callback virando promise

e conclui:

agora eu sei trabalhar com arquitetura assíncrona.

Ainda não.

Isso é começo de runtime assíncrono, não arquitetura assíncrona.

Arquitetura assíncrona começa quando o problema deixa de ser:

  • esperar uma operação terminar

e passa a ser:

  • aceitar trabalho agora e concluir depois
  • coordenar componentes diferentes
  • lidar com falha parcial
  • reprocessar sem duplicar efeito
  • deixar o resultado observável para alguém

Esse é outro nível de problema.

Modelo mental

Pense assim:

await resolve sequência local. Arquitetura assíncrona resolve coordenação distribuída.

Essa frase limpa muita confusão.

Quando você usa await, o seu programa está dizendo:

“vou esperar este passo antes de seguir.”

Quando você desenha arquitetura assíncrona, o sistema está dizendo:

“esta intenção vai atravessar tempo, fila, falha e talvez mais de um processo antes de virar resultado.”

Percebe a diferença?

No primeiro caso, o problema é fluxo de execução.

No segundo, o problema é fluxo de trabalho.

Quebrando o problema

await não resolve fronteira entre componentes

Se a sua aplicação chama outra função no mesmo processo, await costuma bastar.

Mas se ela:

  • publica mensagem
  • depende de worker
  • conversa com outro serviço
  • precisa continuar depois de reiniciar

o problema mudou.

Agora você precisa pensar em:

  • persistência de estado
  • reentrega
  • timeout
  • retry
  • observabilidade

Nada disso aparece magicamente porque você escreveu await.

Assíncrono de verdade quase sempre atravessa tempo

Esse é um bom sinal para perceber que o jogo mudou.

Se o trabalho pode terminar:

  • segundos depois
  • minutos depois
  • em outra máquina
  • depois de um retry

você já está longe do conforto de uma call stack local.

Nesse mundo, perguntas importantes passam a ser:

  • como sei que o trabalho foi aceito?
  • como sei que ainda está em andamento?
  • como sei que falhou?
  • como evito executar duas vezes?

Falha parcial é a parte que await não te ensina

No código local, ou a promise resolve ou rejeita.

Em arquitetura assíncrona, o cenário pode ser mais estranho:

  • o job foi gravado, mas não foi publicado
  • a mensagem foi consumida, mas o worker caiu antes de persistir resultado
  • o efeito externo aconteceu, mas o acknowledgment não foi registrado

Agora você não está mais lidando só com erro.

Está lidando com estados intermediários e inconsistência temporária.

Background não é arquitetura

Tem time que chama qualquer coisa de arquitetura assíncrona só porque jogou a tarefa para “rodar depois”.

Isso é raso.

Se não existe clareza sobre:

  • como o trabalho entra
  • onde ele fica registrado
  • como ele avança
  • como ele falha
  • como ele reaparece

então você não tem arquitetura assíncrona.

Tem só trabalho solto fora da request.

O desenho bom é operacional, não só técnico

Uma arquitetura assíncrona minimamente madura pensa em:

  • quem observa status
  • quem pode reenfileirar
  • o que vai para DLQ
  • o que é transiente e o que é permanente
  • como idempotência é garantida

Esse é o tipo de pergunta que separa “sei usar promise” de “sei operar fluxo assíncrono”.

Exemplo simples

Imagine envio de nota fiscal.

Versão ingênua:

  1. usuário fecha pedido
  2. API chama serviço fiscal com await
  3. se demorar ou falhar, o pedido inteiro sofre junto

Versão com arquitetura assíncrona:

  1. pedido é confirmado
  2. sistema registra intenção de emitir nota
  3. job entra na fila
  4. worker tenta emitir
  5. em falha transitória, faz retry
  6. em falha permanente, marca estado e abre caminho de tratamento
  7. o restante do sistema consegue observar o status

Perceba a diferença.

O ganho aqui não veio de “usar await direito”.

Veio de desenhar um fluxo que aguenta tempo, repetição e falha.

Erros comuns

  • Achar que async/await já resolve desenho assíncrono.
  • Chamar de arquitetura o que na prática é só tarefa jogada para background.
  • Ignorar estado e ficar dependente apenas da fila para saber o que aconteceu.
  • Não pensar em repetição e depois sofrer com efeito colateral duplicado.
  • Modelar falha como binária quando o sistema tem vários estados intermediários.

Como um senior pensa

Quem tem mais repertório costuma notar cedo quando o problema saiu do código e entrou no sistema.

A pergunta muda de:

“Como eu espero isso direito?”

para:

“Como esse trabalho percorre o sistema, falha no meio, reaparece e continua explicável?”

Essa troca de pergunta é o salto.

Porque arquitetura assíncrona não é um truque para ganhar performance.

É um jeito de organizar trabalho quando o tempo e a distribuição já não cabem mais na request.

O que o entrevistador quer ver

Em entrevista, o avaliador quer ver se você sabe diferenciar:

  • runtime assíncrono
  • desenho assíncrono de sistema

Uma resposta forte costuma mencionar:

  • aceite da intenção
  • desacoplamento da request
  • estado persistido
  • retry com critério
  • idempotência
  • visibilidade de resultado

Exemplo de resposta boa:

await me ajuda a coordenar chamadas dentro de um processo. Mas quando o trabalho atravessa fila, worker e tempo, eu preciso pensar em arquitetura assíncrona de verdade: aceite da intenção, estado do job, retry, idempotência e observabilidade. Senão eu só empurro a complexidade para fora da request.”

await organiza execução. Arquitetura assíncrona organiza trabalho.

Quando o sistema continua certo mesmo depois de atraso, repetição e falha parcial, aí sim o assíncrono foi desenhado de verdade.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Próximo artigo Bancos de Dados e Concorrência Artigo anterior HTTP/1.1 vs HTTP/2 vs HTTP/3: o que Muda na Prática

Continue explorando

Artigos relacionados