¿Cómo entender ndb.tasklet appengine?

De la documentación :

Un tasklet NDB es un fragmento de código que puede ejecutarse simultáneamente con otro código. Si escribe un tasklet, su aplicación puede usarlo de manera muy similar a como usa una función NDB asíncrona: llama al tasklet, que devuelve un Futuro; más tarde, al llamar al método get_result () del futuro se obtiene el resultado.

La explicación y los ejemplos en el documento realmente me gusta una magia para mí. Puedo usarlo, pero me siento difícil de entenderlo correctamente.

Por ejemplo:

  1. ¿Puedo poner cualquier tipo de código dentro de una función y decorarlo como ndb.tasklet? Luego lo usé como función asíncrona más tarde. ¿O debe ser RPC appengine?
  2. ¿Este tipo de decorador también funciona en mi PC?
  3. ¿Es lo mismo que tasklet para pypy?

Si nos fijamos en la implementación de un futuro, es muy comparable a lo que es un generador en python. De hecho, utiliza la misma palabra clave de yield para lograr lo que dice que hace. Lea los comentarios de introducción en el tasklets.py para alguna aclaración.

Cuando usas el decorador @tasklet, crea un futuro y espera un valor en la función envuelta. Si el valor es un generador, agrega el futuro al bucle de eventos. Cuando yield en un futuro, el bucle de eventos se ejecuta en TODOS los futuros en cola hasta que el futuro que desea esté listo. La concurrencia aquí es que cada Futuro ejecutará su código hasta que regrese (con el uso de raise ndb.Return(...) o la función se complete), se lance una excepción o se use el yield nuevamente. Supongo que técnicamente, puede utilizar el yield en el código para detener la ejecución de esa función y dejar que el bucle de eventos continúe ejecutando otros futuros, pero supongo que esto no ayudaría mucho a menos que tenga realmente en mente un caso de uso inteligente. .

Para responder tu pregunta:

  1. Técnicamente sí, pero no se ejecutará de forma asíncrona. Cuando decoras una función que no rinde con @tasklet, el valor de su Futuro se calcula y establece cuando llamas a esa función. Es decir, se ejecuta a través de toda la función cuando lo llamas. Si desea lograr una operación asíncrona, debe yield en algo que haga un trabajo asíncrono. En general, en GAE se abrirá camino hacia una llamada RPC.

  2. Si por trabajo en su PC quiere decir si el dev appserver implementa tasklets / Futures como GAE, entonces sí, aunque esto es más preciso con devappserver2 (ahora el predeterminado en el SDK más nuevo). En realidad, no estoy 100% seguro de si las llamadas RPC locales se ejecutarán en paralelo al usar Futures, pero hay un evento que pasa a través de Futures, ya sea local o en producción. Si desea usar Future’s en su otro código que no es de GAE, creo que sería mejor utilizar el futuro integrado de Python 3.2 (o encontrar un puerto trasero aquí )

  3. Algo así, no es realmente una comparación simple. Mira la documentación aquí . La idea es algo similar (el planificador puede compararse con el eventloop), pero la implementación de bajo nivel difiere mucho.