diff --git a/src/KeyedFileMutex.php b/src/KeyedFileMutex.php index d2cb6d2..da646f8 100644 --- a/src/KeyedFileMutex.php +++ b/src/KeyedFileMutex.php @@ -5,6 +5,7 @@ use Amp\Sync\KeyedMutex; use Amp\Sync\Lock; use Amp\Sync\SyncException; +use ValueError; use function Amp\delay; final class KeyedFileMutex implements KeyedMutex @@ -13,21 +14,24 @@ final class KeyedFileMutex implements KeyedMutex private readonly Filesystem $filesystem; + private readonly string $directory; + /** - * @param string $pattern Name of temporary file to use as a mutex, including an %s to splice the key in + * @param string $directory Directory in which to store key files. */ - public function __construct(private readonly string $pattern, ?Filesystem $filesystem = null) + public function __construct(string $directory, ?Filesystem $filesystem = null) { - if (!\preg_match("((%%(*SKIP))*%s)", $this->pattern)) { - throw new \Error("Invalid pattern for a mutex, needs to contain an unescaped %s"); - } - $this->filesystem = $filesystem ?? filesystem(); + $this->directory = \rtrim($directory, "/\\"); + + if (!$this->filesystem->isDirectory($this->directory)) { + throw new ValueError(\sprintf('Directory "%s" does not exist', $this->directory)); + } } public function acquire(string $key): Lock { - $filename = \sprintf($this->pattern, \hash('sha256', $key)); + $filename = $this->getFilename($key); // Try to create the lock file. If the file already exists, someone else // has the lock, so set an asynchronous timer and try again. @@ -63,4 +67,9 @@ private function release(string $filename): void ); } } + + private function getFilename(string $key): string + { + return $this->directory . '/' . \hash('sha256', $key) . '.lock'; + } } diff --git a/test/KeyedFileMutexTest.php b/test/KeyedFileMutexTest.php index 2a4cbe0..2852721 100644 --- a/test/KeyedFileMutexTest.php +++ b/test/KeyedFileMutexTest.php @@ -8,8 +8,20 @@ final class KeyedFileMutexTest extends AbstractKeyedMutexTest { + protected function setUp(): void + { + parent::setUp(); + Fixture::init(); + } + + protected function tearDown(): void + { + parent::tearDown(); + Fixture::clear(); + } + public function createMutex(): KeyedMutex { - return new KeyedFileMutex(\sys_get_temp_dir() . '/testmutex-' . \bin2hex(\random_bytes(5)) . '-%s.lock'); + return new KeyedFileMutex(Fixture::path()); } }