Closed lkppo closed 12 months ago
Any clue? The writeFile
method (the one triggering the error) hasn't been changed.
A reproduction scenario would help. Does the error not occur with Smarty v4.3?
Right. I just tested with 4.3 and found the same error. How to help?
I have something more in logs. An access error on renaming (with v4.3):
[2023-08-31T00:30:52+02:00] PHP Warning: rename(C:\devel\www\wkxlocal\cache\templates\default\compile\wrt64efc31c2f0678_24005802,C:\devel\www\wkxlocal\cache\templates\default\compile\98311c0ceca995f0db9f4ad41b2dcfa2b27b16c2_0.file.display.tpl.php): Accès refusé (code: 5) in C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Smarty.php on line 1818
[2023-08-31T00:30:52+02:00] #1 rename called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Smarty.php:1818]
[2023-08-31T00:30:52+02:00] #2 Smarty\Smarty->writeFile called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:232]
[2023-08-31T00:30:52+02:00] #3 Smarty\Template\Compiled->write called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:195]
[2023-08-31T00:30:52+02:00] #4 Smarty\Template\Compiled->compileAndWrite called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:148]
[2023-08-31T00:30:52+02:00] #5 Smarty\Template\Compiled->compileAndLoad called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:108]
[2023-08-31T00:30:52+02:00] #6 Smarty\Template\Compiled->render called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:184]
[2023-08-31T00:30:52+02:00] #7 Smarty\Template->render called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:639]
[2023-08-31T00:30:52+02:00] #8 Smarty\Template->_execute called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:576]
[2023-08-31T00:30:52+02:00] #9 Smarty\Template->display called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Smarty.php:2243]
[2023-08-31T00:30:52+02:00] #10 Smarty\Smarty->display called at [C:\devel\www\wkxlocal\core\libs\CLOSE.php:241]
[2023-08-31T00:30:52+02:00] #11 CLOSE->__construct called at [C:\devel\www\wkxlocal\core\libs\CLOSE.php:367]
[2023-08-31T00:30:52+02:00] #12 CLOSEPOPUP->__construct called at [C:\devel\www\wkxlocal\core\startup\FACTORY.php:608]
[2023-08-31T00:30:52+02:00] #13 FACTORY_CLOSEPOPUP::getInstance called at [C:\devel\www\wkxlocal\public\tinymce\plugins\wkxcharmap\dialog_column_right.php:105]
[2023-08-31T00:30:52+02:00]
An other example after cleaning the compile directory by hand (with v4.3):
[2023-08-31T00:48:28+02:00] PHP Warning: rename(C:\devel\www\wkxlocal\cache\templates\default\compile\wrt64efc73bef1716_94705877,C:\devel\www\wkxlocal\cache\templates\default\compile\e8aa5c4d14c9bcd5d59a3c94eb62fdd56be81fe7_0.file.content.tpl.php): Accès refusé (code: 5) in C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Smarty.php on line 1818
[2023-08-31T00:48:28+02:00] #1 rename called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Smarty.php:1818]
[2023-08-31T00:48:28+02:00] #2 Smarty\Smarty->writeFile called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:232]
[2023-08-31T00:48:28+02:00] #3 Smarty\Template\Compiled->write called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:195]
[2023-08-31T00:48:28+02:00] #4 Smarty\Template\Compiled->compileAndWrite called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:148]
[2023-08-31T00:48:28+02:00] #5 Smarty\Template\Compiled->compileAndLoad called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:108]
[2023-08-31T00:48:28+02:00] #6 Smarty\Template\Compiled->render called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:184]
[2023-08-31T00:48:28+02:00] #7 Smarty\Template->render called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:289]
[2023-08-31T00:48:28+02:00] #8 Smarty\Template->renderSubTemplate called at [C:\devel\www\wkxlocal\cache\templates\default\compile\98311c0ceca995f0db9f4ad41b2dcfa2b27b16c2_0.file.display.tpl.php:81]
[2023-08-31T00:48:28+02:00] #9 content_64efc73bd4d1c4_85818131 called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\GeneratedPhpFile.php:110]
[2023-08-31T00:48:28+02:00] #10 Smarty\Template\GeneratedPhpFile->getRenderedTemplateCode called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template\Compiled.php:115]
[2023-08-31T00:48:28+02:00] #11 Smarty\Template\Compiled->render called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:184]
[2023-08-31T00:48:28+02:00] #12 Smarty\Template->render called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:639]
[2023-08-31T00:48:28+02:00] #13 Smarty\Template->_execute called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Template.php:576]
[2023-08-31T00:48:28+02:00] #14 Smarty\Template->display called at [C:\devel\www\wkxlocal\core\libs\vendor\smarty\smarty\smarty\src\Smarty.php:2252]
[2023-08-31T00:48:28+02:00] #15 Smarty\Smarty->display called at [C:\devel\www\wkxlocal\core\libs\CLOSE.php:241]
[2023-08-31T00:48:28+02:00] #16 CLOSE->__construct called at [C:\devel\www\wkxlocal\core\libs\CLOSE.php:367]
[2023-08-31T00:48:28+02:00] #17 CLOSEPOPUP->__construct called at [C:\devel\www\wkxlocal\core\startup\FACTORY.php:608]
[2023-08-31T00:48:28+02:00] #18 FACTORY_CLOSEPOPUP::getInstance called at [C:\devel\www\wkxlocal\public\tinymce\plugins\wkxcharmap\dialog_column_left.php:82]
[2023-08-31T00:48:28+02:00]
What are the steps you take that trigger the error?
WIKINDX use globals to collect variables to render. Smarty is called only at the end for rendering by the CLOSE::_construct() function. Smarty's behavior is configured just before rendering by TEMPLATE::loadTemplate().
There are only two differences from the common case where the error is not triggered:
Maybe I'm doing something incompatible during configuration, calling functions in the wrong order, or there's an error in the template?
Do you need any other information?
$smarty->display()
?This happens whenever $smarty->display()
is called, Force compile is enabled, and the menu is hidden. In a context where the menu is displayed there is no error.
I'm preparing a minimal example for tomorrow.
A minimal example is attached.
You need to call many time the index.php page from this archive with a browser to trigger the error.
The error occurs less often because I removed a lot of code.
My understanding of the error is this: as index.php uses an HTML frame to call two pages that are rendered separately but at the same time when Force Compile is enabled the destruction of the templates can cause a race condition when the compiled templates are recreated.
Yes, that seems reasonable. And I'm not sure this can be fixed easily.
This is one the reasons why you would not want to use force compile in production.
We don't use it in production fortunately. Forgetting to disable it during development is the only annoyance. So I no longer see any reason to worry about this problem either.
I'm just wondering why this strategy of writing to a temporary file then renaming it to write it directly to the file?
Interestingly, I believe this was introduced to prevent a race condition where two processes would write to the same file... 🤪
Concurrency is hard... It would have been better to write directly and if that fails to set a pause of a few microseconds then try again once.
I am making a proposal since this seems like an opportunity. I wrote an SQLite storage backend of the cached and compiled pages. This was to test feasibility and performance. It seemed more efficient to me than writing directly to files. Is this a good replacement option or a contribution you would accept? And if you accept it, I undertake to maintain this code.
SQLite stores the whole database as a single file and locks the database file during writing.
Thus, I doubt it would be more efficient than writing to (separate) files directly.
I noticed during the test that the same page was displayed twice as fast.
But it's true that it wasn't a server facing the internet.
Hello,
We have been testing Smarty 5.0.0-rc1 with PHP 8.2 for a few months and have noticed on both Mac and Windows that if the Force Compile option is activated, errors occur when writing compiled files.
Fatal error: Uncaught --> Smarty: unable to write file C:\devel\www\wikindx\cache\templates\default\compile\1d93a5418ebba31bc468f3d375f30b3aab8d0444_0.file_content.tpl.php <-- thrown in C:\devel\www\wikindx\core\libs\vendor\smarty\smarty\smarty\src\Smarty.php on line 1738
Regards,