我们不关心结果时的异步URLfetch? [蟒蛇]

时间:2011-03-23 20:34:47

标签: python google-app-engine asynchronous urlfetch

在我为GAE编写的一些代码中,我需要定期对另一个系统上的URL执行GET,实质上是“ping”它,如果请求失败,超时或成功,我并不十分担心。< / p>

因为我基本上想要“发射并忘记”而不是通过等待请求来减慢我自己的代码,我使用异步urlfetch,而不是调用get_result()。

在我的日志中,我收到警告:

找到1个没有匹配响应的RPC请求(可能是由于超时或其他错误)

我错过了一个明显更好的方法吗?在这个例子中,任务队列或延期任务似乎(对我来说)过度杀伤。

任何意见都会受到赞赏。

2 个答案:

答案 0 :(得分:6)

任务队列任务是您最好的选择。您在日志中看到的消息表明请求正在等待您的URLFetch在返回之前完成,因此这没有帮助。你说任务是“过度杀伤”,但实际上,它们非常轻巧,绝对是最好的方法。延迟甚至允许您直接推迟提取调用,而不必编写要调用的函数。

答案 1 :(得分:2)

async_url_fetch需要多长时间才能完成,以及提供响应需要多长时间?

这是一种可能的方法来利用api在python中的工作方式。

需要考虑的一些要点。

  • 许多网络服务器和反向代理一旦启动就不会取消请求。因此,如果您正在ping的远程服务器提示请求但需要很长时间来为其提供服务,请在create_rpc(截止日期= X)上使用截止日期,以便X将因超时而返回。 ping可能仍然成功。这种技术也适用于appengine本身。

  • GAE RPCs

    • 通过make_call / make_fetch_call提示后的RPC实际上只有在等待其中一个之后才会被调度。
    • 任何刚刚完成的rpc都将在当前等待一个完成时调用它的回调。
    • 您可以创建一个async_urlfetch rpc,并在处理您的请求时尽早使用make_fetch_call将其排队,不要等待它。
    • 实际的页面服务工作,如memcache / datastore调用,以使工作继续进行。对其中一个的第一次调用将执行等待,该等待将调度您的async_urlfetch。
    • 如果在另一个活动期间urlfetch完成,则将调用urlfetch上的回调,允许您处理结果。
    • 如果你调用get_result(),它将在wait()上阻塞直到截止日期,否则它会返回,除非结果准备就绪。

回顾一下。

使用合理的截止日期和回调准备长时间运行的url_fetch。使用make_fetch_call将其排入队列。为页面做你想做的工作。无论url_fetch是完成还是截止日期而不等待它,都要返回页面。

GAE中的底层RPC层都是异步的,似乎有一种更复杂的方式来选择你想要在工作中等待的东西。

这些示例将sleep和url_fetch用于同一应用程序的第二个实例。

调度rpc工作的wait()示例:

class AsyncHandler(RequestHandler):

    def get(self, sleepy=0.0):
        _log.info("create rpc")
        rpc = create_rpc()
        _log.info("make fetch call")
        # url will generate a 404
        make_fetch_call(rpc, url="http://<my_app>.appspot.com/hereiam")
        _log.info("sleep for %r", sleepy)
        sleep(sleepy)
        _log.info("wait")
        rpc.wait()
        _log.info("get_result")
        rpc.get_result()
        _log.info("return")
        return "<BODY><H1>Holla %r</H1></BODY>" % sleepy

等待睡眠4秒后显示

2011-03-23 17:08:35.673 /delay/4.0 200 4093ms 23cpu_ms 0kb Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151 Safari/534.16,gzip(gfe)
I 2011-03-23 17:08:31.583 create rpc
I 2011-03-23 17:08:31.583 make fetch call
I 2011-03-23 17:08:31.585 sleep for 4.0
I 2011-03-23 17:08:35.585 wait
I 2011-03-23 17:08:35.663 get_result
I 2011-03-23 17:08:35.663 return
I 2011-03-23 17:08:35.669 Saved; key: __appstats__:011500, part: 48 bytes, full: 4351 bytes, overhead: 0.000 + 0.006; link: http://<myapp>.appspot.com/_ah/stats/details?tim
2011-03-23 17:08:35.636 /hereiam 404 9ms 0cpu_ms 0kb AppEngine-Google; (+http://code.google.com/appengine; appid: s~<myapp>),gzip(gfe)

异步调度。

E 2011-03-23 17:08:35.632 404: Not Found Traceback (most recent call last): File "distlib/tipfy/__init__.py", line 430, in wsgi_app rv = self.dispatch(request) File "di
I 2011-03-23 17:08:35.634 Saved; key: __appstats__:015600, part: 27 bytes, full: 836 bytes, overhead: 0.000 + 0.002; link: http://<myapp>.appspot.com/_ah/stats/details?time

使用memcache RPC等待开始工作。

class AsyncHandler(RequestHandler):

    def get(self, sleepy=0.0):
        _log.info("create rpc")
        rpc = create_rpc()
        _log.info("make fetch call")
        make_fetch_call(rpc, url="http://<myapp>.appspot.com/hereiam")
        _log.info("sleep for %r", sleepy)
        sleep(sleepy)
        _log.info("memcache's wait")
        memcache.get('foo')
        _log.info("sleep again")
        sleep(sleepy)
        _log.info("return")
        return "<BODY><H1>Holla %r</H1></BODY>" % sleepy

Appengine Prod Log:

2011-03-23 17:27:47.389 /delay/2.0 200 4018ms 23cpu_ms 0kb Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151 Safari/534.16,gzip(gfe)
I 2011-03-23 17:27:43.374 create rpc
I 2011-03-23 17:27:43.375 make fetch call
I 2011-03-23 17:27:43.377 sleep for 2.0
I 2011-03-23 17:27:45.378 memcache's wait
I 2011-03-23 17:27:45.382 sleep again
I 2011-03-23 17:27:47.382 return
W 2011-03-23 17:27:47.383 Found 1 RPC request(s) without matching response (presumably due to timeouts or other errors)
I 2011-03-23 17:27:47.386 Saved; key: __appstats__:063300, part: 66 bytes, full: 6869 bytes, overhead: 0.000 + 0.003; link: http://<myapp>.appspot.com/_ah/stats/details?tim
2011-03-23 17:27:45.452 /hereiam 404 10ms 0cpu_ms 0kb AppEngine-Google; (+http://code.google.com/appengine; appid: s~<myapp>),gzip(gfe)

当memcache.get调用wait()

时调度异步url fetch
E 2011-03-23 17:27:45.446 404: Not Found Traceback (most recent call last): File "distlib/tipfy/__init__.py", line 430, in wsgi_app rv = self.dispatch(request) File "di
I 2011-03-23 17:27:45.449 Saved; key: __appstats__:065400, part: 27 bytes, full: 835 bytes, overhead: 0.000 + 0.002; link: http://<myapp>.appspot.com/_ah/stats/details?time