qi.async, qi.PeriodicTask API¶
Introduction¶
qi.async()
and qi.PeriodicTask
allow managing concurrent tasks.
Use of these should be preferred over classic threading.Thread or threading.Timer operations.
Thread creation and destruction are low-level operations that take resources for context switching each time they happen.
Using qi operations will let the system manage the low level operations and improve its overall performance.
qi.async¶
Launch an operation in a concurrent task.
The qi.future returned can be used to interact with the operation. (cancel, get return value ...)
-
qi.
async
(callback [, delay=usec] [, arg1, ..., argn]) → future¶ Parameters: - callback – the callback that will be called
- delay – an optional delay in microseconds
Returns: a future with the return value of the function
Warning
Canceling the async operation is possible while it is delayed.
Once the callback is called, cancel will not stop it in the middle of its execution.
qi.PeriodicTask¶
Execute an operation periodically and asynchronously.
By default, we do not compensate the callback time. The period will be constant between the end of a call and the beginning of another.
-
class
qi.
PeriodicTask
¶ -
asyncStop
()¶ Can be called from within the callback function Request for periodic task to stop asynchronously
-
compensateCallbackTime
(compensate)¶ Parameters: compensate – boolean. True to activate the compensation. When compensation is activated, call interval will take into account call duration to maintain the period.
Warning
when the callback is longer than the period specified, compensation will result in the callback being called successively without pause
-
isRunning
() → bool¶ Returns: true if task is running
-
isStopping
() → bool¶ Returns: whether state is stopping or stopped. Can be called from within the callback to know if stop() or asyncStop() was called.
-
setCallback
(callable)¶ Parameters: callable – a python callable, could be a method or a function set the callback used by the periodictask, this function can only be called once
-
setName
(name)¶ Set name for debugging and tracking purpose
-
setUsPeriod
(usPeriod)¶ Parameters: usPeriod – the period in microseconds Set the call interval in microseconds. This call will wait until next callback invocation to apply the change. To apply the change immediately, use:
task.stop() task.setUsPeriod() task.start()
-
start
(immediate)¶ Parameters: immediate – immediate if true, first schedule of the task will happen with no delay. start the periodic task at specified period. No effect if already running
Warning
concurrent calls to start() and stop() will result in undefined behavior.
-
stop
()¶ Stop the periodic task. When this function returns, the callback will not be called anymore. Can be called from within the callback function
Warning
concurrent calls to start() and stop() will result in undefined behavior.
-
PeriodicTask operations visualization¶
No compensation, task 3s, period 5s
v v
+-----------+ +-----------
+ Task 3s + wait 5s + Task 3s ...
+-----------+--------------------+-----------
Compensation, task 3s, period 5s
v v
+-----------+ +-----------
+ Task 3s + wait 2s + Task 3s ...
+-----------+---------+-----------
Compensation, task 7s, period 5s
v v
+----------------------------+---------------------------+----
+ Task 7s + Task 7s + ...
+----------------------------+---------------------------+----
Examples¶
In the following examples, we assume we have a connected session. If you already have an application, use:
application.session.service("ALTextToSpeech")
If you don’t, then use that:
session = qi.Session()
session.connect("tcp://127.0.0.1:9559")
Doing something in 2 seconds and getting the result.
import qi
def getAnswerToLifeAndUniverse(a, b):
return a + b
fut = qi.async(getAnswerToLifeAndUniverse, 40, 2, delay=2000000)
#do work while the result is being processed
print("Result:", fut.value())
Calling tts.say after 42 seconds.
import qi
#assume we have a connected session
tts = session.service("ALTextToSpeech")
fut = qi.async(tts.say, "42 seconds elapsed", delay=42000000)
#wait for the sentence to be said
fut.wait()
Calling tts.say every 10 seconds.
import qi
import time
import functools
#assume we have a connected session
tts = session.service("ALTextToSpeech")
sayHelloCallable = functools.partial(tts.say, "hello")
sayHelloTask = qi.PeriodicTask()
sayHelloTask.setCallback(sayHelloCallable)
sayHelloTask.setUsPeriod(10000000)
sayHelloTask.start(True)
time.sleep(30)
sayHelloTask.stop()
Canceling a delayed operation before its execution.
import qi
import time
def dummyAction():
# do your operations here
qi.info("async example", "My dummy action is over")
action = qi.async(dummyAction, delay=15000000)
time.sleep(5)
action.cancel()
action.wait()
if action.isCanceled():
qi.info("async example", "dummyAction was canceled as expected")