Slow Cron.php

Slow Cron.php

by Rob Hudson -
Number of replies: 17
I posted this in another forum but didn't get any response so I'm hoping someone can help me!

I'm trying to figure out why our cron.php takes a long time (50 seconds) to run. I've done some profiling and it seems the call to session_destory() takes the majority of the time (48 seconds). Why is this? Whilst the cron job is running our moodle install runs really slowly.

Could this be fixed by running cron.php using the php command?

We have a duplicate test system which runs the same cron job in about 2 seconds!

It appears that apache is also hanging whilst this command happens -- meaning that our server is out of action for a minute at a time!

Thanks for any help,

Rob
Average of ratings: -
In reply to Rob Hudson

Re: Slow Cron.php

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
Wait, wait, let me get this straight - you think 50 seconds is a 'long time'?

smile

I think ours usually takes about ten minutes or so. (We have it set to run half-hourly I think.) There are times when we've had issues with certain tasks during cron that took several hours. smile For that reason we also have custom code that makes sure two instances of cron can't run at the same time, which is Bad if allowed to happen.

That said, I don't know why your problems are occurring. sad It definitely sounds like you should consider running it from commandline rather than through the web server though. It would seem reasonable that doing this should mean apache won't hang and there shouldn't be a session, so you shouldn't have a possibility that session_destroy takes a long time (unless I am misunderstanding).

--sam
In reply to sam marshall

Re: Slow Cron.php

by Rob Hudson -
Well, the slow bit is the session destroy!

That's pretty much where I got to...

Thanks for the help!

Rob
In reply to sam marshall

Re: Slow Cron.php

by Timothy Takemoto -

Sam wrote

> For that reason we also have custom code that makes sure two instances of cron can't run at the same time

That sounds interesting. Please would you tell us a bit more about your code? Is it php, or more imbedded in apache/C/the server?

I wonder if moodle could (or even if later versions of moodle do) refuse to run a cron while a previous cron is still running.

We are having a similar problem. Sometimes two different moodles attempt to update at the same time, or sometimes for one reason or another a backup does not finish and the cron runs again resulting in multiple sessions accumulating till the server keels over, so so I hear.

There is some unix command that tells you what sessions are running on what proportion of system resources and apparently. I wonder what it is.

Tim

In reply to Timothy Takemoto

Re: Slow Cron.php

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
> I wonder if moodle could (or even if later versions of moodle do) refuse to run a cron while a previous cron is still running.

It would be possible (in fact it would be trivial) to do this with a little "running" flag.

In fact here is the bug for it! MDL-11309
In reply to sam marshall

Re: Slow Cron.php

by Séverin Terrier -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Testers Picture of Translators
we also have custom code that makes sure two instances of cron can't run at the same time

Could you give more details please (perhaps with code ?) ?

Séverin
In reply to Séverin Terrier

Re: Slow Cron.php

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
This is what I use on moodle.org:

crontab:
---------
 
*/30 * * * * /opt/bin/moodlecron


/opt/bin/moodlecron
-------------------

#!/bin/bash

# Create a new lock (and exit this script if one already exists)
# -p = include PID ... and if a lock exists but the process doesn't then consider it stale

if (dotlockfile -p -r 0 /var/tmp/moodlecron.lock) then

# Perform the actual cron work

nice /opt/bin/php /var/www/html/moodle/admin/cron.php >> /logs/moodle_cron.txt 2>&1
nice /opt/bin/cleanupsessions

# Release the lock, allowing this script to be run next time

dotlockfile -u /var/tmp/moodlecron.lock

fi


And of course I installed dotlockfile

In reply to Martin Dougiamas

Re: Slow Cron.php

by Séverin Terrier -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Testers Picture of Translators
Thanks a lot for the explanation , and the code smile
In reply to Séverin Terrier

Re: Slow Cron.php

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
Martin's code is of course fine. We did it in php. This should go into core really but I haven't bothered making the effort to get it agreed (too much work!)

mtrace("Server Time: ".date('r',$timenow)."\n\n");
// ou-specific begins
// Check cron is not already running (on either server).
// Logic:
// 1. Check if file exists in moodledata. If it exists, assume cron is
// already running.
// 2. If the file exists, but has a date earlier than 8 hours ago,
// perhaps that indicates that a previous run of cron crashed. Delete
// file and proceed anyway.
$maxagehours=8;
$lockfile=$CFG->dataroot.'/cron.is.running';
if(file_exists($lockfile)) {
$filetime=filemtime($lockfile);
if($filetime < $timenow-$maxagehours*60*60) {
mtrace("Warning: deleting lock file, more than $maxagehours hours old");
unlink($lockfile);
} else {
mtrace("Exiting: cron is already running, since ".date('r',$filetime));
exit;
}
}
file_put_contents($lockfile,
"# While this file exists, cron is running (or has crashed).
# This file is valid until ".date('r',$timenow+$maxagehours*60*60)."\n");
// ou-specific ends

and at the end

// ou-specific begins
unlink($lockfile);
// ou-specific ends
mtrace("Cron script completed correctly");

--sam
Average of ratings: Useful (3)
In reply to sam marshall

Re: Slow Cron.php

by Dan Poltawski -
Petr wrote a generic locking mechanism in moodle for stats cron processing recently which I am pretty sure would be even simpler than this. Hopefully he'll chime in with the details ;)
In reply to sam marshall

Re: Slow Cron.php

by Roger Emery -
Thank you Sam.

Hopefully this will solve our recent multiple cron / multiple back-up issues (one cron ran for three days due to the other..*how many*...crons running at the same time).
In reply to sam marshall

Re: Slow Cron.php

by Janet Smith -
Sam's code above looks very useful. Does this go into the backup_scheduled.php file? Does anyone know where exactly the code should go in this file? I am guessing put the main portion around line 20 and then the last couple lines at the very end? Can someone confirm?
In reply to Janet Smith

Re: Slow Cron.php

by Pedro Liska -
Sam's code should be placed at the top and bottom of this file:

$CFG->dirroot . '/admin/cron.php'

/admin/cron.php executes the backup_sched.php file.

I'm going to use Sam's code as well. Thanks for sharing Sam!
In reply to Martin Dougiamas

Re: Slow Cron.php

by Brent Lee -
Martin,

Are you still using this same practice for Moodle.org?

Cheers,

Brent.
In reply to sam marshall

Re: Slow Cron.php

by Rob Hudson -
Well, I implemented the php command line call as opposed to using wget and guess what: moodle still doesn't allow access when the script is running!

It is still taking ages to run the session destroy method call... for the moment I've removed the line from cron.php

Will this cause problems?

Cheers

Rob