pradosoft / prado

Prado - Component Framework for PHP
Other
186 stars 70 forks source link

TCache_Lite error #911

Closed majuca closed 1 year ago

majuca commented 1 year ago

Hi,

In one of ou application, each 5 minutes, we receive a lot of request from from differents servers. The number of request is growing and now I have a lot of time the folloming error:

NOTICE: PHP message: ValueError: fread(): Argument #2 ($length) must be greater than 0 in /var/www/html/vendor/pradosoft/prado/framework/I18N/core/TCache_Lite.php:486
Stack trace:
#0 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/TCache_Lite.php(486): fread(Resource id #10, -32)
#1 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/TCache_Lite.php(544): Prado\I18N\core\TCache_Lite->_read()
#2 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/TCache_Lite.php(331): Prado\I18N\core\TCache_Lite->_writeAndControl('a:5022:{s:7:"Ad...')
#3 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/MessageCache.php(152): Prado\I18N\core\TCache_Lite->save('a:5022:{s:7:"Ad...', 'messages.fr:fr', 'messages.fr:Pra...')
#4 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/MessageSource.php(203): Prado\I18N\core\MessageCache->save(Array, 'messages.fr', 'fr')
#5 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/MessageFormat.php(132): Prado\I18N\core\MessageSource->load('messages')
#6 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/MessageFormat.php(181): Prado\I18N\core\MessageFormat->loadCatalogue('messages')
#7 /var/www/html/vendor/pradosoft/prado/framework/I18N/core/MessageFormat.php(160): Prado\I18N\core\MessageFormat->formatString('Websocket', Array, 'messages')
#8 /var/www/html/vendor/pradosoft/prado/framework/Prado.php(740): Prado\I18N\core\MessageFormat->format('Websocket', Array, 'messages', 'UTF-8')
#9 /var/www/html/protected/modeles/MSysMonitoring.php(529): Prado\Prado::localize('Websocket')

Do you have an idee of this problem?

Maybe we should protect by checking if length is greater than 0.

ctrlaltca commented 1 year ago

Has Prado the permissions to write that file? Looks like it's trying to write a 32 byte hash and to read it back, but the file looks empty (size = 0).

majuca commented 1 year ago

Yes I have the write permissions. I will do some test and come back...

majuca commented 1 year ago

Ok, this problem exists from a long time but it was never a problem for us until now. We are working with docker and some weeks ago, we switch to PHP 8.0 and to an alpine docker instead of a ubuntu docker. I don't know if it is php8 (probably yes, more faster) or the alpine docker but this bug was realy a problem after these changes.

Indeed, we have a lot of request comming at the same time and the problem is an none thread safe of the _write function in the TCache_Lite classe. When the function open the file by @fopen($this->_file, "wb"), the file is empty but it is still not blocked at this point. So if a other thread is calling filesize($this->_file) at the same time (_read function), the length is 0.

According to the php documentation, in the _write function, the file must be opend like this @fopen($this->_file, "cb"), blocked and only after that truncate.

I send pull request.

ctrlaltca commented 1 year ago

Merged, than you for the nice explanation!