Tasklets¶
Provides a tasklet decorator and related helpers.
Tasklets are a way to write concurrently running functions without threads. Tasklets are executed by an event loop and can suspend themselves blocking for I/O or some other operation using a yield statement. The notion of a blocking operation is abstracted into the Future class, but a tasklet may also yield an RPC in order to wait for that RPC to complete.
The @tasklet decorator wraps generator function so that when it is called, a Future is returned while the generator is executed by the event loop. Within the tasklet, any yield of a Future waits for and returns the Future’s result. For example:
from from google.cloud.ndb.tasklets import tasklet
@tasklet
def foo():
a = yield <AFuture>
b = yield <BFuture>
return a + b
def main():
f = foo()
x = f.result()
print(x)
In this example, foo needs the results of two futures, AFuture and BFuture, which it gets somehow, for example as results of calls. Rather than waiting for their values and blocking, it yields. First, the tasklet yields AFuture. The event loop gets AFuture and takes care of waiting for its result. When the event loop gets the result of AFuture, it sends it to the tasklet by calling send on the iterator returned by calling the tasklet. The tasklet assigns the value sent to a and then yields BFuture. Again the event loop waits for the result of BFuture and sends it to the tasklet. The tasklet then has what it needs to compute a result.
The tasklet simply returns its result. (Behind the scenes, when you return a value from a generator in Python 3, a StopIteration exception is raised with the return value as its argument. The event loop catches the exception and uses the exception argument as the result of the tasklet.)
Note that blocking until the Future’s result is available using result() is somewhat inefficient (though not vastly – it is not busy-waiting). In most cases such code should be rewritten as a tasklet instead:
@tasklet
def main_tasklet():
f = foo()
x = yield f
print(x)
Calling a tasklet automatically schedules it with the event loop:
def main():
f = main_tasklet()
eventloop.run() # Run until no tasklets left to do
f.done() # Returns True
- class google.cloud.ndb.tasklets.Future(info='Unknown')[source]¶
Bases:
object
Represents a task to be completed at an unspecified time in the future.
This is the abstract base class from which all NDB
Future
classes are derived. A future represents a task that is to be performed asynchronously with the current flow of program control.Provides interface defined by
concurrent.futures.Future
as well as that of the legacy Google App Engine NDBFuture
class.- add_done_callback(callback)[source]¶
Add a callback function to be run upon task completion. Will run immediately if task has already finished.
- Parameters
callback (Callable) – The function to execute.
- cancel()[source]¶
Attempt to cancel the task for this future.
If the task has already completed, this call will do nothing. Otherwise, this will attempt to cancel whatever task this future is waiting on. There is no specific guarantee the underlying task will be cancelled.
- check_success()[source]¶
Check whether a future has completed without raising an exception.
This will wait for the future to finish its task and will then raise the future’s exception, if there is one, or else do nothing.
- done()[source]¶
Get whether future has finished its task.
- Returns
True if task has finished, False otherwise.
- Return type
- exception()[source]¶
Get the exception for this future, if there is one.
If the task has not yet finished, this will block until the task has finished. When the task has finished, this will get the exception raised during the task, or None, if no exception was raised.
- get_exception()¶
Get the exception for this future, if there is one.
If the task has not yet finished, this will block until the task has finished. When the task has finished, this will get the exception raised during the task, or None, if no exception was raised.
- get_result()¶
Return the result of this future’s task.
If the task is finished, this will return immediately. Otherwise, this will block until a result is ready.
- Returns
The result
- Return type
Any
- get_traceback()[source]¶
Get the traceback for this future, if there is one.
Included for backwards compatibility with legacy NDB. If there is an exception for this future, this just returns the
__traceback__
attribute of that exception.- Returns
The traceback, or None.
- Return type
Union[types.TracebackType, None]
- result()[source]¶
Return the result of this future’s task.
If the task is finished, this will return immediately. Otherwise, this will block until a result is ready.
- Returns
The result
- Return type
Any
- running()[source]¶
Get whether future’s task is still running.
- Returns
False if task has finished, True otherwise.
- Return type
- set_exception(exception)[source]¶
Set an exception for this future.
Signals that this future’s task has resulted in an exception. The future is considered done but has no result. Once the exception is set, calls to
done()
will return True, and calls toresult()
will raise the exception.Should not be called from user code.
- Parameters
exception (Exception) – The exception that was raised.
- set_result(result)[source]¶
Set the result for this future.
Signals that this future has completed its task and sets the result.
Should not be called from user code.
- wait()[source]¶
Wait for this future’s task to complete.
This future will be done and will have either a result or an exception after a call to this method.
- static wait_all(futures)[source]¶
Calls
wait_all()
.
- static wait_any(futures)[source]¶
Calls
wait_any()
.
- exception google.cloud.ndb.tasklets.Return[source]¶
Bases:
Exception
Return from a tasklet in Python 2.
In Python 2, generators may not return a value. In order to return a value from a tasklet, then, it is necessary to raise an instance of this exception with the return value:
from google.cloud import ndb @ndb.tasklet def get_some_stuff(): future1 = get_something_async() future2 = get_something_else_async() thing1, thing2 = yield future1, future2 result = compute_result(thing1, thing2) raise ndb.Return(result)
In Python 3, you can simply return the result:
@ndb.tasklet def get_some_stuff(): future1 = get_something_async() future2 = get_something_else_async() thing1, thing2 = yield future1, future2 result = compute_result(thing1, thing2) return result
Note that Python 2 is no longer supported by the newest versions of Cloud NDB.
- google.cloud.ndb.tasklets.sleep(seconds)[source]¶
Sleep some amount of time in a tasklet. .. rubric:: Example
- ..code-block:: python
yield tasklets.sleep(0.5) # Sleep for half a second.
- google.cloud.ndb.tasklets.synctasklet(wrapped)[source]¶
A decorator to run a tasklet as a function when called.
Use this to wrap a request handler function that will be called by some web application framework (e.g. a Django view function or a webapp.RequestHandler.get method).
- Parameters
wrapped (Callable) – The wrapped function.
- google.cloud.ndb.tasklets.tasklet(wrapped)[source]¶
A decorator to turn a function or method into a tasklet.
Calling a tasklet will return a
Future
instance which can be used to get the eventual return value of the tasklet.For more information on tasklets and cooperative multitasking, see the main documentation.
- Parameters
wrapped (Callable) – The wrapped function.
- google.cloud.ndb.tasklets.toplevel(wrapped)[source]¶
A synctasklet decorator that flushes any pending work.
Use of this decorator is largely unnecessary, as you should be using
context()
which also flushes pending work when exiting the context.- Parameters
wrapped (Callable) – The wrapped function.”
- google.cloud.ndb.tasklets.wait_all(futures)[source]¶
Wait for all of several futures to finish.
- Parameters
futures (typing.Sequence[Future]) – The futures to wait on.
- google.cloud.ndb.tasklets.wait_any(futures)[source]¶
Wait for any of several futures to finish.
- Parameters
futures (typing.Sequence[Future]) – The futures to wait on.
- Returns
The first future to be found to have finished.
- Return type