LINUX.ORG.RU

Удаление lockfile при завершении программы python (аналог trap в bash?)

 ,


0

4

TL;DR: Как правильно по-питонячьи реализовать аналог trap или что-то, что будет делать тоже самое для запуска функции при завершении программы вне зависимости от результата, в т. ч. при ошибке?

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

Вопрос: как по-питонячьи этот lockfile удалять при завершении программы вне зависимости от причины завершения (удача/неудача) с учетом того, что программа работает как сервис, т. е. один запуск предполагает длительной взаимодействие с разными файлами - интерактивная программа?

try...except...finallу в скрипте обертке запуска программы? Какой-то хитрый декоратор или хук? Желательно решить это средствами стандартной библиотеки. Поясните для newbie.



Последнее исправление: curbar (всего исправлений: 3)

Ты неправильно это делаешь.

Само наличие файла не должно означать, что процесс запущен, тебе нужно залочить файл через flock(2) или fcntl. Лок автоматически удалится, когда будет закрыт последний fd с этим локом, что случится в том числе если твоя прога сдохнет.

Для пистона нагуглилась библиотечка (https://py-filelock.readthedocs.io/en/latest/), но это всё можно легко сделать руками.

hateyoufeel ★★★★★
()
Ответ на: комментарий от firkax

Опередил.

но это всё можно легко сделать руками.

Не просто можно но и нужно. Тащить библиотеку ради двух строк open+flock это верх глупости.

Там не только open+flock, но и аналог на венде.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

@cobold

Понял, я объяснил мою проблему с учетом решения, которое я вижу, и с некоторыми упрощениями. Поэтому, возможно, ваши варианты могут не подойти.

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

Исходя из этих деталей, подойдет ли этот flock?

curbar
() автор топика
Ответ на: комментарий от curbar

Это не «варианты», это единственный правильный способ использования локфайла. Он подойдёт везде, где тебе нужен локфайл. Реализовывать локфайл через проверку существования и создание - неправильно, так делают только по незнанию.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от FishHook

Лок с файла удалится. Сам файл может и остаться, это не имеет значения. Сходи сам прочитай ссылку, которую ты притащил, лалка! Там именно это и написано.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от curbar

@cobold

Понял, я объяснил мою проблему с учетом решения, которое я вижу, и с некоторыми упрощениями. Поэтому, возможно, ваши варианты могут не подойти.

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

Исходя из этих деталей, подойдет ли этот flock?

А может тебе, ну это, взять базу данных и не мучиться? Но по минимуму, ты можешь просто лочить свой csv на сервере через flock и снимать лок после обработки запроса. Отдельного файла тут не нужно.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Сам файл может и остаться, это не имеет значения.

Имеет. Файл должен остаться т.к. мы не хотим зря дёргать запись на диск бесполезными действиями. Диск вообще может быть в read-only.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Сам файл может и остаться, это не имеет значения.

Имеет. Файл должен остаться т.к. мы не хотим зря дёргать запись на диск бесполезными действиями. Диск вообще может быть в read-only.

На какой диск, дядя? Все чоткие посоны создают свои локфайлы в /run/user/$UID давно уже.

Только ТСу это не нужно, у него уже есть csv на сервере, который можно лочить.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от curbar

Может тогда посмотреть в сторону uwsgi spooler https://smirnov-am.github.io/background-jobs-with-flask/ ? Если конечно в проекте используется uwsgi. Идея в том чтобы при поступлении файла на обработку добавлять в очередь задачу, а обрабатывать задачи единственным воркером, т.е. последовательно. Таким образом параллельного доступа к файлу не будет.

Ну и ещё есть вариант с https://uwsgi-docs.readthedocs.io/en/latest/PythonDecorators.html#uwsgidecorators.lock

cobold ★★★★★
()
Последнее исправление: cobold (всего исправлений: 1)