异步推迟谷歌应用引擎中的多个任务

时间:2014-01-24 18:12:40

标签: python google-app-engine asynchronous app-engine-ndb

我有一个带有3个参数的tasklet,一个带有id和title的字典,一个用户密钥和一个已经存在于数据库中的记录列表。 函数defer_fetch在for循环中被调用N次。

@ndb.tasklet
def defer_fetch(data, user_key, already_inserted):
    if data['_id'] not in already_inserted:
         document_key = yield Document.fetch_or_create(data)
         yield defer_fetch_document(user_key, document_key)
    else:
         document_key = alread_inserted[data['_id']]
    raise ndb.Return(document_key)

@ndb.tasklet
def defer_fetch_document(user_key, document_key):
    deferred.defer(process_document, user_key, document_key, _queue="process-documents")
    raise ndb.Return(True)

document.fetch_or_create的代码正在defer_fetch的所有调用中并行执行,但调用fetch_document不是,如附件中所示

waterfall of calls

如何使defer_fetch_document也并行运行?

1 个答案:

答案 0 :(得分:5)

据我所知,deferred与ndb.tasklets没有很好的协作(deferred.defer上没有产生,所以代码只是同步运行)。 相反,您应该直接使用任务队列及其add_async功能。

@ndb.tasklet
def defer_fetch_document(user_key, document_key):
    queue = taskqueue.Queue("process-documents")
    task = taskqueue.Task(url="<url for worker>", 
                          params={"document_key": document_key.urlsafe()})
    yield queue.add_async(task)  #this returns a rpc which you can yield on
    raise ndb.Return(True)

或者,生成一个文档键列表(从中生成任务列表),然后使用任务列表调用add_async。