Question

Sorry for the vague title - I could not think of a concise way to ask this question. I think a concrete example will help.

I have a resource-intensive process that I want to move into a separate service and then send a message to kick it off. The message will be sent (in this first iteration) by a button being clicked on a website.

The problem is that there is a requirement that clicking the button ten times does not run the process ten times or even queue up ten runs of the process since it is so resource intensive. Our product manager would like that while the process is running, any other messages are basically discarded. But once the process finishes and resources are freed up, the messaging endpoint will act on a request message and run the process again.

We're currently solving this with a semaphore which blocks and discards messages, but I'm always wary of parallel processing and threading.

I thought a saga might be a good way to handle this in that you could have your saga started by the request message and then any others that come in would just open up the existing saga instance which would do a no-op on those additional messages. When the saga finishes, the next message that comes in requesting the process would start a new saga.

I also know you could disable the button while the process runs, but we want to avoid temporally coupling the button to the process, if possible. Meaning, we would rather not poll the process from the website to see if it's done or not.

Is there an industry-standard, or elegant way to handle this that perhaps I haven't thought of? I'd really like to avoid parallelism and the semaphore if possible, but I don't want to overly complicate my solution either. Any help is appreciated.

Bonus points if you can provide MassTransit specific information as that is the ESB I'm using.

Was it helpful?

Solution

You could just set the ConcurrentConsumerLimit of that process to 1 so it only ever consumes one message at a time. If a person hits the button 10x then it just queue it up. Once you finish a long running process, you can keep track of completion time and discard any message that was initiated prior to that period of time.

This problem is normally what's known as Idempotence. Sorta at least. Without a little more details around your requirements I'm not totally sure of what a best approach might be. I'd suggest joining the mailing list for MassTransit and see if someone else a bright idea.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top