Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The documentation is pretty sparse, a few questions:

- How does it handle concurrency? Is each procedure run in a Python thread? Process? Gevent thread?

- How does it handle faults and recovery?

- Do you differentiate errors on the RPC layer with that on the procedure layer? For example, what if the RPC call I do does an RPC call that times out?

On a philosophical note, I'm not sure more RPC layers are what the world needs. The transparency a library like this gives you is really a big lie unless you are willing to accept that any call can now be an RPC one. Otherwise it greatly affects the correctness of your program (method M can now fail with some network failure).

That being said, good work!



ZeroRPC uses Gevent for concurrency

Faults are handled differently depending on whether they are ZeroRPC-layer errors or application errors. To maintain the integrity of the connection itself, there is a heartbeat system independent of any given request. There is also an optional timeout that can be set for a given call's response. Application-level errors are propagated as "RemoteError" exceptions in the python interface. In order to collect more info about remote errors, there is also support for ZeroRPC[0] in Raven[1], the Sentry[2] client (Disqus' error logging system). In any failure case, both sides of the connection are notified and given an opportunity to clean up after themselves.

As to the philosophical concerns, I do agree on some level: RPC in general (and ZeroRPC in particular) are powerful weapons that need to be treated with care. That being said, there are a number of cases that are greatly simplified by the higher-level abstractions and more-robust error handling ZeroRPC provides.

------

[0]: http://raven.readthedocs.org/en/latest/config/zerorpc.html [1]: https://github.com/dcramer/raven [2]: https://github.com/dcramer/sentry


Thanks for the response!

> That being said, there are a number of cases that are greatly simplified by the higher-level abstractions and more-robust error handling ZeroRPC provides.

IMO, c.call(hello, "foo", "bar') would be better than c.hello("foo", "bar"). I think the latter gives too much of an illusion of local call.


You can use the alternative syntax: c('hello', 'foo', 'bar')

Usually, "c" will be called "logger_service" or "metrics_service", thus reminding you that you are talking to a remote service, but its obviously just a convention...

Yes I know, people dont like convention, ee had cases when this illusion of a local call leaded us to do bad shit, this is true.

I think its the trade-off of any abstraction. More power under your fingers-tip mean easier use for good... or bad.


Thanks for the detailed criticism and the kind words.

All procedures are run in their own gevent thread.

Yes, we differentiate errors on the RPC layer - there is a builtin heartbeat system so timeouts can be detected even when the procedure returns an infinite stream (think logs or system metrics). There is no built-in retry mechanism.

On the philosophy question: we discourage "pretending" that a call is local. That lead to the demise of original rpc and as you point out leads to weak systems. It remains the job of the developer to be aware of the network boundary and design accordingly.


> we discourage "pretending" that a call is local

Interesting, because it seems the opposite to me. The example client code makes an RPC call look exactly like a regular Python call. If you believe (which I do) that the syntax of something implies semantics of that something, this would mean you are trying to tell people an RPC call is the same as a local call.

> we differentiate errors on the RPC layer

What does an error look like if my RPC call times out? What does it look like if my RPC does an RPC call that times out?

The website says: "Built-in heartbeats and timeouts detect and recover from failed requests.", what does the 'and recover' part mean?


Syntactically ZeroRPC calls look mostly the same as local calls, but semantically we don't hide erroneous states like you might expect a typically opaque RPC layer to do.

If an RPC call times out, you get a special exception that you can check against. Same with heartbeat failures.

"Recover" might be bad copy; what we mean is that ZeroRPC cleans up pending results. It is up to you to figure out what to do to fully recover. You have to develop with this in mind, but the trade-off is that failures are not hidden from you, and you have full flexibility in deciding what to do in failed states.


My point is that syntax implies semantics. c.hello(..) implies a local call and the semantics that go with it. But the semantics are actually different, which is bad.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: