ZeroRPC

So good you'll forget the R

ZeroRPC is a light-weight, reliable and language-agnostic library for distributed communication between server-side processes. It builds on top of ZeroMQ and MessagePack. Support for streamed responses - similar to python generators - makes ZeroRPC more than a typical RPC engine. Built-in heartbeats and timeouts detect and recover from failed requests. Introspective capabilities, first-class exceptions and the command-line utility make debugging easy. ZeroRPC powers the infrastructure behind dotCloud.

Get The Source

Python Node.js

Installation

pip install zerorpc
npm install zerorpc

Hello World

Server

import zerorpc

class HelloRPC(object):
def hello(self, name):
return "Hello, %s" % name

s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()
var zerorpc = require("zerorpc");

var server = new zerorpc.Server({
hello: function(name, reply) {
reply("Hello, " + name);
}
});

server.bind("tcp://0.0.0.0:4242");

Client

import zerorpc

c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")
print c.hello("RPC")
var zerorpc = require("zerorpc");

var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");

client.invoke("hello", "RPC", function(error, res, more) {
console.log(res);
});
zerorpc tcp://127.0.0.1:4242 hello RPC

Streaming Responses

Server

import zerorpc

class StreamingRPC(object):
@zerorpc.stream
def streaming_range(self, fr, to, step):
return xrange(fr, to, step)

s = zerorpc.Server(StreamingRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()
var zerorpc = require("zerorpc");

var server = new zerorpc.Server({
streaming_range: function(from, to, step, reply) {
for(var i=from; i<to; i+=step) {
reply(i, i + step < to);
}
}
});

server.bind("tcp://0.0.0.0:4242");

Client

import zerorpc

c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")

for item in c.streaming_range(10, 20, 2):
print item
var zerorpc = require("zerorpc");

var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");

client.invoke("streaming_range", 10, 20, 2, function(error, res, more) {
console.log(res);
});
zerorpc tcp://127.0.0.1:4242 streaming_range 10 20 2 --json

First Class Exceptions

Server

import zerorpc

class ExceptionalRPC(object):
def bad(self):
raise Exception(":P")

s = zerorpc.Server(ExceptionalRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()
var zerorpc = require("zerorpc");

var server = new zerorpc.Server({
bad: function(reply) {
//The first parameter to reply() is for errors
//Also possible:
// reply(new Error(":P"), null, false);
reply(":P", null, false);
}
});

server.bind("tcp://0.0.0.0:4242");

Client

import zerorpc

c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")

try:
c.bad()
except Exception, e:
print "An error occurred: %s" % e
var zerorpc = require("zerorpc");

var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");

client.invoke("bad", function(error, res, more) {
console.error("An error occurred:", error);
});
zerorpc tcp://127.0.0.1:4242 bad