Является get_result() требуемым вызовом для put_async() в Google App Engine

С новой версией GAE 1.5.0 теперь у нас есть простой способ делать асинхронные вызовы данных. Мы должны позвонить get_result() после вызова 'put_async'?

Например, если у меня есть модель с именем MyLogData, могу ли я просто позвонить:

put_async(MyLogData(text="My Text"))

прямо перед возвратом моего обработчика без вызова соответствующего get_result()? GAE автоматически блокирует любые ожидающие вызовы перед отправкой результата клиенту?

Обратите внимание, что мне не важно обрабатывать условия ошибки. то есть я не возражаю, если некоторые из них не срабатывают.

Ответы

Ответ 1

Я не думаю, что есть какой-либо верный способ узнать, требуется ли get_result(), если кто-то из команды GAE не проверяет это, но я думаю, что это не нужно. Вот как я его протестировал.

Я написал простой обработчик:

class DB_TempTestModel(db.Model):
    data = db.BlobProperty()

class MyHandler(webapp.RequestHandler):
    def get(self):
        starttime = datetime.datetime.now()
        lots_of_data = ' '*500000
        if self.request.get('a') == '1':
            db.put(DB_TempTestModel(data=lots_of_data))
            db.put(DB_TempTestModel(data=lots_of_data))
            db.put(DB_TempTestModel(data=lots_of_data))
            db.put(DB_TempTestModel(data=lots_of_data))
        if self.request.get('a') == '2':
            db.put_async(DB_TempTestModel(data=lots_of_data))
            db.put_async(DB_TempTestModel(data=lots_of_data))
            db.put_async(DB_TempTestModel(data=lots_of_data))
            db.put_async(DB_TempTestModel(data=lots_of_data))
        self.response.out.write(str(datetime.datetime.now()-starttime))

Я запускал его несколько раз в приложении с высокой репликацией.

Данные всегда были там, заставляя меня поверить, что, если в стороне хранилища данных нет сбоя (маловероятно), это будет написано.

Вот интересная часть. Когда данные записываются с помощью put_async() (?a=2), количество времени (для обработки запроса) было в среднем примерно в 2 - 3 раза быстрее, чем put() (?a=1) (не очень научный тест - просто заглядывая в нее).

Но cpu_ms и api_cpu_ms были одинаковыми как для ?a=1, так и для ?a=2.

Из журналов:

ms=440 cpu_ms=627 api_cpu_ms=580 cpm_usd=0.036244

против

ms=149 cpu_ms=627 api_cpu_ms=580 cpm_usd=0.036244

На стороне клиента, глядя на латентность запросов в сети, он показал те же результаты, т.е. запросы `? a = 2 'были как минимум в 2 раза быстрее. Определенно выигрыш на стороне клиента... но он, похоже, не имеет выигрыша на стороне сервера.

Кто-нибудь из команды GAE хочет прокомментировать?

Ответ 3

Я не знаю, но это работает:

import datetime
from google.appengine.api import urlfetch

def main():
  rpc = urlfetch.create_rpc()
  urlfetch.make_fetch_call(rpc, "some://artificially/slow.url")
  print "Content-type: text/plain"
  print
  print str(datetime.datetime.now())

if __name__ == '__main__':
  main()

Удаленный URL-адрес засыпает 3 секунды, а затем отправляет мне электронное письмо. Обработчик App Engine немедленно возвращается, и удаленный URL-адрес завершается, как ожидалось. Поскольку обе службы абстрагируют одну и ту же базовую структуру RPC, я бы предположил, что хранилище данных ведет себя аналогичным образом.

Хороший вопрос. Возможно, Ник или другой Гуглер могут ответить окончательно.