Разделяемые ресурсы между процессами в python и мьютексы

Как проблему разделяемых ресурсов решает uvicorn?

Запускаю:

uvicorn main.py:app --workers=5 --port=8080 --host=0.0.0.0

Внутри app есть мьютекс (threading.Lock() на часть одного из эндпоинтов). Будет ли этот мьютекс корректно работать, когда я запускаюсь из-под uvicorn? Не возникнет ли гонки? Как уберечься от этого? А если заменю threading на multiprocessing ?


Решаемая задача

Есть сервис, для части одного из эндпоинтов нужен мьютекс на 3 запроса (проверить наличие объектов по фильтру (можно редуцировать, но нужно править БД), обновить объект, обновить ещё один объект). Запросы отправляются к сервису, который реализует REST-API над mongoDB. эти 2 запроса должны быть атомарными.


Ответы (1 шт):

Автор решения: eri

threading.Lock работает внутри одного процесса.

multiprocessing.Lock работает в группе процессов если создан в процессе создающем группу.

uvicorn импортирует модуль приложения. Тут есть вариант или сначапла запускает воркеры, а потом импортируе; или сначала импортирует, а потом запускает воркеров. Воркеры запускаются через multiprocessing по умолчанию.

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

Проверил: переимпортируется модуль после старта процесса.

В документации и в коде не нашел хуков - нужно патчить.

→ Ссылка