Вопрос

У меня есть следующая проблема.Я хочу создать хранилище сеансов на основе файловой системы, где данные каждого сеанса хранятся в простом файле с именем и идентификаторами сеанса.

Мне нужен следующий API: write(sid,data,timeout), read(sid,data,timeout), remove(sid) где sid== имя файла, также я хочу иметь какой-то GC, который может удалять все сеансы с истекшим временем ожидания.

Довольно простая задача, если вы работаете с одним процессом, но абсолютно нетривиальная при работе с несколькими процессами или даже через NFS.

Самое простое решение, о котором я подумал, было:

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)

Самая большая проблема, что файл с отключаемым работает с именами файлов и блокировка файла работы на файл дескрипторы.Таким образом, вышесказанное не сработало бы в следующем сценарии:

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

У кого-нибудь есть идея, как можно решить такую проблему?Существуют ли какие-либо хитрости, позволяющие объединить блокировку файла и удаление файла или сделать операцию над файлом атомарной?

Примечания:

  • Я не хочу использовать базу данных,
  • Я ищу решение для Unix
  • Решение должно работать со стандартными вызовами POSIX, такими как fcnl, open, close, unlink

Спасибо.

Очистка основная проблема заключается в том, что операция с файлами (имена -- unlink) должна выполняться атомарно с операцией с файловыми дескрипторами -- locking:

  • открывать, отсоединять - работать с файлами
  • fnctl - работа с дескрипторами
Это было полезно?

Решение

Разве это не сработало бы?

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)

Если stat сбой с EEXIST (имя файла не существует) или показывает, что текущий файл не совпадает с тем, который вы открыли, bail.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top