2

Just started experimenting with asynch which looks really cool. I'm trying to use futures with an asynch coroutine that runs forever but I get this error:

Task exception was never retrieved future: <Task finished coro=<slow_operation() done, defined at ./asynchio-test3.py:5> exception=InvalidStateError("FINISHED: <Future finished result='This is the future!'>",)> 

This is my code which runs as expected if I remove the 3 lines related to futures:

import asyncio @asyncio.coroutine def slow_operation(): yield from asyncio.sleep(1) print ("This is the task!") future.set_result('This is the future!') asyncio.async(slow_operation()) def got_result(future): print(future.result()) loop = asyncio.get_event_loop() future = asyncio.Future() future.add_done_callback(got_result) asyncio.async(slow_operation()) try: loop.run_forever() finally: loop.close() 

2 Answers 2

2

slow_operator is called indefinitely, calling set_result for the same future object multiple times; which is not possbile.

>>> import asyncio >>> future = asyncio.Future() >>> future.set_result('result') >>> future.set_result('result') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python35\lib\asyncio\futures.py", line 329, in set_result raise InvalidStateError('{}: {!r}'.format(self._state, self)) asyncio.futures.InvalidStateError: FINISHED: <Future finished result='result'> 

Create new future for each slow_operator call. For example:

@asyncio.coroutine def slow_operation(future): yield from asyncio.sleep(1) print ("This is the task!") future.set_result('This is the future!') asyncio.async(slow_operation(new_future())) def got_result(future): print(future.result()) def new_future(): future = asyncio.Future() future.add_done_callback(got_result) return future loop = asyncio.get_event_loop() asyncio.async(slow_operation(new_future())) try: loop.run_forever() finally: loop.close() 

BTW, you can use new syntax (async, await) if you're using Python 3.5+:

async def slow_operation(future): await asyncio.sleep(1) print ("This is the task!") future.set_result('This is the future!') asyncio.ensure_future(slow_operation(new_future())) 
Sign up to request clarification or add additional context in comments.

3 Comments

Very cool. Thank you. But now I'm at the stage of asking why do we need futures anyway? Can I call a regular function from a courotine or is that why future.set_result? is needed?
@dpetican, Sorry, I can't answer that. How about post a separate question?
The short answer is: it depends on whether you need the function to be asynchronous.
1

Following @falsetru answer this is a complete program that has 3 asynch coroutines each with their own got_result function. I'm using v3.4 so thats why I don't use the new syntax. As an interesting side effect the output clearly demonstrates the single threaded nature of coroutines. I hope its useful as a template for someone:

import asyncio @asyncio.coroutine def task1(future): yield from asyncio.sleep(1) print ("This is operation#1") future.set_result('This is the result of operation #1!') asyncio.async(task1(new_future(got_result1))) def got_result1(future): print(future.result()) @asyncio.coroutine def task2(future): yield from asyncio.sleep(1) print ("This is operation#2") future.set_result('This is the result of operation #2!') asyncio.async(task2(new_future(got_result2))) def got_result2(future): print(future.result()) @asyncio.coroutine def task3(future): yield from asyncio.sleep(1) print ("This is operation#3") future.set_result('This is the result of operation #3!') asyncio.async(task3(new_future(got_result3))) def got_result3(future): print(future.result()) def new_future(callback): future = asyncio.Future() future.add_done_callback(callback) return future tasks = [task1(new_future(got_result1)), task2(new_future(got_result2)), task3(new_future(got_result3))] loop = asyncio.get_event_loop() for task in tasks: asyncio.async(task) try: loop.run_forever() finally: loop.close() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.