使用Google App Engine的NDB创建异步方法 [英] Creating an asynchronous method with Google App Engine's NDB

查看:133
本文介绍了使用Google App Engine的NDB创建异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确保我了解了如何创建tasklet和异步方法。我拥有的是返回列表的方法。我希望从某处调用它,并立即允许进行其他调用。所以我有这样的:
$ b $ pre $ code> 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)

d期望它做什么?也就是说,这两个调用是否会异步运行?我是否正确使用期货?



编辑:测试完成后,代码确实会产生所需的结果。我是一个Python的新手 - 有什么方法可以测试以查看这些方法是否正在运行异步?

很难亲自验证这些方法是否正在同时运行 - 您必须进行大量的日志记录。另外,在开发应用程序服务器中,它会更加困难,因为它并不真正并行运行RPC。



您的代码看起来不错,它在正确的位置使用 yield



我唯一的建议是命名你的函数 get_updates_for_user_async() - 它符合NDB自身使用的约定,并且暗示给你的代码的读者,函数返回一个Future并且应该放弃以获得实际结果。



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

  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, / p>

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

这是一个通用的轻微优化对于只包含一个yield的异步函数,立即返回产生​​的值。 (如果你没有立即得到这个信息,你就会成为一个好公司,并且冒着被未来的维护人员打破的风险: - )


I want to make sure I got down how to create tasklets and asyncrounous methods. What I have is a method that returns a list. I want it to be called from somewhere, and immediatly allow other calls to be made. So I have this:

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)

Is this code doing what I'd expect it to do? Namely, will the two calls run asynchronously? Am I using futures correctly?

Edit: Well after testing, the code does produce the desired results. I'm a newbie to Python - what are some ways to test to see if the methods are running async?

解决方案

It's pretty hard to verify for yourself that the methods are running concurrently -- you'd have to put copious logging in. Also in the dev appserver it'll be even harder as it doesn't really run RPCs in parallel.

Your code looks okay, it uses yield in the right place.

My only recommendation is to name your function get_updates_for_user_async() -- that matches the convention NDB itself uses and is a hint to the reader of your code that the function returns a Future and should be yielded to get the actual result.

An alternative way to do this is to use the map_async() method on the Query object; it would let you write a callback that just contains the to_dict() call:

@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)

Advanced tip: you can simplify this even more by dropping the @ndb.tasklet decorator and just returning the Future returned by map_async():

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

This is a general slight optimization for async functions that contain only one yield and immediately return the value yielded. (If you don't immediately get this you're in good company, and it runs the risk to be broken by a future maintainer who doesn't either. :-)

这篇关于使用Google App Engine的NDB创建异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆