O valor do Durable Task não está em substituir todo trabalhador em segundo plano, fila de mensagens ou banco de dados, mas em organizar operações que se estendem por longos períodos, ficam aguardando um evento externo ou podem ser interrompidas depois da execução de parte de suas etapas. O blog do .NET apresenta cinco exemplos práticos usando o Durable Task .NET SDK versão 1.26.0 com o Durable Task Scheduler, ressaltando que a ferramenta preserva o histórico de coordenação, mas não restaura uma pilha de execução CLR suspensa.
A ideia central é separar o que o mecanismo de fluxo de trabalho coordena daquilo que continua sendo responsabilidade da aplicação. O Durable Task pode salvar pontos de progresso, aguardar sem manter uma thread de execução ocupada e executar novamente o código do orquestrador com base nos resultados registrados. No entanto, ele não decide as permissões dos usuários, não garante a execução única de efeitos externos e não determina sozinho quais recursos podem ser excluídos com segurança nem se um pagamento foi realmente recebido.
A aprovação humana não significa interromper o trabalhador
No processamento de faturas, cada fatura pode ser executada em uma orquestração secundária independente. As faturas que não precisam de revisão continuam seu fluxo, enquanto a fatura que exige aprovação humana aguarda um evento externo e um prazo durável. Se o trabalhador parar, outro trabalhador poderá executar novamente o orquestrador e retornar ao ponto de espera, em vez de reconstruir o estado manualmente.
Entretanto, o evento de aprovação é apenas um sinal. Um endpoint autenticado deve registrar atomicamente a decisão final no armazenamento da aplicação antes de enviar o sinal, e a etapa contábil deve verificar uma identidade de publicação estável e uma impressão digital de solicitação imutável. Se o lançamento contábil for aceito e a confirmação da atividade for perdida, o histórico do Durable Task não será suficiente para impedir a duplicação; será necessário um protocolo de reconciliação com o sistema contábil.
Configuração de um ambiente do Azure: onde termina o papel do ARM?
O material explica que ARM e Bicep podem ser suficientes para implantar recursos específicos, pois oferecem ordenação de dependências, execução paralela e reaplicação do estado desejado com identidades estáveis. Portanto, adicionar o Durable Task não se justifica para reconstruir um plano de implantação que o ARM já fornece.
O benefício aparece quando o fluxo de trabalho ultrapassa a implantação de recursos e passa a incluir o recebimento de uma solicitação do locatário, a comunicação do progresso, a espera pela prontidão e, em seguida, a ativação do locatário. O exemplo propõe salvar a solicitação de configuração e seus identificadores no banco de dados da aplicação com outbox e, então, usar uma orquestração que conecte as etapas de rede, banco de dados, armazenamento, aplicação, DNS e verificação de prontidão. As operações do Azure continuam precisando de registros operacionais, identidades estáveis e reconciliação quando as respostas forem perdidas.
O material também alerta contra considerar a compensação um botão de desfazer. O Azure ainda pode estar criando um banco de dados depois de uma falha no armazenamento. Por isso, é necessário impedir que a tentativa antiga inicie novas operações, verificar as operações enviadas anteriormente e excluir apenas os recursos pertencentes exclusivamente à tentativa depois de confirmar que não há operações atrasadas que possam recriá-los. Se não for possível comprovar o estado ou a propriedade, o resultado seguro é NeedsIntervention, e não uma exclusão especulativa.
O fim do prazo do pagamento não é uma recusa
No ciclo de uma assinatura, a resposta do provedor de pagamentos pode desaparecer depois que a operação for aceita. Tentar novamente imediatamente pode gerar uma cobrança duplicada, enquanto considerá-la recusada pode enviar um alerta enganoso. O exemplo propõe associar cada ciclo de pagamento a um identificador de ciclo e a uma chave de pagamento estável, usando então temporizadores duráveis, callbacks, verificações periódicas e um período de tolerância definido.
O livro-razão de pagamentos continua sendo a fonte authoritative para os estados Unknown, Pending, Declined, Paid e NotCharged. O ciclo seguinte só começa depois que o recibo for confirmado e o ciclo atual for encerrado. Se o prazo terminar enquanto o estado continuar sem definição, o resultado será NeedsReconciliation, em vez de presumir que o pagamento foi bem-sucedido ou falhou.
Eventos atrasados exigem proteção no destino
Em uma atualização do índice de busca de artigos jornalísticos, a versão 12 pode chegar depois da versão 13, ou as operações de indexação podem terminar em ordem inversa. A entidade durable pode armazenar a versão mais alta já observada e sequenciar as atualizações de seus contadores, mas não bloqueia o índice externo nem impede que duas solicitações escrevam em paralelo.
Por isso, o próprio destino deve impor uma barreira de versão atômica que rejeite a gravação de uma versão mais antiga depois que uma versão mais recente tiver sido consolidada. O sistema também precisa de uma inbox confiável, de um distribuidor para acompanhamento e de uma reconciliação periódica com a fonte. Mesmo o padrão de orquestrador com um único identificador não oferece garantia de execução única para efeitos externos.
O que isso significa para agentes de inteligência artificial?
Em um fluxo de trabalho de assistente de incidentes, o processo exige salvar a sugestão específica do modelo, aguardar a aprovação do engenheiro e, depois de uma possível falha, executar a ferramenta aprovada. O valor está em recuperar o próprio fluxo de aprovação e decisão, e não em gerar uma nova sugestão a cada nova execução. A identidade da sugestão, a validade da ferramenta e a prevenção da execução de uma solicitação antiga ou duplicada continuam sendo responsabilidades da aplicação.
A conclusão prática dos cinco exemplos é que o Durable Task é adequado quando preservar «o que acontecerá em seguida» se torna um sistema por si só. No entanto, se a aplicação já tiver filas, temporizadores e registros de reconciliação claros, ou se o sistema externo fornecer uma coordenação confiável, como o ARM, o framework poderá adicionar mais uma camada de complexidade do que de valor. Além disso, todos os exemplos dependem de limites externos explícitos: um registro autoritativo, uma chave de idempotência, uma barreira de versão, uma outbox ou um protocolo de reconciliação.