Patch for Multi-Threaded Cron Jobs Created

Events happening in the community are now at Drupal community events on www.drupal.org.
Souvent22's picture

So, we have a few modules that we are running for a new client. We're running drupal on about 60K worth of hardware, not including the Oracle database sitting on it's own nice slice of hardware (about 4 tearbytes of data).

So we get data once a week, millions of rows of data (60 million+). The module that we made for the client has a cron job that runs through and makes some updates (this is along with a Database-side PL\SQL script, and a sprinkle of java. A nice orchestra of apps that work beautifully togather). Well, this takes days to do. Literally days, and we noticed a problem when the "aggregator" failed because it through an error trying to read a certain RSS feed. We were not aware of this for about a week. This cost us and our customer prescious time because since aggregator had filed, the clients custom module never got to run!!! Futher more, I concluded that if I put the custom module first, it would eat up all the cron run time. On top of than, we were seriously "under" utilizing our hardware. This was just totally unaccepatble. Thus comes "Mutli-Threaded Cron" runs.

What this does bascially is fire each modules cron run in it's own "sandbox" if you will. So that each modules cron run has the FULL use of PHP's time out, and does not have to worry about another modules cron run failing. The multi-threaded cron also gives more detailed information about each modules cron run. This will better help site admins control the PHP time out variable (which can now also be set dynamically), and see what modules are taking hte most time to run, the least time, and which ones are currently failing.

I believe this is a BIG improvment over the current cron implementation.
Some items I would like to implement next:

  • Emailing the admin if these is a "cron run fail" escalation (say in a 20 min. period, there are 10 failure, email me), etc.
  • Being able to set each modules individual PHP execution time variable. (be nice to give search.module more time than aggregator module)
  • "Throttle" the cron runs. Meaning, I only want to have 5 cron "threads" running at any given time. So it needs to wait until a few have finished before running more cron threads.

You can review the patch and a detailed discussion of it here: http://drupal.org/node/87528
I'll be discussing more options for mutli-threaded cron runs on my blog: http://www.eb3it.com

Below is a snipped from my blog:

So, I have started an ambitous patch. For those who do not want to read the explination, and just gain knowledge by reading the patch:

This patch allows a user to run each modules cron job as it's own thread.

Right now, there is not a lot of information about cron runs other than "they run". I, as an admin, do lik elike this "black box" feature of something running every so often, but not telling me much about what it's doing, errors etc. What this patch does is allow a user to give drupal the command it uses to run cron.php, and it then fires of each modules cron hook in it's own thread. This has big benefits:

  1. Modules that my be "broken" do now interfear with other module runs
  2. Modules that take up a lot of time (e.g. search.module indexing a large site), will not "hog" all the run time. Each cron job has it's own "sandbox" to run in.
  3. Indivual tracking of modules
    1. This patch adds the ability to see the time that each module took to run.
    2. This reporting of each modules run can help a site admin better turn their site.

Note: This also has an option to "truncate" and keep only so many crons in history (simliar to watchdog

Note:It still allows for a "basic" cron.

I think this patch could lead to some interesting things, such as:

  • Setting individual time outs for each module
  • Capturing error messages during a cron run on a per module basis
  • Emailing an admin upon a "cron error" escalation, and information about which module it is.
  • Among other things.....

The basic program flow is as follows:
Only local images are allowed.

Here are some screen shots:

Cron Confiuration
Only local images are allowed.

Main Run Screen with 2 runs (1 basic, 1 advanced)
Only local images are allowed.

Advanced Run

Only local images are allowed.

 

Basic RunOnly local images are allowed.

Comments

Great stuff

boris mann's picture

Looking very good...I have an issue from ages ago pointing this out...that errors "early" in a cron run kills anything else that should run later. Also looking at some aggregator improvements.

Will keep an eye on this.

Outstanding work

moshe weitzman's picture

very nice improvements .... promoted to the sitewide home page.

Drupal from a shell

sun's picture

Great work!
By reading /usr/bin/lynx-source... you might find this issue interesting - might reduce your server load even more. If it does, we'd be happy to hear some basic benchmarking results there.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

Wow, impressive upgrade!

budda's picture

Wow, impressive upgrade! This would be great for a site aggregating many feeds as nodes, and trying to index them all during the same cron run.

A couple of thoughts...

Anonymous's picture

Ok, a couple of comments.

We've run into the same issue, but haven't spent as much time on it (yet). Here are the posts I've made:

http://blog.firebright.com/2006/10/17/problems-with-cron-and-drupal-mult...
http://blog.firebright.com/2006/10/17/more-love-from-drupal-cron/
http://blog.firebright.com/2006/10/19/update-to-multisite-drupal-cron-pr...

Basically, with some minor modifications, we were able to achieve a thread per command line:
bash# HTTP_HOST=”www.foo.com” php -q /path/to/cron.php

This is only helpful for the most simplistic situations, but might be useful for the less technically oriented users out there.

This patch looks like a great start. We're going to start working with it, and will have some contributions / suggestions I'm sure.

A few things:
* If in a case where you have myisam tables and several modules are attempting to lock the same tables simaltaneously, you'll deadlock. As a result, this is only effective if you have a database backend that's transactional or row level locking is supported.
* While this does allow things to run accross multiple processes, you could bottleneck by spawning a very large number of processes simaltaneously. It would be nice to set some kind of a limit - 5 modules at a time and wait until they complete - the equivalent of a thread pool. Think about running 100 module's crons simaltaneously. That would bring almost any machine to it's knees.
* There is a typo in the patch, "primary key" is mispelled as "priamry key" in the bottom of the patch.

We have a few other issues with the way cron handles things (anyone who knows what I'm talking about will react to these dirty words: watchdog, accesslog, cache, sessions), but I won't pollute this thread.

I'd be interested in other's reactions to the above.

any thoughts on actual php threads as opposed to forked?

Anonymous's picture

Just a quick followup.

Has anyone thought about using the actual thread library included in php5 to handle this situation? I know that php4 support rules this out, but most customers who are heavily invested in Drupal multisite are going to have some serious infrastructure behind it, and may have actually compiled thread support in php and apache.

If there's been any experimentation, we'd LOVE to hear about it.

Enterprise

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week