Recent Topics

1 Oct 31, 2005 16:44    

There are quite a few actions that need to or should be performed asynchronously. These include:

  • Sending pings to blog directories
  • Double checking referers
  • Pruning stats & sessions
  • Generating static pages
  • Auto updating the antispam blacklist
  • Etc...

The plan is to have a table named T_schedule which would store all actions to be performed.

Then there would be a special script like /htsrv/async.php that should be called periodically (either with cron or with a website watchdog service). Typically once every minute.

This script should take an optional password as a parameter to prevent unwanted flooding.

Of course, the script could also be run manually, from a "schedule" tab in the backoffice that would display a neat list of things to come...

The script would look at the next action to do in T_schedule and do the job then report it done.

Typically the fields in the table would be:

  • sch_ID UNSIGNED INT AUTO_INCREMENT
  • sch_date ENUM(pending,running,finished,failed')
  • sch_start_at DATETIME
  • sch_repeat_after UNSIGNED INT seconds after which we want to repeat the same task. Once the task is finished/failed, a new one gets scheduled. Note: make sure the new time hasn't already passed!
  • sch_action VARCHAR(20) typically 'ping' or 'check-referer' or 'prune-hitlog' etc.
  • sch_params I'm not sure about this one, maybe serializing an array() would be the best.
  • sch_results Not sure either, but if a ping fails we want the error message, etc... maybe a serialized array() too.

The main issue here are transactions. In an INNO_DB mysql (i-e WITH transactions) you can make sure that you start the next pending task only if it has passed start_at time and it's still 'pending', then put it into 'running' mode before any other instance of async.php tries to execute it).

Without transactions you're kinda screwed! We could workaround this by creating a second table called T_schedule_hanlder with an Primary Key were we would store the ID of the task we plan to execute; if we can insert it without error, then we know we're the first trying to do the task.