zeroRPC:发送响应后继续运行进程

时间:2015-06-23 21:02:36

标签: python tcp messaging zerorpc

我使用Python 2.7和zeroRPC来建立客户端和服务器进行通信。我希望客户端向服务器发送请求,我希望服务器发送响应以确认它已收到请求。但后来我希望服务器对该请求执行一些繁重的计算。这些计算将花费数小时而不会产生任何响应,因此客户不应该等待;客户端 - 服务器连接应在服务器确认收到请求后立即终止。我怎么能这样做?

这是我现在所拥有的(简化)。

服务器代码:

impor time
import zerorpc

class HelloRPC(object):
    def hey(self, name):
        print 'Hey, %s' % name # just so I can check that the request was received
        # send response confirming that request was received
        # terminate connection
        time.sleep(100000000000000) # some heavy computations

s = zerorpc.Server(HelloRPC())
s.bind('tcp://0.0.0.0:4242')
s.run()

客户代码:

import zerorpc

c = zerorpc.Client()
c.connect('tcp://MyServerName:4242')
c.hey('macarena')

它不起作用:我得到zerorpc.exceptions.LostRemote: Lost remote after 10s heartbeat。我知道我可以使用heartbeat参数无限期地建立连接,但正如我所说,计算将花费数小时而不会产生任何响应,所以我不认为我应该保持连接活着。< / p>

我已经阅读了关于gevent但我无法弄清楚如何将它用于此目的(它甚至是适合这项工作的工具吗?)。我应该使用Python的多处理程序包来生成子进程或类似的东西吗?怎么会这样做呢?

1 个答案:

答案 0 :(得分:5)

这是因为服务器没有发回心跳。主线程在一些非gevent-cooperative循环中被阻塞大约10秒(默认心跳频率的2倍)。

Gevent合作运行你的协同程序(greenlets)。如果一个协同程序永远不会回到gevent循环,它会阻止循环。

也许你的任务是CPU限制的,在这种情况下,你试图保持合作,同时长时间在CPU上搅拌位。有两种方法可以使用zerorpc(和gevent)运行CPU绑定代码:

  • 定期回到gevent IOLoop(gevent.sleep(0))。由于默认心跳为5秒,并且在心跳频率的两倍之后假设断开连接,因此您必须大约每5秒产生一次是安全的。

  • 更通用的解决方案是在自己的进程中运行CPU绑定代码(例如,每个CPU一个进程):

    • 一个进程将是您的服务API,可供网络访问(启用了检测信号的zerorpc.Server)。这个过程永远不会阻止,并且尊重协作调度。
    • 您可以使用CPU进行密集计算。
    • 您的服务API和您的CPU绑定进程与zerorpc通信,但这次关闭了心跳(可能是一个非常长的超时值)。
    • 在服务API过程中,您可以控制自己对CPU绑定进程的争用。