AFT
AFT

Reputation: 115

Make sure one copy of php script running in background

I'm using cronjob to run php script that will be executed every 1 minute

I need also to make sure only of copy is running so if this php script is still running after 2 minutes, cronjob should not run another version.

currently I have 2 options and I would like to see your feedback and if you have any more options

Option 1: create a tmp file when the php script start and remove it when php script finish (and check if the file exists) ---> the problem for me with this option is that if I have my php script crash for any reason, it will not run again (the tmp file will not be deleted)

Option 2: run a bash script like the one below to control the php script execution ---> good but looking for something that can be done within php

#!/bin/bash
function rerun {
        BASEDIR=$(dirname $0)
        echo $BASEDIR/$1
        if ps -ef | grep -v grep | grep $1; then
            echo "Running"
            exit 0
    else
            echo "NOT running";
            /usr/local/bin/php $BASEDIR/$1 &
            exit $?
    fi

}  
rerun myphpscript.php

PS: I just saw "Mutex class" at http://www.php.net/manual/en/class.mutex.php but not sure if it's stable and anyone tried it.

Upvotes: 2

Views: 977

Answers (4)

Kamil Dziedzic
Kamil Dziedzic

Reputation: 5032

You might want to use my library ninja-mutex which provides simple interface for handling mutex. Currently it can use flock, memcache, redis or mysql to handle lock.

Below is an example which uses memcache:

<?php
require 'vendor/autoload.php';

use NinjaMutex\Lock\MemcacheLock;
use NinjaMutex\Mutex;

$memcache = new Memcache();
$memcache->connect('127.0.0.1', 11211);
$lock = new MemcacheLock($memcache);
$mutex = new Mutex('very-critical-stuff', $lock);
if ($mutex->acquireLock(1000)) {
    // Do some very critical stuff

    // and release lock after you finish
    $mutex->releaseLock();
} else {
    throw new Exception('Unable to gain lock!');
}

Upvotes: 1

mogul
mogul

Reputation: 4553

I often use the program flock that comes with many linux distributions directly in my crontabs like:

* * * * * flock -n /var/run/mylock.LCK /usr/local/bin/myprogram

Of cause it is still possible to actually start two simultaneously instances of myprogram if you do it by hand, but crond will only make one.

Flock being a small compiled binary, makes it super fast to launch compared to a eventually larger chunk of php code. This is especially a benefit if you have many longer running executions, which it is not perfectly clear that you actually have.

Upvotes: 1

Bad Pussycat
Bad Pussycat

Reputation: 386

I found the best solution for me is creating a separate database user for your Script and limit the concurent connection to 1 for that user.

Upvotes: 0

Antonio Carlos Ribeiro
Antonio Carlos Ribeiro

Reputation: 87789

If you're not on a NFS mount, you can use flock() (http://php.net/manual/en/function.flock.php):

$fh = fopen('guestbook.txt','a')         or die($php_errormsg);
$tries = 3;
while ($tries > 0) {
    $locked = flock($fh,LOCK_EX | LOCK_NB);
    if (! $locked) {
        sleep(5);
        $tries--;
    } else {
        // don't go through the loop again 
        $tries = 0;
    }
}
if ($locked) {
    fwrite($fh,$_REQUEST['guestbook_entry']) or die($php_errormsg);
    fflush($fh)                              or die($php_errormsg);
    flock($fh,LOCK_UN)                       or die($php_errormsg);
    fclose($fh)                              or die($php_errormsg);
} else {
    print "Can't get lock.";
}  

From: http://docstore.mik.ua/orelly/webprog/pcook/ch18_25.htm

Upvotes: 0

Related Questions