tornado:异步connect

tornado:异步connect_第1张图片
在tornado中,当用iostream.connect函数进行异步connect的时候,如果第一次调用connect不成功,那么我们期待它引发异常_ERRNO_INPROGRESS
或者_ERRNO_WOULDBLOCK,标记当前正在进行connecting(self._connectiong=True),将connect传入的参数callback,保存到类的成员变量_connect_callback,或者将self._connect_future被初始化,并且将当前socket的fd的  写事件注册到ioloop中。
tornado:异步connect_第2张图片
在  _add_io_state函数中,可以看到无论是read,write,error等事件都交给 self._handle_events统一处理
tornado:异步connect_第3张图片

而在_handle_events函数中,首先判断当前是否正在进行连接(self._connectiong),如果正在进行连接,那么表明  异步connect
和服务器端已经连接成功,那么在self._handle_connect中,之前保留的self._connect_future将会被set_result,或者self._connect_callback会被调用。
tornado:异步connect_第4张图片
tornado异步connect的过程就如上面介绍。
注意一点是当一个connectiong socket最终connected,所触发的是 write事件。

最后提出一个问题,当socket正在进行connecting的时候,这个时候也同时开始异步write,tornado在内部中如何处理,确保先connected,再进行write?

我们先看看iostream 中的write函数是如何实现的。
tornado:异步connect_第5张图片
其实所谓的异步write,是先将data写到iostream内部的写缓冲区(self._write_buffer),在ioLoop中,如果检测到socket触发了write事件,那么就在handler中将self._write_buffer中数据,写到socket缓冲区,通过网络发送(_handle_write函数)。

可以看到write函数中有判断(if not self._connectiong)。意思很简单。如果当前socket连接已经建立,也就是不处于(_connecting)状态,那么调用self._handle_write()将iostream写缓冲区中的数据发送。如果发送完了后,_write_buffer中还有数据,那么将socket的写事件注册到ioLoop中,在handler中继续发送数据。

但是如果当前正在connecting,write函数将数据写到write buffer中,没有做实际的事情,直接返回一个self._write_future对象。那么tornado如何确保连接成功后再发送数据。

​回头看看_handle_event函数,就会明白了。
由于异步connect和异步write,所触发事件都是write事件,那么在_handle_event函数,最终也会调用_handle_write,把数据发送,
if(event & self.io_loop.Write)为真。

tornado中,专门对这个问题有一个测试例子。

tornado:异步connect_第6张图片

你可能感兴趣的:(tornado)