twisted bug pb transport.write 高并发

一. twisted的bug
1.transport.write在线程执行的bug
a. 最开始是我用pb.callRemote方法,我把这个方法放在线程里面调用【callInThread, deferToThread】,
在高并发的时候,客户端总是没有响应, 后来发现是发送端根本就没有发送出消息,但是pb并没有断开,反向还是可以调用;
但是当把pb.callRemote放在【callFromThread】里面就没问题。
b. 于是我不用pb,我换成普通的linereciver的socket客户端,发现存在一样的问题,我把transport.write
放在【callInThread, deferToThread】调用,发现在高并发的时候,根本发送不出去消息【完全卡死】,我很困惑。
明白了为什么会出现上述a的情况,pb也是用的transport.write发送消息肯定的。
c. 后来把transport.write放在callFromThread【主线程】中执行,就没有任何问题,最多是慢点,阻塞,但不会卡死;
d. 最后无意中发现,self.transport.getHandle().sendall(data)可以随便在【callInThread, deferToThread,
callFromThread】里面执行,但是在高并发的时候会出现下面的bug:

引起这个bug的代码 :self.transport.getHandle().sendall(data)

########################################################################################
Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 525, in __bootstrap
self.__bootstrap_inner()
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
--- <exception caught here> ---
File "/home/yx/workspace/oldpython/server/virtualenv/local/lib/python2.7/site-packages/Twisted-13.2.0-py2.7-linux-i686.egg/twisted/python/threadpool.py", line 191, in _worker
result = context.call(ctx, function, *args, **kwargs)
File "/home/yx/workspace/oldpython/server/virtualenv/local/lib/python2.7/site-packages/Twisted-13.2.0-py2.7-linux-i686.egg/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/home/yx/workspace/oldpython/server/virtualenv/local/lib/python2.7/site-packages/Twisted-13.2.0-py2.7-linux-i686.egg/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
File "server.py", line 566, in msg_2001
client.send(result)
File "server.py", line 129, in send
self.send_i(data)
File "server.py", line 118, in send_i
self.transport.getHandle().sendall(data)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 11] Resource temporarily unavailable
################################################################################################
这个bug你可以try后,重新发送,可以解决上述所有问题
e. 所以目前有两中方案解决这个bug:
【1】. 将transport.write或者pb.callRemote放在 callFromThread执行【主线程】
【2】. 将transport.getHandle().sendall(data)放在【callInThread, deferToThread,callFromThread】里面执行时候,手动处理下bug即可
个人推荐第一种,第二种在你实在需要线程执行的时候可以用


分享到: 微信 更多