扭曲的 deferToThread tcp 连接

twisted deferToThread tcp connections

我是 twisted 的新手,尝试编写我的第一个应用程序,但实际上我遇到了这个问题:

我有一个主线程将一堆模块加载到 运行,每个模块都位于远程服务器上并可通过 tcp 连接使用,这里是模块 运行代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import struct

from twisted.internet import endpoints
from twisted.internet.defer import inlineCallbacks
from twisted.spread import pb
from txapp.core import get_modules

from txmod.spread import EnvelopeSpreadReceiver


@inlineCallbacks
def listen(reactor):
    modules = yield get_modules()

    for mod in modules:
        endpoint = endpoints.serverFromString(reactor, 'tcp:%d:%s' %
                                              (int(mod.get('module_server_port') or 0),
                                               socket.inet_ntoa(struct.pack('!L', mod.get('module_server_ipaddr'))),))
        endpoint.listen(pb.PBServerFactory(EnvelopeSpreadReceiver()))
        print 'PBServerFactory starting on %s:%d for module %s' % (
            socket.inet_ntoa(struct.pack('!L', mod.get('module_server_ipaddr'))),
            int(mod.get('module_server_port')),
            mod.get('module_name'))


def main():
    from twisted.internet import reactor
    listen(reactor)
    reactor.run()


if __name__ == "__main__":
    main()

一个给定的服务器可能运行多个模块在不同的端口,但通常是:1台服务器,1个模块

运行 应用程序将尝试连接到每个模块的主服务器,运行 代码并期望结果(成功与否)。

我正在努力研究如何使这段代码成为非阻塞的:如果服务器无法响应,tcp 连接可能会挂起,所以我应该将每个模块的 tcp 连接放在一个单独的线程上 deferToThread 吗?

主应用程序每天将处理数百万个请求,因此它应该是完全非阻塞的。

这是正确的处理方式吗?有人可以为我指明如何实现这一目标的正确方向吗?

Twisted 的 event-loop API 不是线程安全的,如 Twisted's threading documentation 所述。这意味着您绝对不能调用 deferToThread 来处理连接;如果你尝试它会崩溃。

等待的 TCP 连接不会导致事件循环卡住;用于向连接发送和接收数据的 API 已经 non-blocking。所以我认为你在这里没有问题要解决,它已经为你解决了。