zerorpc uses gevent for cooperative asynchronous IO. You might want to look into how tornado, multiprocessing and gevent are playing all together.
For what I can tell in:
server = zerorpc.Server(FuncWrapper())
server.bind(server_address)
process = multiprocessing.Process(target=server.run)
process.start()
Line 1 and 2 are creating and binding a port on the current process. But at line 3 and 4, what I can guess happening is:
- fork is called, all threads in the process are lost in the fork
- any zeromq socket & context are dead now (no more thread). Good news is, the context can be destroyed, and a new one created (see http://lists.zeromq.org/pipermail/zeromq-dev/2014-January/024536.html).
- Now you have a port open on your local process, with an active zeromq socket, but nobody is reading from this socket (hence no reaction when you talk to it).
- On the other side, in the multiprocess's process, zerorpc is running, calling recv on the relics of the original zmq socket. Nothing will never come, zeromq is dead already.
Without testing, I can only guess that running zerorpc completely in the new process should work:
def ZeroRPC_Service():
server = zerorpc.Server(FuncWrapper())
server.bind(server_address)
server.run()
process = multiprocessing.Process(target=ZeroRPC_Service)
process.start()
Then via some Manager object or other Shared memory services offered by multiprocess, you could make the zerorpc server in the new process access and share data with your local process.
On a side note, if what you are trying to do, is call server.run() without blocking, if you were using only gevent, I would tell you to simply run it in its own coroutine:
server = zerorpc.Server(FuncWrapper())
server.bind(server_address)
server_coro = gevent.spawn(server.run)
Maybe you can call server.run
from a tornado coroutine/asyunc function directly. Maybe there is a way to integrate gevent and tornado (like this link suggest: https://bmmh.wordpress.com/2012/10/07/tornado-and-gevent/), I don't know enough to help you at this point.