I want a class function to pause execution till value of a class variable is changed as requested by the function by another thread. I am new to python asyncio module.
asyncio.Future seem to provide a mechanism for waiting for future value hence I tried following on a toy example:
class RandomReader:
    def __init__(self):
        self.loop = asyncio.get_event_loop()
        self.service = 3
        self.thread = threading.Thread(target=self.reader)
        self.thread.start()
        self.futures: Dict[int, asyncio.Future] = {}
    def reader(self):
        asyncio.set_event_loop(self.loop)
        while self.service != 0:
            k, v = read()
            if k in self.futures:
                if self.futures[k].done():
                    continue
                self.futures[k].set_result(v)
                self.service -= 1
    async def wait(self, v: int):
        self.futures[v] = self.loop.create_future()
        a = await self.futures[v]
        logging.debug("value %d received %f", v, a)
        return v, a
The read function above reads random key and values that potentially match with wait.
Calling function makes calls like below 3 times (RandomReader.service)
    t1 = asyncio.create_task(random_reader.wait(3))
    print(await t1)
I expected self.futures[k].set_result(v) to assign value to a in wait function like documentation of Future object, but the await doesn't actually execute. Though status of futures in self.futures does change to "FINISHED".
Any help with this is really appreciated.
Asyncio futures are not thread-safe - nor is any other asyncio API, except where explicitly noted otherwise. To mark a future as done from a different thread, use call_soon_threadsafe:
self.loop.call_soon_threadsafe(self.futures[k].set_result, v)
That call will notify the event loop that something is going on, and will have the event loop set the future's result, immediately noticing it and waking up the awaiting coroutine.
Also note that the call to asyncio.set_event_loop() in reader() does not look correct, since the event loop is in fact not running in reader's thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With