Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mkdir cache race condition #8

Open
mjac opened this issue May 30, 2022 · 2 comments
Open

mkdir cache race condition #8

mjac opened this issue May 30, 2022 · 2 comments

Comments

@mjac
Copy link

mjac commented May 30, 2022

Hi KODUS,

Thank you for your library. I had a failure last night on mkdir($path).

ErrorException Warning: mkdir(): File exists mechanism generic handled false

This occurred in … /vendor/kodus/file-cache/src/FileCache.php in Kodus\Cache\FileCache::mkdir at line 380

        if (!file_exists($parent_path)) {
            $this->mkdir($parent_path); // recursively create parent dirs first
        }
        mkdir($path);
        chmod($path, $this->dir_mode);
    }
}

By inspection, it takes time between file_exists($cache_path) and mkdir($path), especially if $parent_path is missing. If user A and user B are both racing to create this directory then mkdir can be called more than once. In this scenario this will raise an ErrorException warning Warning: mkdir(): File exists

if (! file_exists($cache_path) && file_exists(dirname($cache_path))) {
    $this->mkdir($cache_path); // ensure that the parent path exists
}
@kktsvetkov
Copy link

The mkdir() function supports recursively creating sub-folders:

mkdir(
    string $directory,
    int $permissions = 0777,
    bool $recursive = false,
    ?resource $context = null
): bool

recursive
If true, then any parent directories to the directory specified will also be created, with the same permissions.

Using mkdir() there will be no need to reinvent how it works with the private FileCache::mkdir() method, and it seems to me it will solve the competing race conditions as well.

@mjac
Copy link
Author

mjac commented Jun 27, 2023

This appears to be a great solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants