Problem/Motivation
#3036494: Race condition in ImageStyle::createDerivative() partially fixed race conditions when generating image styles. However it did not fix the problem completely.
Steps to reproduce
A fail due to this can be caused by running \Drupal\Tests\thunder\FunctionalJavascript\ArticleCreationTest on apache or nginx. The test randomly fails with:
Failed to create style directory: public://styles/entity_browser_thumbnail/public/2016-05
Proposed resolution
The problem is that image derivatives use the recursive feature of \Drupal\Core\File\FileSystem::mkdir() so while #3036494: Race condition in ImageStyle::createDerivative() fixed the race when creating the last directory in the path ie 2016-05 - it doesn't for any of the others.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#15 | 3211936-15.patch | 3.24 KB | alexpott |
#15 | 12-15-interdiff.txt | 826 bytes | alexpott |
#12 | 3211936-12.patch | 3.24 KB | alexpott |
#12 | 8-12-interdiff.txt | 1.34 KB | alexpott |
Comments
Comment #2
alexpottComment #3
alexpottHere's a test that proves that finally we have this race condition fixed! Yay.
Comment #4
alexpottHmmmm.... I don't think
pcntl_fork()
is available on our CI.... the test failed reliably without the fix for me.Comment #5
alexpottHmmmm.... nope PHP is compiled with
--enable-pcntl
see https://git.drupalcode.org/project/drupalci_environments/-/blob/producti... and the test in #4 is not going to fail. Maybe DrupalCI is just too quick to cause this to happen. The test in #3 reliably fails for me.Comment #6
alexpottLet's see if waiting a bit and all starting at the same time gets us a fail.
Comment #7
alexpottLet's do this a little bit more elegantly with less looping.
Comment #8
alexpottAnd now let's add the fix back in...
Comment #11
daffie CreditAttribution: daffie commentedPatch looks good:
The variable $i is not used and can be removed.
The variable $succes is not necessary and can be removed or should the if-statement be
!$success || !file_exists($recursive_path)
.Can these be replaced with
usleep(100000)
?Comment #12
alexpottThanks for the review @daffie
#11.1 Fixed
#11.2 This is correct. If $success is TRUE then we will not bother evaluating
file_exists($recursive_path)
and therefore save I/O.#11.3 No. This is necessary to ensure that the race condition occurs. Looping and forking takes time that we have to account for. And is documented.
Comment #13
daffie CreditAttribution: daffie commented@alexpott: Thank you for the explanations.
There is a fix and testing for the fix.
The test fails on my local machine when I remove the fix.
All code changes look good to me.
For me it is RTBC.
Comment #14
catchShould this be 'can result'?
One the one hand it's great we can test this, on the other I'm a bit concerned about test stability (and maintainability) with this one. But seems worth a go.
Comment #15
alexpottThanks for the review @catch.
Fixed #14.1
Re #14.2 - in some ways this test is a good thing if we to move Drupal to a place where we support event-loop PHP frameworks like react-php. It'll keep us a bit honest about what happens in destructors. I think the benefits of have test coverage here outweigh maintainability issues:
Comment #19
catchCommitted/pushed to 9.3.x and cherry-picked back to 9.1.x
This can probably go into 8.9.x but the test failed, so asking for a re-run.
Comment #20
larowlanClosing as 8.9.x is now in security-only mode