Pregunta

He siguiente problema. Quiero crear un almacenamiento de sesión basada en sistema de archivos donde los datos de cada sesión se almacena en archivos simple llamada con ID de sesión.

Quiero siguientes API: write(sid,data,timeout), read(sid,data,timeout), remove(sid) donde sid == nombre de archivo, también quiero tener algún tipo de GC que pueden eliminar todas las sesiones de tiempo de espera superado.

tarea relativamente fácil de si se trabaja con un solo proceso, pero absolutamente no es trivial cuando se trabaja con múltiples procesos o incluso a través de NFS.

La solución más simple pensé fue:

write/read:
   fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
   fcntl_lock_file(fd)
   save data to fd/read data from fd
   fcntl_unlock_file(fd)
   close(fd)

GC:
   fd=open(file_name,O_RDWR);
   fcntl_lock_file(fd)
   if(timed_out)
      unlink(file_name)
   fcntl_unlock_file(fd)
   close(fd)

El mayor problema que desvincular archivo funciona en los nombres de archivo y los bloqueos de archivos funciona en el archivo descriptores. Así que lo anterior no quiere trabajar en el siguiente escenario:

GC - open,
write - open
GC - lock, unlink, unlock, close // file still exists because held by write
write - lock, write, unlock, close // file removed

¿Alguien tiene una idea de cómo tal problema puede ser resuelto? ¿Hay trucos que permiten combinar el bloqueo de archivos y presentar remoción o hacer la operación en el archivo atómica?

Notas:

  • No quiero usar la base de datos,
  • busco una solución para Unix
  • solución debe trabajar con el estándar POSIX llama como fcnl, abrir, cerrar, desvincular

Gracias.

clearification el principal problema es que la operación en los archivos (nombres - desvincular) debe hacerse de forma atómica con la operación de descriptores de archivo - Bloqueo:

  • abierta, desvincular - trabajo en archivos
  • fnctl - trabajo en descriptores
¿Fue útil?

Solución

¿No sería este trabajo?

write/read:
   fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
   fcntl_lock_file(fd)
   if stat(file_name).{st_dev, st_ino} != fstat(fd).{st_dev, st_ino}
       unlock, close, retry
   save data to fd/read data from fd
   fcntl_unlock_file(fd)
   close(fd)

Si stat falla con EEXIST (nombre de archivo no existe) o muestra que el archivo actual no es la misma que la que se abrió, la fianza.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top