Archivage : verrou exclusif par boîtier, chdir dans cron_quarantaine

This commit is contained in:
2026-10-02 14:56:27 +00:00
parent 3a9056f5bc
commit b584d411e4
3 changed files with 306 additions and 220 deletions
+51
View File
@@ -22,6 +22,57 @@ const REPERTOIRE_VERSIONS_SQL = "/home/koriolan/versions/shipheart/ressources/sq
const REPERTOIRE_QUARANTAINE = "/home/koriolan/bateaux/archives/quarantaines";
const REPERTOIRE_ERREURS = "/home/koriolan/bateaux/archives/erreurs";
// ----------------------------------------------------------------------------
// Répertoire des verrous par boîtier (cf Verrouiller_boitier()). Les fichiers
// de verrou ne sont JAMAIS supprimés : supprimer un fichier de verrou pendant
// qu'un autre processus le détient ouvrirait une fenêtre où deux processus
// verrouillent chacun un fichier différent portant le même nom.
// ----------------------------------------------------------------------------
const REPERTOIRE_VERROUS = "/home/koriolan/bateaux/verrous";
// ----------------------------------------------------------------------------
// Verrou exclusif NON bloquant sur un boîtier (adresse MAC), partagé par
// cron_archivage.php, cron_quarantaine.php et, plus tard, le traitement à la
// demande depuis le portail (synthèse §44.6) : deux traitements simultanés du
// même boîtier pourraient sinon créer deux générations ou charger deux fois
// dans la même base. Un boîtier déjà verrouillé est simplement sauté, il sera
// repris au passage suivant - jamais d'attente.
// Le verrou est libéré par Liberer_boitier(), et de toute façon par le
// système à la fin du processus (y compris en cas d'arrêt brutal) - aucun
// verrou "orphelin" possible, contrairement à un simple fichier témoin.
// Renvoie ['ok'=>true, 'poignee'=>resource] ou ['ok'=>false, 'raison'=>string].
// ----------------------------------------------------------------------------
function Verrouiller_boitier($adresse_mac)
{
// Nom de fichier construit uniquement à partir des 12 caractères hexadécimaux de l'adresse
// (quel que soit son format d'écriture, avec ou sans ':') - jamais de chemin arbitraire :
$hex = strtoupper(preg_replace('/[^0-9A-Fa-f]/', '', (string)$adresse_mac));
if (strlen($hex) !== 12) return ['ok' => false, 'raison' => "adresse MAC invalide pour un verrou"];
if (!is_dir(REPERTOIRE_VERROUS) && !@mkdir(REPERTOIRE_VERROUS, 0770, true) && !is_dir(REPERTOIRE_VERROUS))
{
return ['ok' => false, 'raison' => "répertoire de verrous " . REPERTOIRE_VERROUS . " impossible à créer"];
}
// Mode 'c' : crée le fichier s'il n'existe pas, sans jamais le tronquer.
$poignee = @fopen(REPERTOIRE_VERROUS . "/boitier_{$hex}.lock", 'c');
if ($poignee === false) return ['ok' => false, 'raison' => "fichier de verrou impossible à ouvrir"];
if (!flock($poignee, LOCK_EX | LOCK_NB))
{
fclose($poignee);
return ['ok' => false, 'raison' => "déjà en cours de traitement par un autre processus"];
}
return ['ok' => true, 'poignee' => $poignee];
}
function Liberer_boitier($poignee)
{
if (!is_resource($poignee)) return;
flock($poignee, LOCK_UN);
fclose($poignee);
}
// ----------------------------------------------------------------------------
// Résout l'affectation active d'un boîtier (par adresse MAC) - cf synthèse