How to wrap custom future to use with asyncio in Python?

这一生的挚爱 提交于 2019-12-10 11:11:00

问题


There is a lot of libraries that use their custom version of Future. kafka and s3transfer are just two examples: all their custom future-like classes have object as the superclass.

Not surprisingly, you cannot directly call asyncio.wrap_future() on such objects and can't use await with them.

What is the proper way of wrapping such futures for use with asyncio?


回答1:


If the future class supports standard future features such as done callbacks and the result method, just use something like this:

def wrap_future(f):
    loop = asyncio.get_event_loop()
    aio_future = loop.create_future()
    def on_done(*_):
        try:
            result = f.result()
        except Exception as e:
            loop.call_soon_threadsafe(aio_future.set_exception, e)
        else:
            loop.call_soon_threadsafe(aio_future.set_result, result)
    f.add_done_callback(on_done)
    return aio_future

Consider that code a template which you can customize to match the specifics of the future you are dealing with.

Intended usage is to call it from the thread that runs the asyncio event loop:

value = await wrap_future(some_foreign_future)

If you are calling it from a different thread, be sure to pass loop explicitly because asyncio.get_event_loop will fail when invoked from a thread not registered with asyncio.



来源:https://stackoverflow.com/questions/49350346/how-to-wrap-custom-future-to-use-with-asyncio-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!