Как предотвратить сбой рабочих-оружейников при попытке получить доступ к одним и тем же файлам - PullRequest
0 голосов
/ 28 ноября 2018

Мое приложение Flask регистрирует запросы в отдельных файлах json, потому что они довольно большие и просто загромождают обычные текстовые журналы (например, app.logger.info("..")).Он хранит последние n запросов в некоторой папке.

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

logfiles = sorted(glob.glob("*.json"))

while len(logfiles) >= n:
    os.remove(logfiles.pop(0))

Я использую приложение с сервером gunicorn и заметил, что для идентичного запроса оно иногда дает сбой, а иногда и успешно.За сбоем следует информация:

[18935] [INFO] Handling signal: int
[18935] [INFO] Shutting down: Master

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

Я предполагаю, что мне придется заблокировать папку и создать очередь изработники, которые пытаются добавить / удалить файлы в папку?Какой лучший способ пойти по этому поводу?Должен ли я использовать один из доступных модулей, таких как threading или Queue?Будут ли они работать гладко с Flask и gunicorn?Или я должен реализовать свою собственную очередь?

PS: Это дополнительный вопрос к Как регистрировать большие запросы в виде файлов?

1 Ответ

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

Когда среда выполнения Python пытается получить доступ к несуществующему файлу, он выдает исключение.В вашем коде нет способа обработать это исключение, и в результате поток gunicorn выдает сигнал прерывания и вылетает.Самый простой способ справиться с этим - использовать try block для инкапсуляции кода, который пытается получить доступ / удалить файл:

try:
    # Code that tries to access the file
    while len(logfiles) >= n:
        os.remove(logfiles.pop(0))
except:
    # Code that you want to execute after the operation fails 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...