atexit для безопасного завершения Python-приложенийКогда вы работаете с сетевыми приложениями, важно не просто обрабатывать данные, но и корректно завершать работу сервера: сохранять остатки в памяти, закрывать соединения, выгружать данные.
✳️ Для этого у Python есть скрытая суперсила — модуль
atexit. Он позволяет регистрировать функции, которые автоматически выполняются при нормальном завершении Python-программы.Это полезно, если нужно:
— Сохранить кэш
— Очистить ресурсы
— Завершить фоновые потоки
— Записать метрики или логи
✳️Но:
atexit не срабатывает при аварийном завершении (например, os._exit() или падении интерпретатора). Для этого используйте signal.⏩️ Мини-проект: клиент-сервер +
atexitСервер:
— Получает UDP-пакеты с метриками от клиента
— Сохраняет данные в in-memory SQLite
— Использует
queue.Queue и фоновый daemon-поток для обработки данных— При завершении работы сохраняет все необработанные данные из очереди с помощью
atexitКод:
import atexit
def shutdown_handler():
# Извлекаем всё из очереди
while not ingest_queue.empty():
buffer.append(ingest_queue.get())
# Сохраняем в БД
_persist_data(buffer, conn)
atexit.register(shutdown_handler)
Клиент:
— Отправляет случайные данные (температура, влажность, sensor\_id)
— Работает в бесконечном цикле
— Завершается по
Ctrl+CКод:
while True:
data = {
"sensor_id": ...,
"temperature": ...,
...
}
client_socket.sendto(json.dumps(data).encode(), addr)
time.sleep(0.01)
⏩️ Почему это важно
В продакшн-сервисах вы не хотите терять данные, если:
— Процесс завершился вручную
— Контейнер Docker останавливается
— Система инициирует shutdown
⏩️ Выводы
— Используйте
atexit для мягкой очистки: логов, файлов, очередей, соединений— Комбинируйте с
signal, если важно обрабатывать SIGINT, SIGTERM— Даже небольшие скрипты выигрывают от аккуратного завершения
Библиотека питониста #буст
