【问题标题】:Tornado's AsyncHTTPClient no longer works after upgrade to 2.0 from 1.2Tornado 的 AsyncHTTPClient 从 1.2 升级到 2.0 后不再工作
【发布时间】:2011-09-24 19:01:48
【问题描述】:

我决定今晚开始使用 Tornado 2.0,但它似乎为我在 ASyncHTTPClient 上做了一些工作。 2.0 的发行说明中没有任何内容表明需要对我使用 ASyncHTTPClient 的方式进行任何真正的更改:

[编辑:使代码更像是一个明确的、自包含的示例]

import time
import threading
import functools

import tornado.ioloop
import tornado.web
from tornado.httpclient import *

class MainHandler(tornado.web.RequestHandler):

    def perform_task(self,finish_function):
      http_client = AsyncHTTPClient()
      tornado.ioloop.IOLoop.instance().add_callback(finish_function)
      # do something
      for i in range(0,10):
        print i
        time.sleep(1)
      request = tornado.httpclient.HTTPRequest("http://10.0.1.5:8888",method="POST",body="finished countdown")
      resp = http_client.fetch(request, self.handle_request)
      return

    def join_callback(self):
      # finish the request, also returns control back to ioloop's thread.
      self.finish()

    def handle_request(self, response):
      if response.error:
          print "Error:", response.error
      else:
          print response.body

    @tornado.web.asynchronous
    def get(self):
        self.write("Kicking off.")
        a_partial = functools.partial(self.perform_task,self.join_callback)
        self.thread = threading.Thread(target=a_partial)
        self.thread.start()
        self.write("\n<br/>Done in here, out of my hands now.")

    # just so this example has something to post to
    @tornado.web.asynchronous
    def post(self):
        self.write("POSTED: %s" % (self.request.body))

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

当使用默认(非卷曲)ASyncHTTPClient 时,我得到以下信息:

Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/tornado/simple_httpclient.py", line 259, in cleanup
    yield
  File "/usr/local/lib/python2.6/dist-packages/tornado/simple_httpclient.py", line 186, in __init__
    functools.partial(self._on_connect, parsed))
  File "/usr/local/lib/python2.6/dist-packages/tornado/iostream.py", line 120, in connect
    self.socket.connect(address)
AttributeError: 'NoneType' object has no attribute 'connect'

如果我添加: tornado.httpclient.AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")

要指定我想使用 PyCurl,我得到以下异常:

   Traceback (most recent call last):
      File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
        self.run()
      File "/usr/lib/python2.6/threading.py", line 484, in run
        self.__target(*self.__args, **self.__kwargs)
      File "migratotron.py", line 46, in perform_migration
        hc.fetch(request,success)
      File "/usr/local/lib/python2.6/dist-packages/tornado/curl_httpclient.py", line 81, in fetch
        self._process_queue()
      File "/usr/local/lib/python2.6/dist-packages/tornado/curl_httpclient.py", line 210, in _process_queue
        curl.info["headers"])
      File "/usr/local/lib/python2.6/dist-packages/tornado/curl_httpclient.py", line 276, in _curl_setup_request
        curl.setopt(pycurl.URL, request.url

)
TypeError: invalid arguments to setopt

我正在做的唯一不寻常的事情是调用这是我创建的另一个线程来进行一些后台处理,它使用 add_callback 将控制权返回给 ioloop 线程。有没有人在 2.0 或类似的版本中看到过这个?

【问题讨论】:

  • 注意:我的代码中的“回调”是一个 URL,而不是一个函数。

标签: python asynchronous tornado pycurl


【解决方案1】:

这些错误消息有点神秘,但在这两种情况下,我认为它们是由于您的请求没有 URL(除非 callback 是 URL)。

2.0 将 ASyncHTTPClient 实现切换为 simple_httpclient(来自 curl_httpclient),但我认为给出的示例也不适用于 Tornado 1.2。

【讨论】:

  • 这是一个 URL,我打算更改代码以使其更明显地发布,但忘记了。感谢您了解。
  • 对,但我很确定你得到的错误意味着它没有被正确解析。是否有前导http://
最近更新 更多