Mam moduł obsługi żądań, który aktualizuje encję, zapisuje ją w magazynie danych, a następnie musi wykonać dodatkowe prace przed powrotem (np. Kolejkowanie zadań w tle i json-serializacja niektórych wyników). Chcę zrównoleglić ten kod, aby dodatkowa praca była wykonywana podczas zapisywania jednostki.Jak zapobiec wywoływaniu przez ndb wywołania metody put_async() i natychmiastowemu wystawianiu wywołania RPC?
Oto co mój kod obsługi sprowadza się do:, Appstats pokazuje
class FooHandler(webapp2.RequestHandler):
@ndb.toplevel
def post(self):
foo = yield Foo.get_by_id_async(some_id)
# Do some work with foo
# Don't yield, as I want to perform the code that follows
# while foo is being saved to the datastore.
# I'm in a toplevel, so the handler will not exit as long as
# this async request is not finished.
foo.put_async()
taskqueue.add(...)
json_result = generate_result()
self.response.headers["Content-Type"] = "application/json; charset=UTF-8"
self.response.write(json_result)
jednak, że datastore.Put
RPC jest robione seryjnie po taskqueue.Add
:
Trochę kopania wokół w ndb.context.py
pokazuje, że połączenie put_async()
zostanie dodane do AutoBatcher
zamiast natychmiastowego wydania RPC.
Zakładam, że kończy się przepłukiwaniem, gdy toplevel
czeka na zakończenie wszystkich wywołań asynchronicznych.
Rozumiem, że dozowanie daje rzeczywiste korzyści w niektórych scenariuszach, ale w moim przypadku tutaj naprawdę chcę, aby wysłany RPC został wysłany natychmiast, więc mogę wykonywać inne prace, gdy jednostka jest zapisywana.
Jeśli robię yield foo.put_async()
, a następnie uzyskać ten sam wodospad w Appstats, ale z datastore.Put
zostało zrobione przed resztą:
to należy się spodziewać, jak yield
sprawia, że moja obsługi czekać na put_async()
wywołanie zakończone przed wykonaniem reszty kodu.
ja też próbowałem dodając wywołanie ndb.get_context().flush()
zaraz po foo.put_async()
, ale datastore.Put
i taskqueue.BulkAdd
połączenia są nadal nie są wykonane równolegle według Appstats.
Moje pytanie brzmi: jak mogę wymusić połączenie z put_async()
, aby ominąć automatyczny dozownik i natychmiast wysłać RPC?
Czy jest produkowany czy lokalny? – Lipis
Jest w trakcie produkcji. –