Using futures
Motivation and usage
The Future class allows storing the result of an operation, either a return value or a
raised exception. It differs from ResultCapture in that you manually specify the result by
calling either Future.set_result() or Future.set_exception() rather than the result
automatically being captured from some async function.
This is often useful when you are implementing an API in a library where requests can be sent to some remote server, but multiple requests can be outstanding at a time so the result is set in some separate async routine:
# Public function in the API: Send the request over some connection
def start_request(request_payload) -> aioresult.ResultBase:
request_id = connection.send_request(request_payload)
result = aioresult.Future()
outstanding_requests[request_id] = result
return result
# Hidden function in the API: In a separate task, wait for responses to any request
async def get_responses():
while True:
request_id, response = await connection.get_next_response()
outstanding_requests[request_id].set_result(response)
del outstanding_requests[request_id]
# Caller code: Use the API and returned Future object
async def make_request():
f = start_request(my_request)
await f.wait_done()
print("result:", f.result())
If you need to wait for several futures to finish, in a similar way to asyncio.gather(),
then you can use wait_all():
results = [start_request(i) for i in range(10)]
await aioresult.wait_all(results)
print("results:", *[f.result() for f in results])
Reference
- class aioresult.Future[ResultT]
Bases:
ResultBase[ResultT]Stores a result or exception that is explicitly set by the caller.
- Type Parameters:
ResultT – Type of the value stored; see Type hints.
Note
Futureinherits most of its methods from its base classResultBase; see the documentation for that class for the inherited methods.- set_result(result)
Sets the result of the future to the given value.
After calling this method, later calls to
ResultBase.result()will return the value passed in.- Parameters:
result (ResultT) – The result value to be stored.
- Raises:
FutureSetAgainException – If the result has already been set with
set_result()orset_exception().
- set_exception(exception)
Sets the exception of the future to the given value.
After calling this method, later calls to
ResultBase.result()will throw an exception and calls toResultBase.exception()will return this exception. The exception raised byResultBase.result()will be aTaskFailedExceptionrather than the exception passed to this method, which matches the behaviour ofResultCapture; see Exception handling.- Parameters:
exception (BaseException) – The exception to be stored.
- Raises:
FutureSetAgainException – If the result has already been set with
set_result()orset_exception().
- exception aioresult.FutureSetAgainException
Bases:
ExceptionRaised if
Future.set_result()orFuture.set_exception()called more than once.It can also be raised from a
ResultCaptureifResultCapture.run()is called more than once.It is raised with the future passed as the argument to the exception:
raise FutureSetAgainException(self)
This allows access to the future from the exception using the
argsattribute:- args: tuple[ResultBase]
1-tuple of the
ResultCaptureorFuturethat raised this exception.