在同步方法中使用“ with语句”运行异步方法

时间:2018-10-17 13:13:26

标签: python async-await django-views with-statement

我的许多Django视图都需要一个句柄。此句柄的创建和对其的操作是异步的。我还想使用with语句自动关闭句柄。

我不确定在异步和同步代码之间建立桥梁。

我到目前为止所拥有的

我实现了一个List<InnerObject> result = outerObjects.stream() .map(outerObject -> innerObjects.stream() .filter(innerObject -> someBooleanMethod(innerObject, outerObject)) .findFirst() .orElse(null)) .filter(Objects::nonNull) .collect(Collectors.toList()); 方法,该方法用作上下文管理器

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()(我正在使用Python 3.6),但是afaik我无法在同步方法中使用此语句,而afaik Django的视图必须是同步的。

我能想到的解决方案

  • 使async with上下文管理器同步,并使用do()在其中包装每个异步调用。然后产生一个同步的托管句柄​​。缺点:句柄的关闭将阻塞其余代码。虽然我不得不等待打开(->异步并不快),但是没有什么依赖于关闭,异步会更快。
  • 为每个视图创建一个异步方法,并让每个同步Djano视图运行包含所有逻辑的异步方法。然后,我可以在此异步方法中使用opened()。缺点:大量的代码重复。

问题

处理此问题的最佳方法是什么? Django同步工作,但是我的远程调用是异步的吗?我应该在哪里建桥?

注释

我想在视图中使用with async....as来拥有RAII。只有视图应该打开句柄,并且在上下文中也应该关闭它们。如果这种方法有缺陷,我愿意改进。

0 个答案:

没有答案