Я работаю над REST API для веб-службы, используя Pyramid и Cornice; данные на стороне сервера обрабатываются с помощью SQLAlchemy и MySQL. Веб-сервер nginx, используя uwsgi, и он настроен для запуска нескольких процессов Python:
[uwsgi]
socket = localhost:6542
plugins = python34
...
processes = 2 # spawn the specified number of workers/processes
threads = 2 # run each worker in prethreaded mode with the specified number of threads
Проблема
Предположим, что таблица customers
на стороне сервера. Используя API, вы можете читать данные клиента, изменять его или удалять. Кроме того, существуют другие функции API, которые считывают данные клиента.
Я могу одновременно выпустить несколько вызовов API, которые затем конкурируют за один и тот же ресурс клиента:
# Write/modify the customer {id} data
curl --request POST ... https://some.host/api/customer/{id}
# Delete customer {id} and all of its associated data
curl --request DELETE https://some.host/api/customer/{id}
# Perform some function which reads customer {id}
curl --request GET ... https://some.host/api/do-work
По существу это Проблема читателей-писателей, но поскольку задействовано более одного процесса, традиционная синхронизация потоков с использованием locks/mutexes/semaphores не будет работать здесь.
Вопрос
Я хотел бы понять лучший способ реализовать блокировку и синхронизацию для такого веб-API на основе Pyramid, так что одновременные вызовы, подобные приведенному выше, обрабатываются безопасно и эффективно (т.е. без ненужной сериализации).
Решения (?)
- Я не думаю, что имеет смысл отметить /flag customer
{id}
какlocked
, потому что SQLAlchemy кэширует такие модификации иflush()
в этом контексте не кажется достаточно атомным? - В этой статье описывается использование HTTP ETag для управления общими ресурсами.
- Можно также использовать Redis как распределенная блокировка менеджер для создания спин-блокировки для функции просмотра?
- Как насчет Pyramid диспетчер транзакций?