1

タスクレットと非同期メソッドの作成方法を確実に理解したいと思います。私が持っているのはリストを返すメソッドです。どこかから呼び出して、すぐに他の呼び出しを許可したい。だから私はこれを持っています:

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)

このコードは、私が期待することを実行していますか?つまり、2つの呼び出しは非同期で実行されますか?先物を正しく使用していますか?

編集:テスト後、コードは目的の結果を生成します。私はPythonの初心者です-メソッドが非同期で実行されているかどうかを確認するためにテストする方法は何ですか?

4

1 に答える 1

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高度なヒント:デコレータを削除し、次のように返されるFutureを返すだけで、これをさらに単純化できますmap_async()

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

これは、yieldを1つだけ含み、yieldされた値をすぐに返す非同期関数の一般的なわずかな最適化です。(これをすぐに受け取らなければ、あなたは良い仲間になります、そしてそれはどちらもしない将来のメンテナによって壊される危険を冒します。:-)

于 2012-08-27T01:21:10.843 に答える