Search code examples
azurearchitecturecloudcqrscloud-hosting

How to run periodical tasks in the system built with CQRS approach?


It turned out that I need to have some periodical tasks within my system which is run under Windows Azure worker role. I would like to emphasize that it may be any platform Azure, Amazon, in-house solution. In terms of usual system it's not a question how to do the task, but since we are in the cloud and there can be several instances of my role, it might be a problem at some point.

So here is a couple of approaches I can think of:

  1. Usual timers, which are synchronized, say through azure storage, so that not to run the task several times. You can implement it yourself or take one from Lokad for instance. You can either execute your task inline on timer event or send a command into the queue.

    Pros:

    • Common approach, everyone knows timers and how to cook them
    • No need to have a state. Once your instances are up, timers are up and running as well

    Cons:

    • There is additional logic of initializing timers and executing them just next to the main part which is responsible only for processing commands and events from the queue.

  2. Once I got the command to start the task, I send a command StartTask(30 seconds). Once command handler received it, it does the stuff needs to be done and then rethrow the same command with the delay of 30 seconds.

    Pros:

    • Perfectly fits the CQRS design
    • No additional logic related to the timers, pure reactor

    Cons:

    • Paradigm breaking, CQRS itself is really difficult to treat and to use from the beginning. People tend to use known technology(usual timers) even if it doesn't fit the design(cqrs approach) and a result we have messy fusion.
    • Another broken paradigm. Is it stateless or stateful over system restarts? I would say state stored is in the brokered messaging environment. All you need to do is to follow the message processing rules.

My opinion on that:

Personally, I do favor the second approach and all the Cons from it should be moved into Pros part.

Question:

What is the best practice in here? Am I missing something?


Solution

  • My recommendation would be to pick up another component to be responsible for period tasks execution. This way you can decide how it should behave and get it scaled separately from your CQRS workers.

    If you'd prefer to have 1 instance handling both of these tasks (periodic and CQRS) in Azure, you can convert them into Windows Services and use your Worker Role as installer and observer. I have an example built with my solution here.

    Btw, if you use Lokad.Cqrs then your second approach sounds fine if it's separated from main component.