You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
4.3 KiB
Markdown
90 lines
4.3 KiB
Markdown
---
|
|
layout: post
|
|
title: "Cap'n Proto v0.4: Time Traveling RPC"
|
|
author: kentonv
|
|
---
|
|
|
|
Well, [Hofstadter](http://en.wikipedia.org/wiki/Hofstadter's_law) kicked in and this release took
|
|
way too long. But, after three long months, I'm happy to announce:
|
|
|
|
### Time-Traveling RPC _(Promise Pipelining)_
|
|
|
|
<img src='{{ site.baseurl }}images/time-travel.png' style='max-width:639px'>
|
|
|
|
v0.4 finally introduces the long-promised [RPC system]({{ site.baseurl }}rpc.html). Traditionally,
|
|
RPC is plagued by the fact that networks have latency, and pretending that latency doesn't exist by
|
|
hiding it behind what looks like a normal function call only makes the problem worse.
|
|
Cap'n Proto has a simple solution to this problem: send call results _back in time_, so they
|
|
arrive at the client at the point in time when the call was originally made!
|
|
|
|
Curious how Cap'n Proto bypasses the laws of physics?
|
|
[Check out the docs!]({{ site.baseurl }}rpc.html)
|
|
|
|
_UPDATE: There has been some confusion about what I'm claiming. I am NOT saying that using
|
|
promises alone (i.e. being asynchronous) constitutes "time travel". Cap'n Proto implements a
|
|
technique called Promise Pipelining which allows a new request to be formed based on the content
|
|
of a previous result (in part or in whole) before that previous result is returned. Notice in the
|
|
diagram that the result of foo() is being passed to bar(). Please
|
|
[see the docs]({{ site.baseurl }}rpc.html) or
|
|
[check out the calculator example](https://github.com/kentonv/capnproto/blob/master/c++/samples)
|
|
for more._
|
|
|
|
### Promises in C++
|
|
|
|
_UPDATE: More confusion. This section is **not** about pipelining ("time travel"). This section
|
|
is just talking about implementing a promise API in C++. Pipelining is another feature on top of
|
|
that. Please [see the RPC page]({{ site.baseurl }}rpc.html) if you want to know more about
|
|
pipelining._
|
|
|
|
If you do a lot of serious JavaScript programming, you've probably heard of
|
|
[Promises/A+](http://promisesaplus.com/) and similar proposals. Cap'n Proto RPC introduces a
|
|
similar construct in C++. In fact, the API is nearly identical, and its semantics are nearly
|
|
identical. Compare with
|
|
[Domenic Denicola's JavaScript example](http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/):
|
|
|
|
{% highlight c++ %}
|
|
// C++ version of Domenic's JavaScript promises example.
|
|
getTweetsFor("domenic") // returns a promise
|
|
.then([](vector<Tweet> tweets) {
|
|
auto shortUrls = parseTweetsForUrls(tweets);
|
|
auto mostRecentShortUrl = shortUrls[0];
|
|
// expandUrlUsingTwitterApi returns a promise
|
|
return expandUrlUsingTwitterApi(mostRecentShortUrl);
|
|
})
|
|
.then(httpGet) // promise-returning function
|
|
.then(
|
|
[](string responseBody) {
|
|
cout << "Most recent link text:" << responseBody << endl;
|
|
},
|
|
[](kj::Exception&& error) {
|
|
cerr << "Error with the twitterverse:" << error << endl;
|
|
}
|
|
);
|
|
{% endhighlight %}
|
|
|
|
This is C++, but it is no more lines -- nor otherwise more complex -- than the equivalent
|
|
JavaScript. We're doing several I/O operations, we're doing them asynchronously, and we don't
|
|
have a huge unreadable mess of callback functions. Promises are based on event loop concurrency,
|
|
which means you can perform concurrent operations with shared state without worrying about mutex
|
|
locking -- i.e., the JavaScript model. (Of course, if you really want threads, you can run
|
|
multiple event loops in multiple threads and make inter-thread RPC calls between them.)
|
|
|
|
[More on C++ promises.]({{ site.baseurl }}cxxrpc.html#kj_concurrency_framework)
|
|
|
|
### Python too
|
|
|
|
[Jason](https://github.com/jparyani) has been diligently keeping his
|
|
[Python bindings](http://jparyani.github.io/pycapnp/) up to date, so you can already use RPC there
|
|
as well. The Python interactive interpreter makes a great debugging tool for calling C++ servers.
|
|
|
|
### Up Next
|
|
|
|
Cap'n Proto is far from done, but working on it in a bubble will not produce ideal results.
|
|
Starting after the holidays, I will be refocusing some of my time into an adjacent project which
|
|
will be a heavy user of Cap'n Proto. I hope this experience will help me discover first hand
|
|
the pain points in the current interface and keep development going in the right direction.
|
|
|
|
This does, however, mean that core Cap'n Proto development will slow somewhat (unless contributors
|
|
pick up the slack! ;) ). I am extremely excited about this next project, though, and I think you
|
|
will be too. Stay tuned!
|