使用Google App Engine NDB创建异步方法

时间:2012-08-25 20:20:00

标签: python google-app-engine google-cloud-datastore

我想确保我了解如何创建tasklet和asyncrounous方法。我所拥有的是一个返回列表的方法。我希望从某个地方调用它,并立即允许其他调用。所以我有这个:

future_1 = get_updates_for_user(userKey, aDate)
future_2 = get_updates_for_user(anotherUserKey, aDate)
somelist.extend(future_1)
somelist.extend(future_2)

....    

@ndb.tasklet
def get_updates_for_user(userKey, lastSyncDate):
    noteQuery = ndb.GqlQuery('SELECT * FROM Comments WHERE ANCESTOR IS :1 AND modifiedDate > :2', userKey, lastSyncDate)
    note_list = list()
    qit = noteQuery.iter()
    while (yield qit.has_next_async()):
        note = qit.next()
        noteDic = note.to_dict()
        note_list.append(noteDic)
    raise ndb.Return(note_list)

这段代码是否符合我的期望?也就是说,这两个调用是否会异步运行?我正确使用期货吗?

编辑:经过测试,代码确实会产生预期的结果。我是Python的新手 - 有什么方法可以测试方法是否运行异步?

1 个答案:

答案 0 :(得分:4)

很难自己验证方法是否同时运行 - 你必须进行大量的登录。同样在开发应用程序服务器中它会更难,因为它并不真正并行运行RPC。

您的代码看起来没问题,它在正确的位置使用yield

我唯一的建议是命名你的函数get_updates_for_user_async() - 它与NDB本身使用的约定相匹配,并且是对你的代码的读者提示函数返回一个Future并且应该得到以获得实际结果

另一种方法是在map_async()对象上使用Query方法;它会让你编写一个只包含to_dict()调用的回调:

@ndb.tasklet
def get_updates_for_user_async(userKey, lastSyncDate):
  noteQuery = ndb.gql('...')
  note_list = yield noteQuery.map_async(lambda note: note.to_dict())
  raise ndb.Return(note_list)

高级提示:您可以通过删除@ndb.tasklet装饰器并返回map_async()返回的Future来进一步简化此操作:

def get_updates_for_user_Async(userKey, lastSyncDate):
  noteQuery = ndb.gql('...')
  return noteQuery.map_async(lambda note: note.to_dict())

这是对仅包含一个yield的异步函数的一般略微优化,并立即返回所产生的值。 (如果你没有立即得到这个,你就是一个好公司,并且它有可能被未来的维护者破坏。: - )