Search code examples
c#task-parallel-librarytpl-dataflowretry-logic

How can I "requeue" messages in a TPL Pipeline?


I have a fire-and-forget Web Service that processes incoming requests. The request needs to go through number of processes that interact with the database via a single-threaded TPL pipeline.

If any process fails the message should be retried but it should be placed at the end of that block's queue. In other words the retry shouldn't be handled by the delegate; it should go to the back of the line (with its retry counter incremented).

Does TPL have this type of functionality built-in or do I need to code it myself?

Would something like this work?

// Proceed if the operation was successful
_firstProcess.LinkTo(_secondProcess, linkOptions, m => m.Succeeded == true);

// Go back to the beginning if it failed
_firstProcess.LinkTo(_firstProcess, linkOptions, m => m.Succeeded == false);

...

// Apply the same to every block.

Solution

  • I've tested and implemented and this since the time I've asked the question. The basic idea works fine. I've added retry counters and Terminal Error blocks. In simple terms, each Transform block links to itself based on the value in the "Succeeded" property, which is only if no errors occurred. If the retry counter exceeds a specified value, it links to a block that acts as a Terminal Error that requires manual intervention.

    Because of the nature of the expected errors, everything that enters the block shortly afterwards is also expected to fail within that specific time window. For this purposes, a dynamic delay mechanism was added for specific blocks when a particular type of error is encountered.