Apache lit-il les fichiers avant de les servir?

J’ai une application mobile qui lit un fichier JSON stocké sur un serveur Apache. Le contenu de ce fichier JSON est régénéré (en utilisant un script PHP) si quelque chose est modifié via une interface graphique.

Je crains que le fait d’essayer de remplacer le fichier JSON en cours d’exécution par Apache puisse causer des problèmes.

Apache obtient-il un verrou de lecture avant de servir des fichiers? Si non, que se passera-t-il si j’essaie de l’écrire en même temps qu’il est servi?

Non. Sur les systèmes compatibles POSIX, tous les lockings sont de toute

Vous pouvez déterminer cela avec strace :

 [pid 7246] open("/var/www/file.json", O_RDONLY|O_CLOEXEC) = 11 [pid 7246] fcntl(11, F_GETFD) = 0x1 (flags FD_CLOEXEC) [pid 7246] mmap(NULL, 20, PROT_READ, MAP_SHARED, 11, 0) = 0x7f53f93da000 [pid 7246] munmap(0x7f53f93da000, 20) = 0 [pid 7246] writev(10, [{"HTTP/1.1 200 OK\r\nDate: Thu, 26 J"}, ...) = 365 [pid 7246] close(11) = 0 

Par conséquent, il peut arriver que votre fichier JSON ne soit que partiellement écrit. Pour éviter ce problème, écrivez votre fichier JSON dans un fichier temporaire sur le même système de fichiers et utilisez le rename atomique pour remplacer le fichier.

De cette façon, si l’ open a réussi, apache continuera à servir l’ancien fichier. Si le rename termine avant l’ open , apache recevra le nouveau fichier complété.

Si vous vous souciez de la cohérence (en cas de panne de courant), vous pouvez également appeler fsync dans l’application qui écrit le fichier JSON avant de le fermer.

Vous pensez au paradigme erroné pour les plates-formes * nix. Ce que vous voulez, ce sont des écritures de fichiers atomiques dans le fichier JSON de votre script. Vous faites cela en écrivant le fichier sur un nom de fichier temporaire unique dans le répertoire cible, puis en utilisant rename() pour déplacer ce fichier sur l’ancien. L’opération de déplacement de fichier est atomique. Les processus asynchrones ouvriront l’ancien fichier JSON ou le nouveau, mais pas l’hybride.

Il existe différentes manières de créer un nom de fichier temporaire. Voir les commentaires de l’utilisateur sur la documentation PHP sur tempnam() . Mon système génère un identifiant unique de requête, donc j’utilise simplement $_SERVER["UNIQUE_ID"] comme base.