FileSystemWatcher : surveillance du systeme de fichiers
Qu’est-ce que FileSystemWatcher
Async\FileSystemWatcher est un observateur persistant des modifications de fichiers et de repertoires.
Contrairement aux approches ponctuelles, FileSystemWatcher s’execute en continu et delivre les evenements via l’iteration standard foreach :
<?php
use Async\FileSystemWatcher;
$watcher = new FileSystemWatcher('/path/to/dir');
foreach ($watcher as $event) {
echo "{$event->filename}: renamed={$event->renamed}, changed={$event->changed}\n";
}
?>
L’iteration suspend automatiquement la coroutine lorsque le buffer est vide et la reprend lorsqu’un nouvel evenement arrive.
FileSystemEvent
Chaque evenement est un objet Async\FileSystemEvent avec quatre proprietes readonly :
| Propriete | Type | Description |
|---|---|---|
path |
string |
Le chemin passe au constructeur de FileSystemWatcher |
filename |
?string |
Le nom du fichier qui a declenche l’evenement (peut etre null) |
renamed |
bool |
true – le fichier a ete cree, supprime ou renomme |
changed |
bool |
true – le contenu du fichier a ete modifie |
Deux modes de buffering
Fusion (par defaut)
En mode fusion, les evenements sont regroupes par la cle path/filename. Si un fichier a change plusieurs fois avant que l’iterateur ne l’ait traite, un seul evenement avec les drapeaux fusionnes reste dans le buffer :
<?php
use Async\FileSystemWatcher;
// coalesce: true -- par defaut
$watcher = new FileSystemWatcher('/tmp/dir');
?>
C’est optimal pour les scenarios typiques : hot-reload, reconstruction a la modification de la configuration, synchronisation.
Brut
En mode brut, chaque evenement du systeme d’exploitation est stocke comme un element separe dans un buffer circulaire :
<?php
use Async\FileSystemWatcher;
$watcher = new FileSystemWatcher('/tmp/dir', coalesce: false);
?>
Adapte lorsque l’ordre exact et le nombre d’evenements importent – audit, journalisation, replication.
Constructeur
new FileSystemWatcher(
string $path,
bool $recursive = false,
bool $coalesce = true
)
path – chemin vers un fichier ou un repertoire. Si le chemin n’existe pas, une Error est lancee.
recursive – si true, les repertoires imbriques sont egalement surveilles.
coalesce – mode de buffering : true – fusion d’evenements (HashTable), false – tous les evenements (buffer circulaire).
La surveillance demarre immediatement a la creation de l’objet. Les evenements sont mis en buffer meme avant le debut de l’iteration.
Cycle de vie
close()
Arrete la surveillance. L’iteration courante se termine apres le traitement des evenements restants dans le buffer. Idempotent – les appels repetes sont surs.
<?php
$watcher->close();
?>
isClosed()
<?php
$watcher->isClosed(); // bool
?>
Fermeture automatique
Si l’objet FileSystemWatcher est detruit (sort du scope), la surveillance s’arrete automatiquement.
Exemples
Hot-Reload de la configuration
<?php
use Async\FileSystemWatcher;
use function Async\spawn;
spawn(function() {
$watcher = new FileSystemWatcher('/etc/myapp', recursive: true);
foreach ($watcher as $event) {
if (str_ends_with($event->filename ?? '', '.yml')) {
echo "Configuration modifiee : {$event->filename}\n";
reloadConfig();
}
}
});
?>
Surveillance avec limite de temps
<?php
use Async\FileSystemWatcher;
use function Async\spawn;
use function Async\delay;
$watcher = new FileSystemWatcher('/tmp/uploads');
spawn(function() use ($watcher) {
delay(30_000);
$watcher->close();
});
foreach ($watcher as $event) {
processUpload($event->filename);
}
echo "Surveillance terminee\n";
?>
Surveillance de plusieurs repertoires
<?php
use Async\FileSystemWatcher;
use function Async\spawn;
$dirs = ['/var/log/app', '/var/log/nginx', '/var/log/postgres'];
foreach ($dirs as $dir) {
spawn(function() use ($dir) {
$watcher = new FileSystemWatcher($dir);
foreach ($watcher as $event) {
echo "[{$dir}] {$event->filename}\n";
}
});
}
?>
Mode brut pour l’audit
<?php
use Async\FileSystemWatcher;
use function Async\spawn;
spawn(function() {
$watcher = new FileSystemWatcher('/secure/data', coalesce: false);
foreach ($watcher as $event) {
$type = $event->renamed ? 'RENAME' : 'CHANGE';
auditLog("[{$type}] {$event->path}/{$event->filename}");
}
});
?>
Annulation via Scope
FileSystemWatcher se termine correctement lorsque le scope est annule :
<?php
use Async\FileSystemWatcher;
use function Async\spawn;
use function Async\delay;
spawn(function() {
$watcher = new FileSystemWatcher('/tmp/test');
spawn(function() use ($watcher) {
foreach ($watcher as $event) {
echo "{$event->filename}\n";
}
echo "Iteration terminee\n";
});
delay(5000);
$watcher->close();
});
?>
Voir aussi
- Coroutines – l’unite de base de la concurrence
- Channel – channels CSP pour le transfert de donnees
- Annulation – le mecanisme d’annulation