Portable Cron

Revision as of 12:47, 4 October 2008 by Ric (talk | contribs) (New page: <span id="top"></span> <div style="padding:0;margin:0; border-bottom:3px inset #000000"> {| | MPG UniCenter || Portable Cron design running on Uniform Server...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

MPG UniCenter

Portable Cron design running on Uniform Server 3.5-Apollo

Portable Cron

After installing Drupal you will notice it requires a script to be run periodically using something called Cron. This is a Unix process unavailable on a Windows machine. Although Drupal provides an option to run this script manually I thought it would be useful to simulate a Cron process on Uniform Server. The technique can be adapted to other scripts that require a Cron process to be run.

Top

Cron job

The script Drupal requires running via a cron-job is cron.php, which can be found in either the server web-root or the folder you installed Drupal in.

When logged in as administrator you can run the cron job manually using a link provided. Alternatively run the script from a browser by typing the following:

http://localhost/cron.php or if install in a separate folder named “drupal” http://localhost/drupal/cron.php

On a local server all that is required is to run cron.php from a batch file using PHP in CLI mode (check out this page for CLI mode)

Top

Batch file - intro

Create a batch file named run_cron.bat add the following two lines and save it in folder “Uniform Server”:

udrive\usr\local\php\php.exe -n udrive\www\cron.php
pause

PHP is run with switch –n this prevents PHP loading a configuration file (php.ini). Second parameter is the path and file name of the file to be run.

Note 1: “pause” is included allowing you to view any error messages.

Note 2: I install Drupal in the web-root folder “www” if you install in a seperate folder (drupal) remember to change the path to udrive\www\drupal\cron.php

Top

Testing

Quick test:

  • Start Uniform Server
  • Run the above batch file

You will see a list of warnings and a fatal error message similar to this:

J:\drupal_server\Uniform Server>udrive\usr\local\php\php.exe -n udrive\www\cron.php
Warning: include_once(./includes/bootstrap.inc): failed to open stream: No such file or directory in J:\drupal_server\Un
iform Server\udrive\www\cron.php on line 9
Warning: include_once(): Failed opening './includes/bootstrap.inc' for inclusion (include_path='.;C:\php5\pear') in J:\d
rupal_server\Uniform Server\udrive\www\cron.php on line 9
Fatal error: Call to undefined function drupal_bootstrap() in J:\drupal_server\Uniform Server\udrive\www\cron.php on lin
e 10

J:\drupal_server\Uniform Server>pause
Press any key to continue . . .

I have included the above to highlight paths are local and not server relative as expected by Drupal. The solution is to run cron.php on your live server as explained below.

Top

Additional script and new batch file

Create a new PHP script named run_cron.php containing the following code and save it to folder containing cron.php.

<? $dummy = file("http://localhost/cron.php"); ?>

This script executes the file function reading the content of cron.php into a dummy array (the variable $dummy is never used). What’s important is the path to the file, its what would be typed into a browser meaning that page is run on the server with correct paths to other files it calls.

Change the batch file to call this new script as follows:

udrive\usr\local\php\php.exe -n udrive\www\run_cron.php 
pause

Run the new batch file this time there will be no errors.

Log into Drupal as admin; click the Status report link. To the right of “Cron maintenance tasks” note the “Last run” time.

Run batch file again, refresh page the time will update confirming scripts work.

Note: Just below “Cron maintenance tasks” you will find the link to manually run the cron task.

OK! Seems like we have created a long-winded method to duplicate the same function. That’s not strictly true the two files batch and script provide full control independent of a web browser.

Top

Automation

There are two methods of periodically running run_cron.bat the first is to set-up Windows to schedule a task. I will not be covering this check out the following link for details http://support.microsoft.com/kb/308569

The second method is to modify run_cron.bat so it periodically runs the line of code that executes run_con.php; this has the advantage of portability. Remainder of this write-up covers this in detail.

Top

Batch file with delay loop

Modify run_cron.bat as follows:

:next
ping 1.1.1.1 -n 1 -w 60000 > nul
udrive\usr\local\php\php.exe -n udrive\www\run_cron.php 
goto :next

The ping command introduces a delay of 60 seconds (60000ms). After this delay cron-job is run and loops back to “next” repeating the whole process.

Run the batch file and you will instantly observe a problem! The command window remains open.

Interestingly when Apache is run as a program it suffers from this same problem. Solution is to run Apache in a hidden process using uniserve.exe. Applying this to our cron problem results in a working solution although it requires a second batch file as follows:

Create a new batch file in folder “Uniform Server” named run_cron_hidden.bat and add the following lines:

start udrive\home\admin\program\uniserv.exe run_cron.bat
pause

Run this new batch file, when requested press any key this closes the command window however run_cron command window remains running and hidden.

The above is a solution but far from ideal once started cron cannot be stopped until the PC is restarted (normally what is required). The reliance of ping as a delay is another issue. If the IP address is active the delay fails, solution is to use unidelay.exe for details refer to this page.

Top

Proposed solution

Final batch files and scripts are shown below:

J:\drupal_server\Uniform Server\udrive\www\run_cron.php

<? $dummy = file("http://localhost/cron.php"); ?>

J:\drupal_server\Uniform Server\run_cron_hidden.bat

start udrive\home\admin\program\uniserv.exe run_cron.bat

J:\drupal_server\Uniform Server\run_cron.bat

:next
unidelay.exe 60
udrive\usr\local\php\php.exe -n udrive\www\run_cron.php
goto :next
exit

Note: unidelay.exe 60 runs the cron-job every 60 seconds increase this as required.

Top

Summary

The above-proposed solution is generic and can be adapted to other application requiring periodic running of an application.

As part of the LCC series I cover a small utility that specifically targets Drupal with a portable cron program. You can recompile this to meet your own requirements or use it as is.

Top


  Ric