Как справиться с условиями гонки файлового сервера?

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

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

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

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

1 ответ

Решение

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

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

Чтобы решить первую проблему:

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

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

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

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

Чтобы решить вторую проблему:

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

Другие вопросы по тегам