Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a delay in C# MessageQueue using MSMQ #13

Open
popohoma opened this issue Oct 21, 2024 · 1 comment
Open

Implement a delay in C# MessageQueue using MSMQ #13

popohoma opened this issue Oct 21, 2024 · 1 comment

Comments

@popohoma
Copy link

Hi All,

I am currently facing a technical problem dealing with MSMQ, C# MessageQueue and Thread.

My system is using MSMQ and C# MessageQueue framework. At the moment it will read message one by one from MSMQ and process it in C#.

There is a business scenario that the message that I am processing will be relying on another message that comes in later (say 5 minutes later). Therefore I need process this message later after the dependant message has persisted into database.

I want to put the original processing message back to the Queue with delay, retry for 10 times max with 10 seconds interval each. What is the best way for me to implement this logic given my current module is single threaded. It reads message one by one from the Queue in FIFO order.

Current Code:

var message = new System.Messaging.Message(messageBody, formatter)
_myQueue.Send(message)

I am thinking to use a ThreadPool to manage any messages requires a delay but my colleagues strongly against it as current module is single threaded and my separate thread may have adverse effect to it.

Your suggestion is greatly appreciated.

MSMQ

@thomasjohngleeson
Copy link

We implemented a set of retry queues to accomplish something similar.

Note: none of our messages are order dependent and are idempotent. If while processing a message the handler throws a retriable exception (ie: database deadlock/timeout) the handler code sends the 'bad' message to the retry queue and commits the transaction which threw the exception (ie: pops the 'bad' message). A separate service is responsible for monitoring the retry que and routing messages to one of 4 'delay' queues. If this is the first visit of a message to the retry service then it gets routed to the 30 second retry queue, second try goes to the 60 second queue and so forth. That same service also has a poller thread which peeks each queue every 15s looking for expiry times and then popping those which have expired and routing back to their destination queue. Note: using separate queues keeps the peeking somewhat efficient because the peek never needs to beyond the first message to see if any have expired, its effectively FIFO.

If we needed a static 5 min delay queue like your use case, I think we could have the sender send directly to a 300s 'retry' queue and our retry service would do the right thing. IJW :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants