qi.Future API¶
Introduction¶
Promise and Future are a way to synchronise data between multiples threads. The number of future associated to a promise is not limited. Promise is the setter, future is the getter. Basically, you have a task to do, that will return a value, you give it a Promise. Then you have others thread that depend on the result of that task, you give them future associated to that promise, the future will block until the value or an error is set by the promise.
Reference¶
-
qi.
FutureState
¶ Constants that describe the state of the Future. This is the status returned by
qi.Future.wait()
qi.FutureState.None The future is not bound. qi.FutureState.Running The future is attached to a Promise. qi.FutureState.Canceled The future has been canceled qi.FutureState.FinishedWithError The future has finished and an error is available qi.FutureState.FinishedWithValue The future has finished and a value is available
-
qi.
FutureTimeout
¶ Constants to use for timeout arguments.
qi.FutureTimeout.None Do not wait. qi.FutureTimeout.Infinite Block forever
-
class
qi.
Promise
¶ -
__init__
(cb)¶ Parameters: cb – a python callable If the promise was constructed with a callback in parameter, it will be executed when a future associated to the promise is cancelled. The first argument of the callback is the promise itself.
-
future
() → qi.Future¶ Get a qi.Future from the promise, you can get multiple from the same promise.
-
isCancelRequested
() → bool¶ Return true if the future associated with the promise asked for cancelation
-
setCanceled
() → None¶ Set the state of the promise to Canceled
-
setError
(error) → None¶ Set the error of the promise
-
setValue
(value) → None¶ Set the value of the promise
-
-
class
qi.
Future
¶ -
addCallback
(cb) → None¶ Parameters: cb – a python callable, could be a method or a function. Add a callback that will be called when the future becomes ready. The callback will be called even if the future is already ready. The first argument of the callback is the future itself.
-
andThen
(cb) → None¶ Parameters: cb – a python callable, could be a method or a function. Returns: a future that will contain the return value of the callback. Add a callback that will be called when the future becomes ready if it has a value. If the future finishes with an error, the callback is not called and the future returned by andThen is set to that error. The callback will be called even if the future is already ready. The first argument of the callback is the value of the future itself.
-
cancel
() → None¶ Ask for cancelation.
-
error
(timeout) → string¶ Parameters: timeout – a time in milliseconds. Optional. Returns: the error of the future. Raise: a RuntimeError if the timeout is reached or the future has no error. Block until the future is ready.
-
hasError
(timeout) → bool¶ Parameters: timeout – a time in milliseconds. Optional. Returns: true if the future has an error. Raise: a RuntimeError if the timeout is reached. Return true or false depending on the future having an error.
-
hasValue
(timeout) → bool¶ Parameters: timeout – a time in milliseconds. Optional. Returns: true if the future has a value. Raise: a RuntimeError if the timeout is reached. Return true or false depending on the future having a value.
-
isCancelable
() → bool¶ Returns: always true, all future are cancelable now Deprecated since version 2.5.
-
isCanceled
() → bool¶ Returns: true if the future is canceled.
-
isFinished
() → bool¶ Returns: true if the future is not running anymore (if hasError or hasValue or isCanceled).
-
isRunning
() → bool¶ Returns: true if the future is still running.
-
then
(cb) → None¶ Parameters: cb – a python callable, could be a method or a function. Returns: a future that will contain the return value of the callback. Add a callback that will be called when the future becomes ready. The callback will be called even if the future is already ready. The first argument of the callback is the future itself.
-
unwrap
() → Future¶ If this is a Future of a Future of X, return a Future of X. The state of both futures is forwarded and cancel requests are forwarded to the appropriate future
-
value
(timeout) → value¶ Parameters: timeout – a time in milliseconds. Optional. Returns: the value of the future. Raise: a RuntimeError if the timeout is reached or the future has error. Block until the future is ready.
-
wait
(timeout) → qi.FutureState¶ Parameters: timeout – a time in milliseconds. Optional. Returns: a qi.FutureState
.Wait for the future to be ready.
-
Examples¶
Simple example:
import qi
import time
import functools
def doSomeWork(p):
#do your work here instead of sleeping
time.sleep(1)
p.setValue(42)
p = qi.Promise()
f = p.future()
qi.async(functools.partial(doSomeWork, p))
print "result:", f.value()
With callback:
import qi
import time
import functools
def doSomeWork(p):
#do your work here instead of sleeping
time.sleep(1)
p.setValue(42)
def resultReady(f):
if f.hasValue():
print "Value:", f.value()
elif f.hasError():
print "Error:", f.error()
p = qi.Promise()
f = p.future()
qi.async(functools.partial(doSomeWork, p))
#resultReady will be called even if the result is already there.
f.addCallback(resultReady)
Cancellation support¶
In some situations, you will want to create asynchronous operations that can be
interrupted in the middle of their execution. For that you can set a callback
to the promise that will be called when someone asks for cancellation or just
check for isCancelRequested()
on the promise.
import qi
import time
from functools import partial
class FakeOperation:
def doStep(self):
time.sleep(0.3)
print 'I executed one step'
def longOperation(self, promise):
"do steps or cancel before the end"
for i in range(10):
if promise.isCancelRequested():
print 'Cancel requested, aborting'
promise.setCanceled()
return
self.doStep()
# if an error occurred, promise.setError("error")
# use setValue if everything went ok
print 'longOperation finished'
promise.setValue(None)
def asyncLongOperation(self):
"start long operation and return a future"
promise = qi.Promise()
qi.async(partial(self.longOperation, promise))
return promise.future()
m = FakeOperation()
fut = m.asyncLongOperation()
time.sleep(1)
fut.cancel()
assert fut.wait() == qi.FutureState.Canceled
assert fut.isCanceled()
assert fut.isFinished()
-
qi.
PromiseNoop
(*args, **kwargs)¶ No operation function .. deprecated:: 2.5