Episódio 23 – Revertendo um Estado: Desfazer não é Magia, é Design
Nem toda operação assíncrona precisa apenas de um callback de sucesso. Muitas vezes, precisamos de algo mais: a capacidade de desfazer uma etapa, ou ao menos saber como restaurar o estado anterior de forma segura. Isso é especialmente crítico em fluxos de tarefas encadeadas, onde um erro na etapa 3 pode invalidar as etapas anteriores.
Problema
Imagine a cadeia:
- Validar um token
- Baixar dados remotos
- Processar e salvar localmente
Se a etapa 3 falhar, você quer desfazer o que a etapa 2 fez?
Se sim, você precisa de controle reversível.
Solução: Tarefas com reversão (undo)
A ideia é simples:
- Ao adicionar uma tarefa, você fornece também uma UndoTask, ou seja, uma operação complementar
- Se alguma tarefa subsequente falhar e você estiver em modo "RollbackOnError", as UndoTasks anteriores são executadas na ordem inversa
TaskChain := TTaskChain.Create(True); // ContinueOnError := False
TaskChain.RollbackOnError := True;
TaskChain.AddTask(
'Download JSON',
procedure(...)
begin
// tarefa principal
end,
procedure
begin
// tarefa de rollback caso próxima falhe
end
);
Design Flexível
Na implementação atual, o TTaskChain pode ser expandido para:
- Armazenar um array de
UndoTask - Executar as
UndoTaskem ordem reversa caso ocorra falha eRollbackOnErroresteja habilitado
Essa abordagem abre portas para:
- Implementar "transações" visuais ou lógicas
- Testes com simulação de falhas e validação de rollback
- Funcionalidades tipo Ctrl+Z em tarefas complexas
Mas é thread-safe?
Sim, pois cada UndoTask é chamada de forma sincronizada na thread principal, garantindo consistência com a UI.
Se a tarefa tiver envolvimento com banco, arquivos ou componentes visuais, você tem total controle para desfazer o que for necessário.
Conclusão
Desfazer não é luxo, é segurança. Adicionar essa possibilidade nas suas TaskChains deixa seu código mais robusto, previsível e pronto para falhas.
No próximo episódio, vamos explorar como combinar encadeamento de tarefas com persistência de estado, mesmo após reboot.