2

Say I have a database with a table, each record in this table corresponds with an action to be ececuted. This table has a datetime field in which the next moment the action should be executed is stored.

This table is being read by a windows servic and the actions are stored in a datastructure. Every few minutes the service reads the table and new actions are merged into the datastructure, so actions created in the meanwhile don't get missed out.

Each action has a certain repeat interval. When an action has run, the datetime field gets updated to the next moment it should run based on that interval.

Now here's where I'm wondering about the correct course of action: what is the preferred way to actually start the action at its given time?

Say I've an action that should be run at 09:00 in the datastructure, how do I ensure it getting triggered at 09:00? What I currently have in mind is to check the datastructure every minute, compare the current time with the time the action is scheduled and if they match, execute the action and update the execute time of the action according to its associated interval.

As a datastructure I tend to think in the line of a queue, so I can have the next job in front and I only have to check the first, but then I need to rearrange the queue everytime new actions are found.

My main point of interest is a good approach for checking if an action should be executed, an appropriate datastructure will follow. The amount of actions in the table will be really low, no more then 25. I have no control over the database so everything should be done programmatically in C# in case your're wondering. Any tips, experiences or points of advise?

Oxymoron
  • 1,382
  • 4
  • 20
  • 40
  • Do you -need- a database? Who initiates the scheduled tasks? – Ralf de Kleine Dec 23 '10 at 15:13
  • Depends on the system; in a db (or similar) you can persist the system state in case the system falls over. – Tim Barrass Dec 23 '10 at 15:15
  • Yes, a database is needed as a central point of adding new actions et cetera. Of course this is but a small fragment of the system. The only thing of discussion should be the way the times get checked. – Oxymoron Dec 23 '10 at 15:21

4 Answers4

1

Say the granularity is 1 minute. I'd have one thread poll the db frequently and update a list of things to kick off in the next minute. A separate timer thread could then just kick off that list of actions as the minute ticks over.

When you get into the details it gets a little more complicated, as you might want to keep tight reins on the state machine associated with it as well (prepared, running, complete etc).

Tim Barrass
  • 4,813
  • 2
  • 29
  • 55
  • That's about what I had in mind and was wondering if this is the preffered way. – Oxymoron Dec 23 '10 at 15:19
  • Well, it's a way, and if your service level is tight (you need to kick things off pretty much on the minute) it'll work better than the simple answer, which is to poll and kick off what should have started in the last minute. It also helps insulate you to some extent from scaling problems -- polling a *lot* of state info to work out what to run might lead you to miss kicking off tasks. There's a lot of wrinkles, and it really depends on the service you want to guarantee. – Tim Barrass Dec 23 '10 at 15:39
  • Ok, after some thought, I'm going with this :) – Oxymoron Dec 23 '10 at 19:45
1

Use an existing solution...

http://quartznet.sourceforge.net/

Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
0

SQL Agent seems to be a good choice, but you'll not get feedback on the client app'.

ykatchou
  • 3,667
  • 1
  • 22
  • 27
0

what if you had a timer instance as part of the datastructure, and schedule it to run once when this action is due. this way you don't have to check, and as soon as you put your structure in the queue or list, you know that it's scheduled to run. the timer will fire on a separate thread, and so your code will run async to the part that talks to the db...

Alex
  • 2,342
  • 1
  • 18
  • 30
  • Does that mean you need a thread per task? Or would it subscribe to a particular timing event and kick itself off if the event data was the right time? e.g. you have a single timer thread sending out timing events every minute, or however long, and tasks register to receive those events. – Tim Barrass Dec 23 '10 at 17:20