From fa7e569a1611a80828cb87fa52dd5dcbd9279448 Mon Sep 17 00:00:00 2001 From: Benjamin Gaussorgues Date: Mon, 15 Dec 2025 15:58:15 +0100 Subject: [PATCH] fix(snowflakes): FileSequence generator must always use the same dir `TempManager::getTemporaryFolder` is returning a random directory. FileSequence needs always the same directory, even if different processes. Signed-off-by: Benjamin Gaussorgues --- lib/private/Snowflake/FileSequence.php | 22 +++++++++++++++++++++- tests/lib/Snowflake/FileSequenceTest.php | 10 +++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/private/Snowflake/FileSequence.php b/lib/private/Snowflake/FileSequence.php index 665b447c0c30c..53a3bc240690d 100644 --- a/lib/private/Snowflake/FileSequence.php +++ b/lib/private/Snowflake/FileSequence.php @@ -15,6 +15,8 @@ class FileSequence implements ISequence { /** Number of files to use */ private const NB_FILES = 20; + /** Lock file directory **/ + public const LOCK_FILE_DIRECTORY = 'sfi_file_sequence'; /** Lock filename format **/ private const LOCK_FILE_FORMAT = 'seq-%03d.lock'; /** Delete sequences after SEQUENCE_TTL seconds **/ @@ -25,7 +27,25 @@ class FileSequence implements ISequence { public function __construct( ITempManager $tempManager, ) { - $this->workDir = $tempManager->getTemporaryFolder('.snowflakes'); + $this->workDir = $tempManager->getTempBaseDir() . '/' . self::LOCK_FILE_DIRECTORY; + $this->ensureWorkdirExists(); + } + + private function ensureWorkdirExists(): void { + if (is_dir($this->workDir)) { + return; + } + + if (@mkdir($this->workDir, 0700)) { + return; + } + + // Maybe the directory was created in the meantime + if (is_dir($this->workDir)) { + return; + } + + throw new \Exception('Fail to create file sequence directory'); } #[Override] diff --git a/tests/lib/Snowflake/FileSequenceTest.php b/tests/lib/Snowflake/FileSequenceTest.php index 82d2f9fefbeca..70054fee14473 100644 --- a/tests/lib/Snowflake/FileSequenceTest.php +++ b/tests/lib/Snowflake/FileSequenceTest.php @@ -20,16 +20,16 @@ class FileSequenceTest extends ISequenceBase { public function setUp():void { $tempManager = $this->createMock(ITempManager::class); - $this->path = uniqid(sys_get_temp_dir() . '/php_test_seq_', true); - mkdir($this->path); - $tempManager->method('getTemporaryFolder')->willReturn($this->path); + $this->path = sys_get_temp_dir(); + $tempManager->method('getTempBaseDir')->willReturn($this->path); $this->sequence = new FileSequence($tempManager); } public function tearDown():void { - foreach (glob($this->path . '/*') as $file) { + $lockDirectory = $this->path . '/' . FileSequence::LOCK_FILE_DIRECTORY; + foreach (glob($lockDirectory . '/*') as $file) { unlink($file); } - rmdir($this->path); + rmdir($lockDirectory); } }