I have two or more PHP apps running on Docker that process files in a shared directory. So I need a lock system to prevent those apps working on the same file. Ex: there are 3 files in the directory, if app1 works on file1, app2 have to skip this file1 and pass to file2. I have a script like this in the apps:
// $files is a list of all files in the directory
foreach($files as $file) {
$this->performFile($file);
$this->moveFileToHistory($file);
}
I tried to use file or directory as lock so for example if a file1.lock(file or directory) exists it is locked.
$dir = md5($file) . 'lock';
if (@mkdir($dir, 0700)) {
$this->performFile($file);
$this->moveFileToHistory($file);
rmdir($dir);
}
and it works but in case of crash or interruption I think that it is better to use something that can be cleaned or released even if PHP itself crashes.So I was thinking about:
Is there a better way to go than using file or directory in this case?
I finally came up with a solution. There is this component symfony/lock from symfony that you can use for managing locks. You can define the expiration time that fits exactly my needs. Here an example:
foreach($files as $file) {
// the lock expires after 60s if $lock->release() is not called due to a randomly reason.
$lock = $this->lockFactory->createLock(md5($file), 60);
if (!$lock->acquire()) {
continue;
}
try {
$this->performFile($file);
$this->moveFileToHistory($file);
} finally {
$lock->release();
}
}
You can use those available stores to manage locks.