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 <benjamin.gaussorgues@nextcloud.com>
This commit is contained in:
Benjamin Gaussorgues 2025-12-15 15:58:15 +01:00
parent b15e294a6e
commit fa7e569a16
No known key found for this signature in database
2 changed files with 26 additions and 6 deletions

View file

@ -15,6 +15,8 @@ use Override;
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]

View file

@ -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);
}
}