Open wamanuz opened 10 years ago
I recommend using CurlAsyncHTTPClient which is much, much faster than the default async HTTP client in Tornado. In the light server we do the following:
try:
import tornado.curl_httpclient
tornado.httpclient.AsyncHTTPClient.configure(tornado.curl_httpclient.CurlAsyncHTTPClient)
except ImportError:
logging.warning("Couldn't import CurlAsyncHTTPClient, reverting to slow default implementation")
Afterwards the HTTP client can be instantiated by running tornado.httpclient.AsyncHTTPClient()
as usual.
AsyncHTTPClient.fetch returns a Future. If you want to wait for the Future to return in a pseudo-synchronous manner, you can use coroutines:
@tornado.gen.coroutine
def func():
future = asyncclient.fetch(URL)
response = yield future
Upon yielding the function will suspend execution, and tornado.gen.coroutine will intercept the yielded Future. When the Future completes tornado.gen.coroutine will return control to the suspended function, and will send the Future's result as the result of the yield expression.
Any function decorated by tornado.gen.coroutine will in turn return a Future that completes when the function completes, with the result of the Future being the value returned by the function using the return
statement.
Alternatively, the IOLoop object provides an add_future method that takes a Future and a callback that will be called with the Future as an argument when the Future completes. In addition, AsyncHTTPClient.fetch has a callback argument.
I don't have time to work on this anymore today (I'm travelling south over the extended weekend tomorrow), but I'll summarize what I've figured about "async-ing" the lamp-server connection.
send_lamp_multi
and send_lamp_all
should need any changes (yes, I know that the API is kinda ugly).http.client.HTTPClient
class, which means the connect_lampserer
could take care of most of the configuration-related things, and other modules just request whatever path they need. As I understand the docs on tornado.httpclient, we would need to pass all of these options to every request separately (or create some kind of wrapper class/object/thing that encapsulates it), which is a bit annoying.Anyway, anyone is free to pick this up if they want to. The above links should make it clear what needs to be changed, I just don't have time to implement and test it today.
Not that high priority