Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cron job for php script that requires VERY long execution time

Tags:

php

cron

I have a php script run as a cron job that executes a set of simple tasks that loops for each user in the database and takes about 30 mins to complete. This process starts over every hour and needs to be as fast and efficient as possible. The problem Im having, is like with any server script, execution time varies and I need to figure out the best cron time settings.

If I run cron every minute, I need to stop the last loop of the script 20 seconds before the end of the minute to make sure that the current loop finishes in time. Over the course of the hour this adds up to a lot of wasted time.

Im wondering if its a bad idea to simple remove the php execution time limit and run the script once an hour and let it run to completion.... is this a bad idea?

like image 663
websiteguru Avatar asked Nov 02 '10 22:11

websiteguru


1 Answers

Assuming you'd like the work done ASAP, don't use cron. Cron is good for things that need to happen at specific times. It's often abused to simulate a background process that would ideally process work as soon as work appears. You should probably write a daemon that runs continuously. (Note: you could also look at a message/work-queue type system, there are nice libraries out there to do this too)

You can write a daemon from scratch using the pcntl functions (since you don't care about multiple worker processes, it's super-easy to get a process running in the background.), or cheat and just make a script that runs forever and run it via screen, or leverage some solid library code like PEAR's System:Daemon or nanoserv

Once the daemonization stuff is taken care of, all you really care about is having a loop that runs forever. You'll want to take care that your script doesn't leak memory, or consume too many resources.

Generally, you can do something like:

<?PHP
// some setup code 
while(true){
    $todo = figureOutIfIHaveWorkToDo();
    foreach($todo as $something){
        //do stuff with $something
        //remember to clean up resources so you don't leak memory!
        usleep(/*some integer*/);
    }
    usleep(/* some other integer */); 
}

And it'll work pretty well.

like image 76
timdev Avatar answered Sep 21 '22 00:09

timdev