Pour garder une trace et tenter de trouver une parade à un bug qu'on a chez Infini avec bigup. Le contexte, les fichiers des sites qu'on y héberge sont stockés sur un NFS (disque réseau) accessible depuis nos différentes VMs qui portent apache. Certainement à cause de la latence engendrée par le NFS, l'upload avec bigup échoue X fois sur Y, en renvoyant une erreur "Indiquez un fichier !".
Après pas mal d'échanges avec @maieul qui nous a remonté le bug, et suite à différents tests, j'ai trouvé ce qui semble être l'origine du problème dans la méthode trouver_fichiers() de la classe CacheRepertoire ici :
ajouter un clearstatcache() sur le répertoire avant le test, car comme indiqué dans https://www.php.net/manual/en/function.is-dir.php "The results of this function are cached. See clearstatcache() for more details." => sans succès
Pour l'instant, la seule parade qui fonctionne est d'ajouter un sleep(1) (ou autre valeur) avant le test sur is_dir(), mais ça n'est pas viable...
Complément d'info : j'ai testé et confirmé le bug sur nos VMs PHP 7.2 et 7.4, avec SPIP 4.0, 4.1 et 3.2 plus bigup.
Pour garder une trace et tenter de trouver une parade à un bug qu'on a chez Infini avec bigup. Le contexte, les fichiers des sites qu'on y héberge sont stockés sur un NFS (disque réseau) accessible depuis nos différentes VMs qui portent apache. Certainement à cause de la latence engendrée par le NFS, l'upload avec bigup échoue X fois sur Y, en renvoyant une erreur "Indiquez un fichier !".
Après pas mal d'échanges avec @maieul qui nous a remonté le bug, et suite à différents tests, j'ai trouvé ce qui semble être l'origine du problème dans la méthode `trouver_fichiers()` de la classe `CacheRepertoire` ici :
https://git.spip.net/spip/bigup/src/commit/482bc07f98189f8a5892b220a1e1711dccba08f6/inc/Bigup/CacheRepertoire.php#L83
Le test sur `!is_dir($directory)` renvoie parfois false, et génère le bug en question.
J'ai tenté pas mal de choses, comme :
- ajouter un `opendir()/closedir()` avant le test cf https://stackoverflow.com/questions/41723458/php-file-exists-or-is-file-does-not-answer-correctly-for-10-20s-on-nfs-files-ec => sans succès
- ajouter un `clearstatcache()` sur le répertoire avant le test, car comme indiqué dans https://www.php.net/manual/en/function.is-dir.php "The results of this function are cached. See clearstatcache() for more details." => sans succès
Pour l'instant, la seule parade qui fonctionne est d'ajouter un `sleep(1)` (ou autre valeur) avant le test sur `is_dir()`, mais ça n'est pas viable...
Pour info, j'ai trouvé mention de ce type de bug chez nextcloud https://github.com/nextcloud/server/issues/7124 qui pour contourner un problème similaire avec `is_writable()` sur NFS applique le patch suivant https://github.com/nextcloud/server/pull/13237
Complément d'info : j'ai testé et confirmé le bug sur nos VMs PHP 7.2 et 7.4, avec SPIP 4.0, 4.1 et 3.2 plus bigup.
Je dit sans doute une betise, mais ne pourrait-on pas se passer de ce test is_dir et faire un try/catch sur RecursiveDirectoryIterator ? ca se trouve lui n'est pas soumis au cache ?
Je dit sans doute une betise, mais ne pourrait-on pas se passer de ce test `is_dir` et faire un try/catch sur `RecursiveDirectoryIterator` ? ca se trouve lui n'est pas soumis au cache ?
et en testant le fichier "$directory/.ok" plutot que le is_dir() ?
Pas certain que ça changerait quelque chose car cette fonction a le même problème que is_disr() cf https://www.php.net/manual/en/function.file-exists.php ; j'ai tout de même testé avec if (!file_exists("$directory/.ok")) { au lieu de if (!is_dir($directory)) { et ça ne règle pas le problème.
Mais je ne crois pas que le problème vienne du statcache, c'est un pb de latence disque avant tout, et de ce que j'en ai lu les fonctions is_file, is_dir, is_writable etc "n'aiment pas ça". Ça m'étonne tout de même, car on a déjà des tests de ce type dans sous_repertoire() et je n'ai jamais observé de problème similaires jusqu'ici chez Infini.
> et en testant le fichier `"$directory/.ok"` plutot que le `is_dir()` ?
Pas certain que ça changerait quelque chose car cette fonction a le même problème que `is_disr()` cf https://www.php.net/manual/en/function.file-exists.php ; j'ai tout de même testé avec `if (!file_exists("$directory/.ok")) {` au lieu de `if (!is_dir($directory)) {` et ça ne règle pas le problème.
Mais je ne crois pas que le problème vienne du statcache, c'est un pb de latence disque avant tout, et de ce que j'en ai lu les fonctions is_file, is_dir, is_writable etc "n'aiment pas ça". Ça m'étonne tout de même, car on a déjà des tests de ce type dans `sous_repertoire()` et je n'ai jamais observé de problème similaires jusqu'ici chez Infini.
Pour garder une trace et tenter de trouver une parade à un bug qu'on a chez Infini avec bigup. Le contexte, les fichiers des sites qu'on y héberge sont stockés sur un NFS (disque réseau) accessible depuis nos différentes VMs qui portent apache. Certainement à cause de la latence engendrée par le NFS, l'upload avec bigup échoue X fois sur Y, en renvoyant une erreur "Indiquez un fichier !".
Après pas mal d'échanges avec @maieul qui nous a remonté le bug, et suite à différents tests, j'ai trouvé ce qui semble être l'origine du problème dans la méthode
trouver_fichiers()
de la classeCacheRepertoire
ici :482bc07f98/inc/Bigup/CacheRepertoire.php (L83)
Le test sur
!is_dir($directory)
renvoie parfois false, et génère le bug en question.J'ai tenté pas mal de choses, comme :
opendir()/closedir()
avant le test cf https://stackoverflow.com/questions/41723458/php-file-exists-or-is-file-does-not-answer-correctly-for-10-20s-on-nfs-files-ec => sans succèsclearstatcache()
sur le répertoire avant le test, car comme indiqué dans https://www.php.net/manual/en/function.is-dir.php "The results of this function are cached. See clearstatcache() for more details." => sans succèsPour l'instant, la seule parade qui fonctionne est d'ajouter un
sleep(1)
(ou autre valeur) avant le test suris_dir()
, mais ça n'est pas viable...Pour info, j'ai trouvé mention de ce type de bug chez nextcloud https://github.com/nextcloud/server/issues/7124 qui pour contourner un problème similaire avec
is_writable()
sur NFS applique le patch suivant https://github.com/nextcloud/server/pull/13237Complément d'info : j'ai testé et confirmé le bug sur nos VMs PHP 7.2 et 7.4, avec SPIP 4.0, 4.1 et 3.2 plus bigup.
Je dit sans doute une betise, mais ne pourrait-on pas se passer de ce test
is_dir
et faire un try/catch surRecursiveDirectoryIterator
? ca se trouve lui n'est pas soumis au cache ?et en testant le fichier
"$directory/.ok"
plutot que leis_dir()
?Apparement RecursiveDirectoryIterator serait aussi soumis au cache. On me signale des bug du type de la capture d'écran
Pas certain que ça changerait quelque chose car cette fonction a le même problème que
is_disr()
cf https://www.php.net/manual/en/function.file-exists.php ; j'ai tout de même testé avecif (!file_exists("$directory/.ok")) {
au lieu deif (!is_dir($directory)) {
et ça ne règle pas le problème.Mais je ne crois pas que le problème vienne du statcache, c'est un pb de latence disque avant tout, et de ce que j'en ai lu les fonctions is_file, is_dir, is_writable etc "n'aiment pas ça". Ça m'étonne tout de même, car on a déjà des tests de ce type dans
sous_repertoire()
et je n'ai jamais observé de problème similaires jusqu'ici chez Infini.une relance sur ce sujet ? c'est vraiment très problématique comme bug...