Open loadlj opened 8 years ago
Blocking and non-blocking HTTP client implementations using pycurl Blocking client指的是HTTPClient,non-blocking HTTP client指的是AsyncHTTPClient
Blocking and non-blocking HTTP client implementations using pycurl
__init__
调用_curl_create初始化self._curl。
def _curl_create(max_simultaneous_connections=None): curl = pycurl.Curl() if logging.getLogger().isEnabledFor(logging.DEBUG): curl.setopt(pycurl.VERBOSE, 1) curl.setopt(pycurl.DEBUGFUNCTION, _curl_debug) curl.setopt(pycurl.MAXCONNECTS, max_simultaneous_connections or 5) return curl
fetch
将参数中的requets和kwargs封装成一个HTTPRequest对象,调用_curl_setup_request设置self.curl各种参数。将self.curl返回的buffer和反回的url以及请求信息封装成一个HTTPResponse对象.
__new__
这里初始化使用的是new而不是init, 可参照difference。还有_ASYNC_CLIENTS需要注意,源代码中的解释是There is one client per IOLoop since they share curl instances
There is one client per IOLoop since they share curl instances
_ASYNC_CLIENTS = weakref.WeakKeyDictionary() cls._ASYNC_CLIENTS[io_loop] = instance
这段代码确保当AsyncHTTPClient被销毁的时候,ioloop也随之被销毁, 且每个AsyncHTTPClient只对应一个IOLoop。
AsyncHTTPClient
接受一个httprequest和一个callback, 将request封装成一个HTTPRequest,将request和相应的callback存到self.request中。调用self._add_perform_callback()
httprequest
callback
request
HTTPRequest
self.request
self._add_perform_callback()
_handle_socket
由libcurl回调更改文件描述符状态。声明一个event_map, 将libculr文件描述符封装成ioloop文件描素福状态,包括pycurl.POLL_IN,pycurl.POLL_OUT等。 将封装好的事件传入到ioloop中,设置handler为ioloop_event。
libcurl
event_map
libculr
ioloop
pycurl.POLL_IN
pycurl.POLL_OUT
handler
ioloop_event
_handle_events
由ioloop回调更改文件描述符状态, 调用socket_action接口,调用self._finish_pending_requests。
socket_action
self._finish_pending_requests
_finish_pending_requests
调用info_read取出curl返回的信息。
info_read
curl
num_q, ok_list, err_list = self._multi.info_read
调用self._finish处理curl, 调用_process_queue。
self._finish
_process_queue
将self._free_list中的curl对象取出来,取出self._requests中的request和callback构造curl对象,将其加入到self._multi中。
self._free_list
self._requests
self._multi
_finish
读取curl的info,封装一个HTTPResponse对象,调用info中的callback。
HTTPResponse
info
from tornado import ioloop, httpclient def handle_request(response): if response.error: print "Error:", response.error else: print response.body ioloop.IOLoop.instance().stop() http_client = httpclient.AsyncHTTPClient2() http_client.fetch("http://www.baidu.com", handle_request) ioloop.IOLoop.instance().start()
HTTPClient
Blocking and non-blocking HTTP client implementations using pycurl
Blocking client指的是HTTPClient,non-blocking HTTP client指的是AsyncHTTPClientHTTPClient
函数说明
__init__
调用_curl_create初始化self._curl。
fetch
将参数中的requets和kwargs封装成一个HTTPRequest对象,调用_curl_setup_request设置self.curl各种参数。将self.curl返回的buffer和反回的url以及请求信息封装成一个HTTPResponse对象.
AsyncHTTPClient
函数说明
__new__
这里初始化使用的是new而不是init, 可参照difference。还有_ASYNC_CLIENTS需要注意,源代码中的解释是
There is one client per IOLoop since they share curl instances
这段代码确保当
AsyncHTTPClient
被销毁的时候,ioloop也随之被销毁, 且每个AsyncHTTPClient
只对应一个IOLoop。fetch
接受一个
httprequest
和一个callback
, 将request
封装成一个HTTPRequest
,将request
和相应的callback
存到self.request
中。调用self._add_perform_callback()
_handle_socket
由
libcurl
回调更改文件描述符状态。声明一个event_map
, 将libculr
文件描述符封装成ioloop
文件描素福状态,包括pycurl.POLL_IN
,pycurl.POLL_OUT
等。 将封装好的事件传入到ioloop
中,设置handler
为ioloop_event
。_handle_events
由
ioloop
回调更改文件描述符状态, 调用socket_action
接口,调用self._finish_pending_requests
。_finish_pending_requests
调用
info_read
取出curl
返回的信息。调用
self._finish
处理curl
, 调用_process_queue
。_process_queue
将
self._free_list
中的curl
对象取出来,取出self._requests
中的request
和callback
构造curl
对象,将其加入到self._multi
中。_finish
读取
curl
的info,封装一个HTTPResponse
对象,调用info
中的callback
。通过代码分析流程图