4

ヒットしました結果を2回設定することはできません非同期クエリをndb.Future.wait_all(futures)に実行すると、GAE Ndb非同期クエリの実行時エラーが発生します。このようなGAE NDB「結果を2回設定できません」エラー

何か:

futures = [] 
for item in items: 
    item._future_get = MyEntity.query(...).get_async() 
    futures.append(item._future_get) 

ndb.Future.wait_all(futures) 
# ... 

それはwait_allとの結果で失敗がどこSO上mentionnedされていない二回

、このエラーメッセージを設定することはできません。 Googleには2011年までの2-3件の記述があり、明確な説明はありません。

詳細情報:

アイテムは以前のフェッチのndbエンティティです。しかし、MyEntityでクエリが実行されるため、ここでは問題はありません(少なくとも私は思っています)。私はこのように関連するオブジェクトに先物を付けることに慣れているので、すべてが完了したときに並べ替える方が簡単です。

スタックトレース:

File "/home/my_project/app/main/admin/my_module.py", line 166, in admin_base_cleanup_details ndb.Future.wait_all(futures) 
    File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 350, in wait_all ev.run1() 
    File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/eventloop.py", line 235, in run1 delay = self.run0() 
    File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/eventloop.py", line 197, in run0 callback(*args, **kwds) 
INFO  2016-04-26 08:40:04,152 module.py:808] default: "GET /admin/cleanup/details?mode=status HTTP/1.1" 500 - 
    File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 475, in _on_future_completion self._help_tasklet_along(ns, ds_conn, gen, val) 
    File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 386, in _help_tasklet_along self.set_result(result) 
    File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 265, in set_result 
    raise RuntimeError('Result cannot be set twice.') 
RuntimeError: Result cannot be set twice. 

いくつかのより精度:

  • はい、それはGAE上で起こるだけでなく、地元のdevの上で行います。

  • いいえ、毎回失敗するわけではありませんが、しばしば十分です。

私はそれが別のスレッドからの並行性と関係していることがわかりました。 Webページは、ajax呼び出しを介して2つの要求を開始しました.1つは、非同期呼び出しを伴う更新クエリのためのもので、数秒かかります。また、定期的なステータス更新のようなものもあります。失敗したのは後者であり、必ずしもそうではありません。それ以来、私は2つの要求が重複することを避け、失敗しました。重複しているリクエストは禁止されていないので、バグのように見えます。

+0

あなたは 'item'が例外を取得するので、変更可能な属性とアイテムがアイテムに複製されたこと_future_get可能性がラインNOREが何であるかを言及していませんか? –

+0

スタックトレースと、 'item'が何であるかについてもう少し詳しく知る必要があります。 –

+0

@Tim私は最初の質問にもっと多くの情報を追加しました。 – patb

答えて

1

あなたはおそらく将来を取得するために)(fetch_async使用する必要があり、一方、「非同期最初のクエリの結果を返します」get_asyncを()を使用しています。

https://cloud.google.com/appengine/docs/python/ndb/queryclass#Query_get_async

+0

私はget_async()_は、future_を返すと信じていますが、あなたが参照しているドキュメントがこれを明示的に述べていないことは事実です。未来ではなくエンティティを返した場合、それ以外はどのように非同期になりますか? – patb

+0

あなたは正しいです。 ndb.get_async()実際に未来を返します。あなたが問題の原因としていることは、かなり面白いです。おそらく、タスクレットの一見は、重複する要求を避ける必要なしに、より具体的な解決策を提供する可能性があります。 –

関連する問題