Pregunta

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?

¿Fue útil?

Solución

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.

Otros consejos

What about using something like the scheduler from Windows Mobile Services, or the Windows Azure Store Scheduler app from Aditi? They can be used to kick off just about anything and you can have them send a command out to your system.

If you did option 1 then yes, you'd have to deal with synchronization, but there is redundancy built in there. If you did option 2 and the instance processing the command faulted, make sure that something the tasks then didn't just stop. That would depend on how you have your command retries set up.

If you use azure servicebus as your broker, you can use it's deferred messages feature to defer the send of your command to the time that it needs to be received. http://code.msdn.microsoft.com/windowsazure/Brokered-Messaging-ccc4f879

The scheduled time elapsing is an event - so I'd have a process which creates events like "ScheduleElapsedEvent". You can then implement handlers which create/dispatch commands if necessary.

You can keep the event schedules in a data store which supports some kind of atomic updates. That could be SQL, or NoSQL, like MongoDB. Even when scaled out with replica sets and shards, you can still check and update a record with Mongo. So worker processes could each check this schedule.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top