user1661677 user1661677 - 6 months ago 26
PHP Question

Should I avoid a one hour sleep()?

I'm using the DigitalOcean API to create droplets when my web application needs the extra resources. Because of the way DigitalOcean charges (min. one hour increments), I'd like to keep a created server on for an hour so it's available for new tasks after the initial task is completed.

I'm thinking about formatting my script this way:

$time = time();
// run resource heavy task
sleep($time + 3599);

Is this the best way to achieve this?


It doesn't look like a good idea, but the code is so simple, nothing can compete with that. You would need to make sure your script can run, at least, for that long.

Note that sleep() should not have $time as an argument. It sleeps for the given number of seconds. $time contains many, many seconds.

I am worried that the script might get interrupted, and you will never delete the droplet. Not much you can do about that, given this script.

Also, the sleep() itself might get interrupted, causing it to sleep much shorter than you want. A better sleep would be:

$remainingTime = 3590;
do {
  $remainingTime = sleep($remainingTime);
} while ($remainingTime > 0); 

This will catch an interrupt of sleep(). This is under the assumption that FALSE is -1. See the manual on sleep():

Then there's the problem that you want to sleep for exactly 3599 seconds, so that you're only charged one hour. I wouldn't make it so close to one hour. You have to leave some time for DigitalOcean to execute stuff and log the time. I would start with 3590 seconds and make sure that always works.

Finally: What are the alternatives? Clearly this could be a cron job. How would that work? Suppose you execute a PHP script every minute, and you have a database entry that tells you which resource to allocate at a certain start time and deallocate at a certain expire time. Then that script could do this for you with an accurary of about a minute, which should be enough. Even if the server crashes and restarts, as long as the database is intact and the script runs again, everything should go as planned. I know, this is far more work to implement, but it is the better way to do it.