Как справиться с условиями гонки файлового сервера? - PullRequest
0 голосов
/ 06 ноября 2018

Я занимаюсь разработкой приложения, которое опрашивает папку на сетевом файловом сервере (cifs) для новых файлов в запланированном задании cron каждую минуту.

Когда он видит новый файл, он временно копирует его в локальную файловую систему, а затем выполняет различные действия с файлом, а затем удаляет его как из локальной, так и из сетевой файловой системы.

У меня есть опасения по поводу возможности возникновения состояния гонки, когда мое приложение опрашивает сетевую папку, в то время как кто-то добавляет файл в сетевую папку. Файлы невероятно малы (1 КБ), поэтому очень редко нужно, чтобы файл копировался при опросе папки, но это могло произойти.

Мой вопрос, это законное беспокойство, и если да, то как мне справиться с этим?

1 Ответ

0 голосов
/ 23 ноября 2018

Вот как я решил свои проблемы.

Обратите внимание, что у меня была эта проблема в нескольких областях моего рабочего процесса. во-первых, мне нужно было отслеживать новые файлы в каталоге с моим приложением и следить за тем, чтобы они были завершены, и т. д. во-вторых, мне приходилось загружать файлы в каталог, за которым следит другая программа, а) у меня нет контроль, и б) очень архаичен и не выполняет никакой проверки.

Для решения первой задачи:

В моем запланированном задании я просканировал каталог на наличие всех файлов, затем сгенерировал хэш md5 для каждого файла и сохранил его в таблице в базе данных вместе с путем к файлу.

В следующий раз, когда мое запланированное задание будет выполнено (через 1 минуту), я извлекаю все строки из базы данных (путь к файлу и хэш), проверяю, существует ли файл, и затем снова генерирую хеш md5. Если файл существует и хэш-код совпадает, я выполняю обработку файла (и удаляю его из каталога). В случае сбоя одного из этих двух файлов я просто перехожу к следующему файлу в цикле.

После того, как все файлы обработаны, я обрезаю таблицу, которая проиндексировала файлы, и затем переиндексирую все файлы, снова сохраняя их в базе данных. Минуту спустя моя работа начинается снова, потребляя файлы из индекса.

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

Для решения второй задачи:

Чтобы гарантировать, что другая часть программного обеспечения не будет использовать файл, который мог находиться в процессе загрузки, я просто создал на сервере другой каталог, который программа не отслеживала, и загрузил туда файлы. Когда передача файлов была завершена, я выполнил команду перемещения, чтобы переместить файлы в отслеживаемый каталог, и, поскольку перемещение - это атомарная операция в файловой системе, поэтому оно безопасно от состояния гонки.

...