Parfois, il est nécessaire de s’assurer que plusieurs instances d’un même script CLI ne puisse pas être lancées à la fois. Prenons par exemple, un script chargé de vider une pile d’emails stockés dans une base de données à intervalle régulier (une minute) via un crontab.

Sans ce système de lock, il serait possible, pour une obscure raison, qu’il soit lancé par le crontab plusieurs fois : on aurait alors un petit script de spam qui enverrait en double ou pire les mêmes emails aux mêmes personnes (si ce sont des clients c’est embêtant !)

Pour éviter ce genre de cas de figure plusieurs solutions sont disponibles :

  • on tue les processus déjà lancés avant d’en relancer un autre (en prenant le risque de ne pas laisser terminer la premier instance)
  • on empêche les nouvelles instances de se lancer si une d’elle est déjà en cours (c’est cette solution que j’ai retenue)

L’idée étant de faire un script générique que l’on puisse utiliser sur n’importe qu’elle plateforme PHP5 c’est pourquoi pour que la première instance puisse déclarer qu’elle est en fonctionnement j’ai choisi de stocker son PID dans un fichier mais on aurait aussi pu utiliser memcache à la place.

Fini la présentation, voici maintenant un morceau de script générique que l’on peut coller en haut de chaque script CLI pour mettre en place le système de lock.

if(php_sapi_name() == 'cli') {
	$lockname = '/tmp/'.basename($argv[0], '.php').'.lock';
	$pid = is_file($lockname) ? trim(file_get_contents($lockname)) : false;
	if (($pid !== false) && posix_kill($pid, 0)) {
		die('Error: Batch is already running with PID: '.$pid."\n");
	}
	else {
		register_shutdown_function('unlink', $lockname);
		$fp = fopen($lockname, 'w');
		fwrite($fp, posix_getpid());
		fclose($fp);
	}
}

Les fonctions remarquables sont les posix_xxx accessibles uniquement en mode CLI (d’où la vérification du mode d’appel tout en haut avec php_sapi_name) et register_shutdown_function qui permet d’éxécuter une fonction à la fin du script (peu importe la façon dont sa fin est arrivée !)

Je ne trouve pas tellement de défauts à cette méthode alors si vous vous en voyez n’hésitez pas à les partager via les commentaires.

Tagged with:
 
About The Author

Clément

Clément est développeur Back-Office chez une société spécialiste de la veille et de l'analyse sur Internet. Quand il rentre chez lui, il passe le plus clair de son temps à chercher une formule magique pour devenir riche sur Internet entre deux projets personnels.

One Response to Système de lock d’éxécution de script PHP

  1. Bons tips (sincèrement) && pardon pour le bl posé :p

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>