-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
Follow-up for #5205: fix high concurrency race condition #11375
Conversation
Composer would fail with an ``` PHP temp directory (/tmp) does not exist or is not writable to Composer. Set sys_temp_dir in your php.ini ``` error when used in parallel. Because it is checking if a file with `md5(microtime())` can be created, which is not sufficiently unique when used in parallel. Since each Composer instance runs in its own process, this can easily be mitigated by not just partitioning based on time of use, but also based on process ID. Original investigation: https://www.drupal.org/project/automatic_updates/issues/3338789#comment-14961390
The failures here are for PHPStan compliance, but the single line that this PR changed is not being complained about … 😅 Note: this is somewhat related to #9580, since this also relates to improving atomicity. |
phpstan currently fails in the master branch already. |
@@ -339,7 +339,7 @@ function_exists('php_uname') ? php_uname('s') . ' / ' . php_uname('r') : 'Unknow | |||
|
|||
// Check system temp folder for usability as it can cause weird runtime issues otherwise | |||
Silencer::call(static function () use ($io): void { | |||
$tempfile = sys_get_temp_dir() . '/temp-' . md5(microtime()); | |||
$tempfile = sys_get_temp_dir() . '/temp-' . getmypid() . '-' . md5(microtime()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use random_bytes
, just Composer already support php 7.2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
random_bytes
would not guarantee that we don't have race conditions. It would just make them more random.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed.
It'd reduce the collision rate, but not prevent it.
Namespacing by process ID prevents it.
Thanks, merged as 5d2d513 in 2.5 branch |
Composer would fail with an
error when used in parallel with a sufficiently high rate of operations. Because it is checking if a file with
md5(microtime())
can be created, which is not sufficiently unique when used in parallel:Since each Composer instance runs in its own process, this can easily be mitigated by not just partitioning based on time of use (
microtime()
), but also based on process ID (getmypid()
). 🥳Original investigation: https://www.drupal.org/project/automatic_updates/issues/3338789#comment-14961390
History
#5205 introduced this in 2016 at 28e9193 and it was refined a few days later in 43eb471 — since then it has been untouched.
Who is affected?
It would seem that Drupal's Automatic Updates & Project Browser functionality (see https://dri.es/drupal-project-browser-empowers-ambitious-site-builders) is the first to run into this. Or to be more precise: its test coverage is the first to run into this, because Drupal core's test suite is so enormous that it has to be massively parallelized in order for it to run in any reasonable amount of time (currently ~1 hour with concurrency = 32).
Work-around until this lands
We added the following to our
\Drupal\package_manager\ProcessFactory::create()
which is a SymfonyProcess
factory which we use to triggercomposer
from within our test suite:… and immediately our test suite began to pass consistently!
We can keep doing this in our end, but I see no reason why Composer would not want to be more robust 😊