Решил, что сегодня я буду пинать шины Tornado 2.0, но, похоже, для меня это коснулся ASyncHTTPClient. Ничто в примечаниях к выпуску для 2.0 не указывает на какие-либо реальные изменения, необходимые для использования ASyncHTTPClient:
[EDIT: сделал код более явным, самодостаточным примером]
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 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()
при использовании ASINcHTTPClient по умолчанию (non-curl) я получаю следующее:
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-адреса (если callback
является URL-адресом).
2.0 переключил реализацию ASyncHTTPClient на simple_httpclient (из curl_httpclient), но я не думаю, что приведенный пример работал бы в Tornado 1.2.
http://
?