Conceito

Uma mensagem pode ser considerada uma “poison” quando sempre que ela é processada, ocorre um erro. Neste caso, o erro não é algo temporário como falta de conectividade, timeout ou outro motivo temporário, mas é algo definitivo como por exemplo, uma mensagem mal formada ou com dados inválidos.

Neste caso, não importa quantas vezes esta mensagem seja processada, ela sempre resultará em erro.

Cenário

Em um aplicativo que usa o Azure Queue Service o ciclo comum de processamento é:

  1. Obter uma mensagem da fila. O que apenas “esconde” por alguns instantes a mensagem, ou seja, não apaga a mensagem da fila.
  2. Executar o processamento de negócio relacionado com a mensagem obtida.
  3. Se o processamento executar com sucesso, excluir definitivamente a mensagem da fila de mensagens
  4. Se o processamento executar com falha, a mensagem não é excluída, então após alguns instantes ela volta a estar visível e pronta para ser processada novamente.

O problema desta abordagem é que se uma poison message sempre voltar para a fila poderá comprometer o funcionamento de todo o sistema.

Por exemplo, no caso do Azure, digamos que eu tenha apenas uma worker role processando mensagens, ao acumular poison messages na fila pode ser que boa parte do tempo seja gasto reprocessando poison messages que saem e voltam pra fila o tempo todo. Este cenário além de não ser economicamente interessante,  pode chegar ao ponto de bloquear completamente o processamento de mensagens “boas”.

Como resolver

O ideal em um cenário de poison messages é identificá-las, removê-las da fila e registrar o ocorrido para investigação posterior.

Identificar

Para identificar que uma mensagem é problemática, uma das formas é controlar a quantidade de tentativas de processamento que ela sofreu. E caso atinja uma quantidade X de tentativas, ela é considerada uma poison message.

No caso do Azure Queue Service, isto pode ser feito através da propriedade DequeueCount da mensagem,  que identifica quantas vezes esta mensagem foi lida da fila. Ao atingir uma quantidade X configurada no .cscfg ela é removida da fila e transformada em uma outra mensagem e incluída na fila de mensagens problemáticas para um tratamento diferenciado.


 

Remover

Uma das formas de remover uma mensagem identificada como poison é termos outra fila de mensagens para armazenar as poison messages, ou seja, a mensagem com problema é retirada da fila normal do aplicativo e incluída em outra fila, fila esta de mensagens com problema.

Uma outra alternativa seria registrar a mensagem e demais detalhes do seu processamento em uma base de dados seja ela relacional ou não.

Tratar

Por fim, tendo mensagem na fila de mensagens problemáticas, precisamos fazer algo com elas. Uma possibilidade é criar um fluxo com o Workflow Foundation que realiza atividades como enviar e-mail para um administrador da fila, registrar em log o ocorrido, gravar em um table service informações sobre a mensagem, entre outros.

Conclusão

Independente da técnica utilizada para tratar poison messages, o importante é prepararmos nossa solução para elas.

Referências