Skip to content

Instantly share code, notes, and snippets.

@videni
Last active July 18, 2023 08:15
Show Gist options
  • Save videni/33c00216b0bec5498d36c1130899d235 to your computer and use it in GitHub Desktop.
Save videni/33c00216b0bec5498d36c1130899d235 to your computer and use it in GitHub Desktop.
php-save-load-using-require-method-race condition-demo
<?php
$cachePath = '/tmp/t.php';
$put = function($cachePath){
$code = '<?php';
$code .= "\n\n";
$code .= 'return ' . var_export([], true) . ';';
file_put_contents($cachePath, $code, LOCK_EX);
};
$get = function($cachePath) {
return require($cachePath);
};
$retry = function($cachePath) use($get) {
$start = microtime (true);
$count = 0;
do {
$result = $get($cachePath);
// Race condition happens when $result is not array.
if (is_array($result)) {
if ($count >0) {
echo sprintf("%s => %s micro seconds".PHP_EOL, $count, (microtime(true) - $start) * 1000000);
}
return $result;
}
$count++;
} while($result === 1 );
};
$load = function($cachePath) use($retry, $put) {
$put($cachePath); // Create the file every time, so we can see the race condition exists
return $retry($cachePath);
};
for($i=0;$i<1000000;$i++) {
$load($cachePath);
}
@videni
Copy link
Author

videni commented Jul 18, 2023

The loop woule take 22 micro seconds , which is acceptable in my case, but a better solution is to diable the truncation problem, check here

@videni
Copy link
Author

videni commented Jul 18, 2023

New way

<?php

$cachePath = '/tmp/t.php';

$put = function($cachePath){
    $code = '<?php';
    $code .= "\n\n";
    $code .= 'return ' . var_export([], true) . ';';

    $fp = fopen($cachePath, "c");

    flock($fp, LOCK_EX);
    fwrite($fp, $code);

    fclose($fp);
};

$get = function($cachePath) {
    return require($cachePath);
};

$load = function($cachePath) use($get, $put) {
    $put($cachePath); // Create the file every time, so we can see the race condition exists

    var_dump($get($cachePath));
};

for($i=0;$i<1000000;$i++) {
    $load($cachePath);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment