Многие из моих представлений Django нуждаются в ручке.Создание этого дескриптора и операции над ним являются асинхронными.Я также хочу использовать оператор with для автоматического закрытия дескриптора.
Я не уверен, где поставить мост между асинхронным и синхронным кодом.
Что у меня есть
Я реализовал opened()
метод, который работает как менеджер контекста :
@contextmanager
async def opened(self):
handle = await library.open_asynchronnously()
try:
yield handle
finally:
await library.close_asynchronously(handle)
В представлении Я хочу использовать его следующим образом
def server_detail(request,server):
with Server.opened(server) as server_handle:
result = do(asynchronous_call(server_handle))
return result
Я также использую метод do()
для запуска асинхронного кода внутри синхронного :
def do(coroutine):
event_loop = asyncio.new_event_loop()
asyncio.set_event_loop(event_loop)
result = event_loop.run_until_complete(coroutine)
asyncio.get_event_loop().close()
return result
Проблема
«Проблема» заключается в том, чтоЯ не могу поместить with... as
в do()
.
Я думал об использовании async with
(я использую Python 3.6), но на самом деле у меня не может быть этого утверждения внутри синхронного метода и afaikПредставления Джанго должны быть синхронными.
Решения, которые я могу придумать
- Сделать диспетчер контекста
opened()
синхронным и обернуть каждый асинхронный вызов в нем с помощью do ().Затем выведите синхронный управляемый дескриптор.Недостаток: закрытие дескриптора заблокировало бы остальную часть кода.Хотя мне все равно приходится ждать открытия (-> асинхронность не быстрее), от закрытия ничего не зависит, и асинхронность будет быстрее. - Создайте асинхронный метод для каждого представления и позвольте каждому синхронному представлению Djano запускать этоасинхронный метод, который содержит всю логику.Затем я мог бы использовать
with async....as
в этом асинхронном методе.Недостаток: массовое дублирование кода.
Вопрос
Как лучше всего справиться с этим?Django работает синхронно, но мои удаленные вызовы асинхронны?Где я должен построить мост?
Примечания
Я хочу использовать with...as
, чтобы иметь RAII.Только представления должны открывать дескрипторы, и они также должны быть закрыты в их контексте.Если этот подход ошибочен, я открыт для улучшений.