Search code examples
pythongoogle-app-engineasynchronouswebapp2

Asynchronous Tasks


I have a question regarding the architecture of Tasks in App Engine.

Say I have a simple task:

class MyTask(webapp2.RequestHandler):
    def post(self):
        k = ndb.Key(urlsafe=self.request.get('key'))
        entities = Model.query(ancestor=k).fetch(100)
        for entity in entities:
            entity.something = True
        ndb.put_multi(entities)

I have only one frontend instance, and many of these tasks running at once. Does it make sense to turn it into a tasklet, like this?

class MyTask(webapp2.RequestHandler):
    @ndb.synctasklet
    def post(self):
        k = ndb.Key(urlsafe=self.request.get('key'))
        entities = yield Model.query(ancestor=k).fetch_async(100)
        for entity in entities:
            entity.something = True
        yield ndb.put_multi_async(entities)

Would this potentially allow collecting the RPCs and sending them out in larger batches? Or would it simply run as just as fast as the synchronous version, blocking on each RPC?


Solution

  • NDB creates a new context per request, so no, there would be no advantage.

    Details: Both ndb.toplevel and ndb.synctasklet creates a new context (which would be in charge of aggregating RPC requests and batching them out). toplevel actually is a synctasklet but it will create a fresh context to use.