Cap'n Proto 0.4: Time-traveling RPC
kentonv.github.io
kentonv.github.io
Yes, total network failure is still an issue. Typically, applications need to solve this by catching a network exception somewhere high up the stack and then starting over with a fresh connection.
There's certainly an argument to be made for using a different abstraction, e.g. those provided by ZeroMQ, that can handle fault tolerance more transparently. But, it all depends on your use case. A lot of things just don't fit into stateless models -- particularly real-time collaborative types of things. (ZeroMQ pairs nicely with Cap'n Proto serialization, BTW, if that's the route you prefer.)
ie: (in Scala, my C++-fu is weak)
getTweetsFor("domenic") // returns a future
.map(parseTweetsForUrls)
.map(_.head)
.flatMap(expandUrlUsingTwitterApi)
.flatMap(httpGet)then() will actually accept functions returning regular values, too. A big difference between then() and map() is that then() accepts an optional second parameter for exception handling. In any case, I used "then" because that's what Javascript promises use.
One easy way to think of Monads is that they are like black holes - you are free to put something into it but can't ever pull it back out. Instead, all you are allowed to do is chain them together (with bind). So to transform the value inside a monad, you must write a function that takes that value and returns the transformed value wrapped in the same type of monad (Promise in this case). The monadic machinery in 'bind' will take care of pushing the result from one Promise into the transform function.
bind :: m a -> (a -> m b) -> m b
return :: a -> m a
These allow us to define
then :: m a -> (a -> b) -> m b
then x f = bind x (return . f)
i.e. it's trivial to lift a regular function into the monad.
A typical RPC in a C++/Java/C# language looks something like this:
var client = EchoClient::Connect("corba://example.com:9000");
var request = new EchoRequest();
request.set_message("hello world!")
var options = new RpcOptions();
options.set_timeout_milliseconds(5000);
Future<EchoResponse> futureResponse = client.Echo(request, options);
EchoResponse response = futureResponse.Wait();
According to the article this is going "back in time", but that's completely silly -- the response is being returned at the point of the Wait() call, which blocks until the server has finished RPC processing.And of course, languages with proper thread support (e.g. Haskell) don't need to bother with futures at all, because it's easy to spawn a new thread for each request instead of blocking some central main thread.
And it's fairly easy to provide syntactic sugar over this to provide closure-based control flow
Sorry, but did you read the docs?
I want to know how the Cap'n'proto design discussed in the post is significantly different from this standard RPC model.
That seems like it'd only be useful in very specific circumstances; you'd need RPC methods with the same type for request and response, and it only works if you're using the same backend for each call (e.g. you can't have load balancing of separate calls).
http://kentonv.github.io/capnproto/rpc.html
Also, it is not the case that the new RPC's input type has to match the old one's output. You can take just one object embedded in the old response and use it in the new request.
Please do look at the examples.
This is all described in detail in the docs.
This model is possible because the Haskell runtime decouples threads from the OS's process-with-shared-address-space abstraction, so running a few million threads is a reasonable design choice. Users of Erlang will find the Haskell threading model very familiar, with the exception that Haskell also provides ways to pass around mutable state (e.g. you could pass a pointer through a channel).
It is possible to implement something like a Future monad if you really want to, based on MVar, but cheap threads make it unnecessary.
Anyone know what I did wrong?
Sigh.
http://packages.ubuntu.com/source/trusty/unity-scopes-api
There is also the OSX text editor, TextMate, which uses Cap'n Proto for some kind of cache file.
Sadly, most users don't actually tell me about their experiences, but given the number of people asking questions and filing bugs, I suspect there are many more.
The biggest thing holding people back is lack of MSVC support.