annotate src/capnproto-0.6.0/doc/_posts/2013-12-12-capnproto-0.4-time-travel.md @ 152:ffc6df9c760c

List of exclusions from the appimage repo
author Chris Cannam <cannam@all-day-breakfast.com>
date Thu, 28 Jun 2018 15:29:59 +0100
parents 45360b968bf4
children
rev   line source
cannam@147 1 ---
cannam@147 2 layout: post
cannam@147 3 title: "Cap'n Proto v0.4: Time Traveling RPC"
cannam@147 4 author: kentonv
cannam@147 5 ---
cannam@147 6
cannam@147 7 Well, [Hofstadter](http://en.wikipedia.org/wiki/Hofstadter's_law) kicked in and this release took
cannam@147 8 way too long. But, after three long months, I'm happy to announce:
cannam@147 9
cannam@147 10 ### Time-Traveling RPC _(Promise Pipelining)_
cannam@147 11
cannam@147 12 <img src='{{ site.baseurl }}images/time-travel.png' style='max-width:639px'>
cannam@147 13
cannam@147 14 v0.4 finally introduces the long-promised [RPC system]({{ site.baseurl }}rpc.html). Traditionally,
cannam@147 15 RPC is plagued by the fact that networks have latency, and pretending that latency doesn't exist by
cannam@147 16 hiding it behind what looks like a normal function call only makes the problem worse.
cannam@147 17 Cap'n Proto has a simple solution to this problem: send call results _back in time_, so they
cannam@147 18 arrive at the client at the point in time when the call was originally made!
cannam@147 19
cannam@147 20 Curious how Cap'n Proto bypasses the laws of physics?
cannam@147 21 [Check out the docs!]({{ site.baseurl }}rpc.html)
cannam@147 22
cannam@147 23 _UPDATE: There has been some confusion about what I'm claiming. I am NOT saying that using
cannam@147 24 promises alone (i.e. being asynchronous) constitutes "time travel". Cap'n Proto implements a
cannam@147 25 technique called Promise Pipelining which allows a new request to be formed based on the content
cannam@147 26 of a previous result (in part or in whole) before that previous result is returned. Notice in the
cannam@147 27 diagram that the result of foo() is being passed to bar(). Please
cannam@147 28 [see the docs]({{ site.baseurl }}rpc.html) or
cannam@147 29 [check out the calculator example](https://github.com/kentonv/capnproto/blob/master/c++/samples)
cannam@147 30 for more._
cannam@147 31
cannam@147 32 ### Promises in C++
cannam@147 33
cannam@147 34 _UPDATE: More confusion. This section is **not** about pipelining ("time travel"). This section
cannam@147 35 is just talking about implementing a promise API in C++. Pipelining is another feature on top of
cannam@147 36 that. Please [see the RPC page]({{ site.baseurl }}rpc.html) if you want to know more about
cannam@147 37 pipelining._
cannam@147 38
cannam@147 39 If you do a lot of serious Javascript programming, you've probably heard of
cannam@147 40 [Promises/A+](http://promisesaplus.com/) and similar proposals. Cap'n Proto RPC introduces a
cannam@147 41 similar construct in C++. In fact, the API is nearly identical, and its semantics are nearly
cannam@147 42 identical. Compare with
cannam@147 43 [Domenic Denicola's Javascript example](http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/):
cannam@147 44
cannam@147 45 {% highlight c++ %}
cannam@147 46 // C++ version of Domenic's Javascript promises example.
cannam@147 47 getTweetsFor("domenic") // returns a promise
cannam@147 48 .then([](vector<Tweet> tweets) {
cannam@147 49 auto shortUrls = parseTweetsForUrls(tweets);
cannam@147 50 auto mostRecentShortUrl = shortUrls[0];
cannam@147 51 // expandUrlUsingTwitterApi returns a promise
cannam@147 52 return expandUrlUsingTwitterApi(mostRecentShortUrl);
cannam@147 53 })
cannam@147 54 .then(httpGet) // promise-returning function
cannam@147 55 .then(
cannam@147 56 [](string responseBody) {
cannam@147 57 cout << "Most recent link text:" << responseBody << endl;
cannam@147 58 },
cannam@147 59 [](kj::Exception&& error) {
cannam@147 60 cerr << "Error with the twitterverse:" << error << endl;
cannam@147 61 }
cannam@147 62 );
cannam@147 63 {% endhighlight %}
cannam@147 64
cannam@147 65 This is C++, but it is no more lines -- nor otherwise more complex -- than the equivalent
cannam@147 66 Javascript. We're doing several I/O operations, we're doing them asynchronously, and we don't
cannam@147 67 have a huge unreadable mess of callback functions. Promises are based on event loop concurrency,
cannam@147 68 which means you can perform concurrent operations with shared state without worrying about mutex
cannam@147 69 locking -- i.e., the Javascript model. (Of course, if you really want threads, you can run
cannam@147 70 multiple event loops in multiple threads and make inter-thread RPC calls between them.)
cannam@147 71
cannam@147 72 [More on C++ promises.]({{ site.baseurl }}cxxrpc.html#kj_concurrency_framework)
cannam@147 73
cannam@147 74 ### Python too
cannam@147 75
cannam@147 76 [Jason](https://github.com/jparyani) has been diligently keeping his
cannam@147 77 [Python bindings](http://jparyani.github.io/pycapnp/) up to date, so you can already use RPC there
cannam@147 78 as well. The Python interactive interpreter makes a great debugging tool for calling C++ servers.
cannam@147 79
cannam@147 80 ### Up Next
cannam@147 81
cannam@147 82 Cap'n Proto is far from done, but working on it in a bubble will not produce ideal results.
cannam@147 83 Starting after the holidays, I will be refocusing some of my time into an adjacent project which
cannam@147 84 will be a heavy user of Cap'n Proto. I hope this experience will help me discover first hand
cannam@147 85 the pain points in the current interface and keep development going in the right direction.
cannam@147 86
cannam@147 87 This does, however, mean that core Cap'n Proto development will slow somewhat (unless contributors
cannam@147 88 pick up the slack! ;) ). I am extremely excited about this next project, though, and I think you
cannam@147 89 will be too. Stay tuned!