✨feature: Initial MVP
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
// phpcs:disable PEAR.Commenting.FileComment,PEAR.Commenting.ClassComment
|
||||
|
||||
/**
|
||||
* File locking support.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace IronKanban\Support;
|
||||
|
||||
/**
|
||||
* Runs callbacks while holding an exclusive file lock.
|
||||
*/
|
||||
final class FileLock
|
||||
{
|
||||
/**
|
||||
* Execute a callback under an exclusive lock.
|
||||
*
|
||||
* @param string $path Lock file path.
|
||||
* @param callable $callback Callback to execute.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function run(string $path, callable $callback): mixed
|
||||
{
|
||||
ensure_directory(dirname($path));
|
||||
$handle = fopen($path, 'c+');
|
||||
|
||||
if ($handle === false) {
|
||||
throw new \RuntimeException('Unable to open lock file: ' . $path);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!flock($handle, LOCK_EX)) {
|
||||
throw new \RuntimeException('Unable to lock file: ' . $path);
|
||||
}
|
||||
|
||||
return $callback();
|
||||
} finally {
|
||||
flock($handle, LOCK_UN);
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user