-
Notifications
You must be signed in to change notification settings - Fork 235
Fix database deadlock exception in AssetService::getTypoScript #1945
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
base: development
Are you sure you want to change the base?
Fix database deadlock exception in AssetService::getTypoScript #1945
Conversation
With TYPO3 v13, AssetService calls FrontendInterface::set() four times in AssetService::getTypoScript() for a single AssetService::buildAll() invocation. The cache usage was introduced in e84af96 ("[BUGFIX] Handle new TS-not-set limitation on v13 (FluidTYPO3#1928)"), as TYPO3 v13 no longer fully sets up TypoScript when serving fully-cached pages. The four callers of AssetService::getTypoScript() are: - AssetService::getSettings() - AssetService::writeCachedMergedFileAndReturnTag() - AssetService::getFileIntegrity() - AssetService::generateTagForAssetType() Reducing the number of FrontendInterface::set() calls reduces the amount of database deadlock errors that occur if the Typo3DatabaseBackend is used for the "vhs_main" cache and many concurrent requests hit the same TYPO3 page that contains at least one uncached content element. But it doesn't solve them completely; e.q. They still occur but less frequent. This issue is tracked in the upstream TYPO3 bug tracker as #106593 [1]. A reproduction example is available on GitHub [2]. [1]: https://forge.typo3.org/issues/106593 [2]: https://github.com/adamkoppede/reproduce-deadlock-with-fluidtypo3-vhs-7-1
Since change e84af96 ("[BUGFIX] Handle new TS-not-set limitation on v13 (FluidTYPO3#1928)") the "plugin.tx_vhs" section of the TypoScript setup is written into a cache. This is necessary as TYPO3 v13 PrepareTypoScriptFrontendRendering [1] no longer performs the full TypoScript setup when serving a fully-cached page. An "Setup array has not been initialized" error is thrown when trying to access the uninitialized TypoScript setup. For pages with uncached content, FrontendInterface::set() is called on each request. This leads to database deadlock errors if the Typo3DatabaseBackend is used for the "vhs_main" cache and many concurrent requests hit the same TYPO3 page. This issues is tracked in upstream TYPO3 bug tracker as #106593 [2]. A fully reproduction example is available on GitHub [3]. We don't need to store the TypoScript of those pages with uncached content in the cache, because they cannot be served from cache and thus forcing the full TypoScript setup. [1]: https://github.com/TYPO3/typo3/blob/v13.4.9/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php#L146 [2]: https://forge.typo3.org/issues/106593 [3]: https://github.com/adamkoppede/reproduce-deadlock-with-fluidtypo3-vhs-7-1
c1a42f5
to
57203d8
Compare
Tests pass locally with The current The issue seems to affect the unit tests only. The output for the following seems fine in a TYPO3 v13 instance with all three typo3fluid/fluid 4.1.x versions: <html
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:vhs="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
data-namespace-typo3-fluid="true"
>
<ol>
<li><f:if condition="1 == 1" then="good" else="bad"/></li>
<li><f:if condition="0 == 1" then="bad" else="good"/></li>
<li><vhs:condition.context.isProduction then="good" else="bad"/></li>
<li><vhs:condition.context.isTesting then="bad" else="good"/></li>
<li>
<vhs:condition.iterator.contains haystack="['hello', 'world']" needle="world">
<f:then>good</f:then>
<f:else>bad</f:else>
</vhs:condition.iterator.contains>
</li>
<li>
<vhs:condition.iterator.contains
haystack="['hello', 'world']"
needle="underworld"
>
<f:then>bad</f:then>
<f:else>good</f:else>
</vhs:condition.iterator.contains>
</li>
<li>
<vhs:condition.iterator.contains
haystack="['hello', 'world']"
needle="world"
then="good"
/>
</li>
<li>
<vhs:condition.iterator.contains
haystack="['hello', 'world']"
needle="world"
then="good"
else="bad"
/>
</li>
<li>
<vhs:condition.iterator.contains
haystack="['hello', 'world']"
needle="underworld"
else="good"
/>
</li>
<li>
<vhs:condition.iterator.contains
haystack="['hello', 'world']"
needle="underworld"
then="bad"
else="good"
/>
</li>
</ol>
</html> |
If the database caching backend is used for the "vhs_main" cache, database deadlocks occur if there are many concurrent requests to a page with uncached content. A full reproduction example is available on GitHub: https://github.com/adamkoppede/reproduce-deadlock-with-fluidtypo3-vhs-7-1
The deadlock occurs in the
EXT:core Typo3DatabaseBackend::set() method
. I created an issue in the upstream TYPO3 bug tracker: https://forge.typo3.org/issues/106593Currently
Typo3DatabaseBackend::set()
is called four times per HTTP request. The first commit in this change set extends thestatic::$settingsCache
so it containsplugin.tx_vhs
fully, instead of justplugin.tx_vhs.settings
; this reduces theTypo3DatabaseBackend::set()
calls down to one per request. The second commit removes theTypo3DatabaseBackend::set()
call for pages with uncached content, as they cannot be served from cache.