Using Drush to Run Cron Hooks

There are times when I need more control over individual cron hooks, but do not really need a full solution like Ultimate Cron or Elysia Cron. I just wanted something to run the cron hooks of one or more modules without running every cron hook on the Drupal site I’m working on. Something like drush cron module_name is what I had in mind.

Below is one solution to this problem. It’s a simple drush extension called lightcron with one command: run-cron-hooks, which is aliased to rch. You can pass one or more module names separated by spaces, similar to the pm-download command. This extension is by no means as robust as the two cron modules above. I will have to look into possible performance issues that may results in running multiple drush commands that fully bootstrap Drupal to execute one function. It may also be worthwhile investigating multithreading with Drush for an extension handling cron tasks like this. Despite these shortcomings, this extension does what I need it to do: run a single cron hook.

Usage

If you wanted to run hook_cron() for an individual module e.g. feeds, you would run:

drush rch feeds

The above command would fire feeds_cron() if feeds is installed and enabled on your site.

Running more than one cron hook is just as easy. Say you want to run the cron hooks for feeds, xmlsitemap, and search:

drush rch feeds scheduler search

If the above command succeeds, you would receive the following output:

feeds (2013-10-31 07:20:54 -0400): cron hook executed.
scheduler (2013-10-31 07:20:54 -0400): cron hook executed.
search (2013-10-31 07:20:54 -0400): cron hook executed.

Lightcron will let you know if the module is enabled, but doesn’t have a cron hook:

$> drush rch devel
devel does not have a cron hook.

You’ll also know if the module doesn’t exist:

$> drush rch dne
dne does not exist i.e. not installed and enabled.
If a hook is not executed, drush will log it as an error.

Installation

There are a few directories drush looks in for extensions. To keep things simple, I’d suggest placing this extension in ~/.drush. The lightcron extension can be found on my github account in drushexts.

Assuming ~/.drush/drushexts does not exist on your machine, run the clone command below to create and fill it. Change drushexts to something else if ~/.drush/drushexts exists on your machine so you don’t override anything.

# Put the repo in ~/.drush/drushexts
git clone https://github.com/jh3/drushexts.git \
~/.drush/drushexts
# Clear drush's cache after you add new extensions
drush cc drush

The code

Below is the meat of the extension. The full extension can be found in drushexts on github.

Lightcron’s implementation of hook_drush_command():

 "Run a cron hook for a specific module or set of modules",
    'arguments' => array(
      'modules' => 'The modules that have the cron hooks you want to execute',
    ),
    'examples' => array(
      'drush rch scheduler' => 'Run the scheduler cron hook',
      'drush rch feeds xmlsitemap' => 'Run the cron hooks for feeds and xmlsitemap',
    ),
    'aliases' => array('rch'),
    // http://drush.ws/docs/bootstrap.html
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
  );
  return $items;
}

And the callback for run-cron-hooks:

 $module, '!date' => date('Y-m-d H:i:s O'))), 'ok');
      }
      else {
        drush_log(dt('!module does not have a cron hook.', array('!module' => $module)), 'error');
      }
    }
    else {
      drush_log(dt('!module does not exist i.e. not installed and enabled.', array('!module' => $module)), 'error');
    }
  }
}

Creating Drush extensions is straightforward if you already have an understanding of custom module development. The naming convention for the callbacks was initially confusing. Reading through the source of the core Drush commands helps a lot. The sandwich example is very helpful as well.

Be sure to check out the Drush API reference along with the built-in examples by running drush topic for even more help.