¿Apache lee los archivos de locking antes de servirlos?

Tengo una aplicación móvil que lee un archivo JSON que está almacenado en un servidor Apache. El contenido de ese archivo JSON se regenera (utilizando un script PHP) si se cambia algo a través de una GUI.

Me preocupa que el hecho de intentar sobrescribir el archivo JSON en medio de la publicación de Apache pueda causar problemas.

¿Apache obtiene un locking de lectura antes de servir archivos? Si no, ¿qué pasará si trato de escribirlo al mismo tiempo que se sirve?

No. En los sistemas compatibles con POSIX, todos los lockings son de todos modos avisos, por lo que incluso si apache obtendría un locking de lectura, el otro proceso podría simplemente escribir el archivo.

Usted puede determinar que con 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 

Por lo tanto, puede suceder que su archivo JSON esté solo parcialmente escrito. Para evitar este problema, escriba su archivo JSON en un archivo temporal en el mismo sistema de archivos y use el rename de rename atómico para sobrescribir el archivo.

De esa manera, si la open ha tenido éxito, apache continuará sirviendo el archivo anterior. Si el rename finaliza antes de la open , apache obtendrá el nuevo archivo completado.

Si se preocupa por la coherencia (en el caso de un fallo de alimentación o algo así), también puede llamar a fsync en la aplicación que escribe el archivo JSON antes de cerrarlo.

Estás pensando en el paradigma equivocado para las plataformas * nix. Lo que quiere son escrituras atómicas en el archivo JSON en su script. Para ello, escriba el archivo en un nombre de archivo temporal único en el directorio de destino y luego use rename() para mover este archivo sobre el anterior. La operación de mover archivos es atómica. Los procesos asíncronos abrirán el archivo JSON anterior o el nuevo pero no un híbrido.

Hay varias formas de construir un nombre de archivo temporal. Consulte la documentación de PHP sobre los comentarios de los usuarios sobre tempnam() . Mi sistema genera una ID única de solicitud, así que solo uso $_SERVER["UNIQUE_ID"] como base.