Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting asyncio.Future's value in a callback from different thread

I have a library that gives me an option to schedule a callback when an external job finishes. Is it safe to use this callback for Future.set_result()? If not, what is the proper way to achieve this? Future's documentation says that its methods are not thread safe, so I assume there might be a problem with this.

My goal is to use OpenCL events from PyOpenCL as awaitable objects in asyncio code. I was thinking about a helper function like this:

def wrap_opencl_event(event):
    f = asyncio.Future()
    event.set_callback(pyopencl.command_execution_status.COMPLETE, lambda x: f.set_result(None))
    return f

and using it this way:

async def do_slow_stuff():
    ev1 = pyopencl.enqueue_something()
    ev2 = pyopencl.enqueue_something_else(wait_for=[ev1])
    await wrap_opencl_event(ev2)
    process_results()
like image 678
cube Avatar asked Feb 04 '23 14:02

cube


1 Answers

After reading the documentation a bit more thoroughly it seems that the future's value should be set in a callback scheduled with the event loop:

def wrap_opencl_event(event):
    loop = asyncio.get_event_loop()
    f = loop.create_future()
    event.set_callback(pyopencl.command_execution_status.COMPLETE,
                       lambda status: loop.call_soon_threadsafe(f.set_result, None))
    return f
like image 63
cube Avatar answered Feb 07 '23 17:02

cube