Module google.appengine.ext.ndb.tasklets

Résumé

Décorateur de tasklet.

Les tasklets constituent un moyen d'écrire des fonctions qui s'exécutent simultanément sans threads. Ils sont exécutés par une boucle d'événements et peuvent se suspendre d'eux-mêmes en bloquant des opérations d'E/S ou toute autre opération, à l'aide d'une instruction "yield". La notion d'opération de blocage est résumée dans la classe Future, mais un tasklet peut également appliquer l'instruction "yield" à un RPC afin d'en attendre la fin.

Le décorateur @tasklet encapsule la fonction de générateur de sorte que lorsqu'elle est appelée, un objet Future est renvoyé pendant que le générateur est exécuté par la boucle d'événements. Dans le tasklet, toute instruction "yield" d'un objet Future attend et affiche le résultat de l'objet Future. Exemple :

@tasklet
def foo():
  a = yield <some Future>
  b = yield <another Future>
  raise Return(a + b)

def main():
  f = foo()
  x = f.get_result()
  print x

Notez que le blocage est relativement inefficace (mais pas largement, car il n'est pas en attente d'occupation) jusqu'à ce que le résultat de l'objet Future soit disponible à l'aide de get_result(). Dans la plupart des cas, ce code doit être réécrit en tant que tasklet :

@tasklet
def main_tasklet():
  f = foo()
  x = yield f
  print x

Lorsque vous appelez un tasklet, sa planification se fait automatiquement avec la boucle d'événements :

def main():
  f = main_tasklet()
  eventloop.run()  # Run until no tasklets left to do
  f.done()  # Returns True

En tant que caractéristique spéciale, si la fonction encapsulée n'est pas une fonction de générateur, sa valeur est renvoyée via l'objet Future. Cela rend les deux fonctions suivantes équivalentes :

@tasklet
def foo():
  return 42

@tasklet
def foo():
  if False: yield  # The presence of 'yield' makes foo a generator
  raise Return(42)  # Or, after PEP 380, return 42

Cette caractéristique (inspirée par Monocle) est pratique si vous mettez en œuvre une interface qui attend des tasklets, mais que vous n'avez pas besoin de suspendre. Vous n'avez pas besoin d'insérer une instruction "yield" factice pour créer le tasklet dans un générateur.

Contenus

google.appengine.ext.ndb.tasklets.Return

alias de StopIteration

google.appengine.ext.ndb.tasklets.tasklet(func)source
google.appengine.ext.ndb.tasklets.synctasklet(func)source

Décorateur permettant d'exécuter une fonction en tant que tasklet lorsqu'elle est appelée.

Utilisez cette solution pour encapsuler une fonction de gestionnaire de requêtes qui sera appelée par un framework d'application Web (par exemple, une fonction de vue Django ou une méthode webapp.RequestHandler.get).

google.appengine.ext.ndb.tasklets.toplevel(func)source

Un tasklet de synchronisation qui définit un nouveau contexte par défaut.

À utiliser pour les fonctions d'affichage de premier niveau, telles que webapp.RequestHandler.get() ou les fonctions d'affichage Django.

google.appengine.ext.ndb.tasklets.sleep(dt)source

Fonction publique pour suspendre un certain temps

Exemple

yield tasklets.sleep(0.5) # Sleep for half a sec.

google.appengine.ext.ndb.tasklets.add_flow_exception(exc)source

Ajoute une exception qui ne doit pas être enregistrée dans les journaux.

L'argument doit être une sous-classe de l'exception.

google.appengine.ext.ndb.tasklets.get_return_value(err)source
google.appengine.ext.ndb.tasklets.get_context()source
google.appengine.ext.ndb.tasklets.set_context(new_context)source
google.appengine.ext.ndb.tasklets.make_default_context()source
google.appengine.ext.ndb.tasklets.make_context(*args, **kwds)source
class google.appengine.ext.ndb.tasklets.Future(info=None)source

Bases : objet

Objet Future comporte 0 rappel ou plus.

Les rappels sont appelés lorsque le résultat est prêt.

REMARQUE : Il peut être légèrement inspiré, mais non conforme à l'interface Future définie par PEP 3148. Il est également inspiré des classes UserRPC et MultiRpc spécifiques à App Engine, et tente d'être légèrement compatible.

FINISHING = 2
IDLE = 0
RUNNING = 1
add_callback(callback, *args, **kwds)source
add_immediate_callback(callback, *args, **kwds)source
check_success()source
done()source
dump()source
dump_stack()source
get_exception()source
get_result()source
get_traceback()source
set_exception(exc, tb=None)source
set_result(result)source
state
wait()source
classmethod wait_all(futures)source
classmethod wait_any(futures)source
class google.appengine.ext.ndb.tasklets.MultiFuture(info=None)source

Bases : google.appengine.ext.ndb.tasklets.Future

Objet Future qui dépend de plusieurs autres objets Future.

Ceci est utilisé en interne par "v1, v2, ... = yield f1, f2, ...". La sémantique (par exemple, la gestion des exceptions) est limitée par ce cas d'utilisation.

Le protocole du point de vue de l'appelant est le suivant :

mf = MultiFuture()
mf.add_dependent(<some other Future>)  -OR- mf.putq(<some value>)
mf.add_dependent(<some other Future>)  -OR- mf.putq(<some value>)
  .
  . (More mf.add_dependent() and/or mf.putq() calls)
  .
mf.complete()  # No more dependents will be added.
  .
  . (Time passes)
  .
results = mf.get_result()

Les résultats correspondent maintenant à la liste des résultats de tous les objets Future dépendants, dans l'ordre dans lequel ils ont été ajoutés.

L'ajout de la même dépendance plusieurs fois est autorisé.

Vous pouvez ajouter des rappels à tout moment.

À partir d'un point de vue Future dépendant, vous n'avez rien à faire. Un rappel est automatiquement ajouté à chaque objet Future dépendant qui signale sa fin à l'objet MultiFuture.

Gestion des exceptions : si un objet Future dépendant génère une erreur, il est transmis à mf. Pour forcer une erreur anticipée, vous pouvez appeler mf.set_exception() au lieu de mf.complete(). Une fois ceci fait, vous ne pouvez plus appeler mf.add_dependent() ou mf.putq().

add_dependent(fut)source
complete()source
putq(value)source
set_exception(exc, tb=None)source
class google.appengine.ext.ndb.tasklets.QueueFuture(info=None)source

Bases : google.appengine.ext.ndb.tasklets.Future

File d'attente suivant le même protocole que MultiFuture.

Toutefois, au lieu de renvoyer les résultats sous forme de liste, elle vous permet de récupérer les résultats dès qu'ils sont prêts, un à la fois, à l'aide de la méthode getq(). L'objet Future lui-même se termine par un résultat "None" lorsque le dernier résultat est prêt (qu'il ait été récupéré ou non).

La méthode getq() renvoie un objet Future qui bloque votre code jusqu'à ce que le résultat suivant soit prêt, puis renvoie ce résultat. Chaque appel getq() récupère un résultat unique. Les appels getq() supplémentaires après le dernier résultat renvoient déjà EOFError comme exception de Future. Cela signifie que q.getq() renvoie un objet Future comme toujours, mais en indiquant qu'il génère une erreur EOFError.

REMARQUE : Les valeurs peuvent également être transmises directement via .putq(value). Toutefois, il n'y a pas de contrôle de flux. Si le producteur est plus rapide que le consommateur, la file d'attente augmente sans cesse.

add_dependent(fut)source
complete()source
getq()source
putq(value)source
set_exception(exc, tb=None)source
class google.appengine.ext.ndb.tasklets.SerialQueueFuture(info=None)source

Bases : google.appengine.ext.ndb.tasklets.Future

Semblable à QueueFuture, mais conserve l'ordre d'insertion.

Cette classe est utilisée par les opérations de requête.

Règles invariantes :

  • L'une des deux options _queue et _waiting est vide.

  • Les objets Future dans _waiting sont toujours en attente.

(Les objets Future dans _queue peuvent être en attente ou terminés.)

Dans la discussion ci-dessous, add_dependent() est traité de la même manière que putq().

Si putq() précède getq(), la situation se présente comme suit :

putq() v

_queue: [f1, f2, …]; _waiting: [] ^ getq()

Ici, putq() ajoute un objet Future à droite de _queue et getq() en supprime un à gauche.

Si la fonction getq() précède putq(), elle se présente comme suit :

putq() v

_queue: []; _waiting: [f1, f2, …]

^ getq()

Ici, la fonction putq() supprime un objet Future à gauche de _waiting et getq() en ajoute un à droite.

Lorsque les deux sont vides, putq() ajoute un objet Future à droite de _queue, tandis que getq() en ajoute un à droite de _waiting.

L'option _full signifie qu'aucun autre appel à putq() ne sera effectué. Elle est définie en appelant complete() ou set_exception().

L'appel de complete() indique qu'aucun autre appel putq() ne sera effectué. Si la fonction getq() est située derrière, les appels getq() ultérieurs utiliseront _queue jusqu'à ce qu'il soit vide. Ensuite, la fonction renvoie un objet Future qui transmet l'erreur EOFError (notez que getq() ne génère jamais d'erreur EOFError). Si la fonction getq() est prête lorsque la fonction complete() est appelée, les objets Future dans _waiting reçoivent tous une exception "EOFError" (utilisant ainsi "_waiting").

Si la fonction set_exception() est appelée au lieu de complete(), l'exception et l'ensemble des traces sont utilisés à la place de EOFError.

add_dependent(fut)source
complete()source
getq()source
putq(value)source
set_exception(exc, tb=None)source
class google.appengine.ext.ndb.tasklets.ReducingFuture(reducer, info=None, batch_size=20)source

Bases : google.appengine.ext.ndb.tasklets.Future

File d'attente suivant le même protocole que MultiFuture.

Toutefois, au lieu d'être une liste de résultats d'objets Future dépendants, le résultat est calculé en appelant un tasklet "reducer". Le tasklet du réducteur utilise une liste de valeurs et renvoie une valeur unique. Il peut être appelé plusieurs fois sur des sous-listes de valeurs et doit se comporter comme sum().

REMARQUE : Les valeurs d'entrée du réducteur peuvent être réorganisées par rapport à l'ordre dans lequel elles ont été ajoutées à la file d'attente.

add_dependent(fut)source
complete()source
putq(value)source
set_exception(exc, tb=None)source