<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title>Java to the Limit</title>
    
    <link rel="alternate" type="text/html" href="http://www.javalimit.com/" />
    <id>tag:typepad.com,2003:weblog-507222</id>
    <updated>2013-05-21T16:22:09+02:00</updated>
    <subtitle>Knowing your wisdom's insufficience is yet a kind of omniscience</subtitle>
    <generator uri="http://www.typepad.com/">TypePad</generator>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/javalimit" /><feedburner:info uri="javalimit" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
        <title>How Could it go so Bad?</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/2V10qeJ8LY4/how-could-it-go-so-bad.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2013/05/how-could-it-go-so-bad.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e2019102609158970c</id>
        <published>2013-05-21T16:22:09+02:00</published>
        <updated>2013-05-21T16:22:09+02:00</updated>
        <summary>This past weekend I’ve been reading Roubini and Mihm’s [Crisis Economics](http://www.amazon.com/gp/product/B00B9ZHWK6/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B00B9ZHWK6&amp;linkCode=as2&amp;tag=krekrasblo-20), a worthwhile read if you’d like to understand *what went wrong*. ![Crisis Economics](http://cache0.bdcdn.net/assets/images/book/medium/9780/1410/9780141045931.jpg) I’m “just an ordinary guy” when it comes to international-scale economics; and like most people probably...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.javalimit.com/"><div xmlns="http://www.w3.org/1999/xhtml"><p>This past weekend I’ve been reading Roubini and Mihm’s <a href="http://www.amazon.com/gp/product/B00B9ZHWK6/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B00B9ZHWK6&amp;linkCode=as2&amp;tag=krekrasblo-20">Crisis Economics</a>, a worthwhile read if you’d like to understand <em>what went wrong</em>.</p>

<p><img src="http://cache0.bdcdn.net/assets/images/book/medium/9780/1410/9780141045931.jpg" alt="Crisis Economics" /></p>

<p>I’m “just an ordinary guy” when it comes to international-scale economics; and like most people probably — I’ve been baffled by what the financial crisis that peaked in the fall of 2008 was really about.  This book is a great and neutral exposition of what really happened and what we should do about it.</p>

<h2>What Happened?</h2>

<p>The first two thirds of the book is a history lesson on what happened, a parallel tale of 1929 and 2008.  The last part talks about what we should do about it, and how the concequences of the US’s enoumous current trade deficit may unfold.</p>

<p>The latter part is the more interesting of course.  The authors make it very clear that the crisis is not directly the fault of the individual actors in the financial system; it’s the system itself that is fundamentally broken.</p>

<p>One central principle that was broken in the recent crisis was that central banks bailed out (a) financial institutions that were not just illiquid but they were also insolvent, and (b) they also bailed out non-banks. Both represent moral hazards, as it may cause people to expect such bail outs in the future; even in non-bank financial institutions, which is likely to make them take risks they would not otherwise undertake.</p>

<h2>What should be done?</h2>

<p>The crisis is an eminent opportunity to change legislation.  Generally, the legislation need to guide system actor’s motivations and increase transparency.</p>

<ul>
<li>Compensation in the financial sector should be restructured so as to value long-time gains rather than quick wins.  The authors make it an explicit point to say that it is not necessarily the size of compensation which is the problem; it’s the structure.  There needs to be more <em>skin in the game</em>.</li>
<li>The fact that rating are payed for by the very institutions that are selling financial products, is fundamentally broken.  IMO, ratings should be provided to the public free of charge by truly independent bodies — national or supernational, and the more the merrier.  Until then, never trust an <em>AAA</em> rating again.</li>
<li>Derivatives need to be controlled.  It’s absurd that the system alows anyone to buy CDS’s “bankrupcy insurance” for a any 3rd party; even without having an equity interest in that party.  It’s like buying fire insurance for your neighbours house ... which might motivate me to play around with some matches ...</li>
<li>Too-big-to-fail oriented legislation is bullshit; rules should apply to everyone.  If anything, corporations that are too large to fail should be split up.</li>
</ul>

<p>The book contains many more suggestions for what could be done, the above are some of the more important ones it seems.</p>

<h2>What’s Next?</h2>

<p>According to the authors it is inevitable that soon, the US’s status as the world’s primary economy will fade, and likely be replaced with a century with Chinese dominance.  The US Dollar cannot continue to be the reference currency.  Hopefully this shift will happen in an orderly fashion, but if the US tries to devaluate the dollar by inducing too much inflation (reducing the value of treasury bonds) we might see a “run on the bank” out of the ordinary.</p>

<h2>Conclusions</h2>

<p>Great book.  There’s a lot of “doom day” books out there, this is not one of them.  It provides a solemn and trustworthy account of what happend and argues what we need to do. </p>
<xhtml:img xmlns:xhtml="http://www.w3.org/1999/xhtml" src="http://feeds.feedburner.com/~r/javalimit/~4/2V10qeJ8LY4" height="1" width="1" /></div></content>



    <feedburner:origLink>http://www.javalimit.com/2013/05/how-could-it-go-so-bad.html</feedburner:origLink></entry>
    <entry>
        <title>Consistency Eventualis</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/nlkHR655XJ8/consistency-eventualis.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2012/10/consistency-eventualis.html" thr:count="1" thr:updated="2012-10-23T09:01:47+02:00" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e2017ee45ce15c970d</id>
        <published>2012-10-22T23:47:29+02:00</published>
        <updated>2012-10-23T11:13:35+02:00</updated>
        <summary>Here is just a short note on the unfortunate choice of name for the concept Eventual Consistency. To many non-native speaking people, it sounds like Maybe Consistent. Many languages have a word derived from the latin word eventualis (German: eventuell,...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.javalimit.com/"><div xmlns="http://www.w3.org/1999/xhtml"><p>Here is just a short note on the unfortunate choice of name for the concept <b>Eventual Consistency</b>.  To many non-native speaking people, it sounds like <i>Maybe Consistent.</i>
</p>

<p>Many languages have a word derived from the latin word <i>eventualis</i> (German: eventuell, French: éventuel, Danish: eventuelt, …) which in these languages literally means <i>possibly</i> or <i>perhaps</i> - a word used to denote something which <i>may</i> happen, or maybe not.  For instance, we would use it in phrases such as [replace underlined word with with "our" version of eventual]:
</p>

<ul>
<li> <i>Could you <u>perhaps</u> do me a favour?</i> </li>
<li> <i>What do you think of the <u>possibly</u> fatal outcome?</i> </li>
</ul>

<p>To an average Dane, for instance, <i>eventually fatal</i> doesn't necessarily sound bad; likewise <i>eventually wonderful</i> is not necessarily good.  </p>

<p>This is of course very unfortunate us who want to promote <i>eventual consistency</i> as a tool to provide better scalability and availability in large-scale distributed systems.  The term makes it sound flaky, or "perhapsy".  "If you are lucky - and the planets all line up correctly - yes, then it will eventually be consistent."  It just rings wrong.
</p>

<p>So, from now on I propose that we all call it <i>delayed consistency</i>, which at least to my ear sounds much more right.  It sounds like we will eventually get there :-)
</p>


<xhtml:img xmlns:xhtml="http://www.w3.org/1999/xhtml" src="http://feeds.feedburner.com/~r/javalimit/~4/nlkHR655XJ8" height="1" width="1" /></div></content>



    <feedburner:origLink>http://www.javalimit.com/2012/10/consistency-eventualis.html</feedburner:origLink></entry>
    <entry>
        <title>Erlang is not a Concurrent Functional Programming Language</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/-oPMNDqQnO0/erlang-is-not-a-concurrent-functional-programming-language.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2011/05/erlang-is-not-a-concurrent-functional-programming-language.html" thr:count="20" thr:updated="2011-05-31T08:00:33+02:00" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e20154327e376e970c</id>
        <published>2011-05-24T01:14:24+02:00</published>
        <updated>2011-05-26T10:58:20+02:00</updated>
        <summary>Whenever developers fall in love with Erlang (as many tend to do these days) they are too often busy promoting it to their friends and colleagues as a cool language for *concurrency* and *functional programming*. Which is a pity, for...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.javalimit.com/"><div xmlns="http://www.w3.org/1999/xhtml"><div style="float: right; margin-left: 1em"><script type="text/javascript">
     var topsy_nick = "drkrab";
     var topsy_style = "big";
</script>
<script type="text/javascript" src="http://cdn.topsy.com/button.js" /></div>

<p>Whenever developers fall in love with Erlang (as many tend to do these days) they are too often busy promoting it to their friends and colleagues as a cool language for <em>concurrency</em> and <em>functional programming</em>.  Which is a pity, for several reasons.</p>

<ol>
<li>It intimidates people.</li>
<li>It's wrong.</li>
</ol>

<h3>The intimidation factor</h3>

<p>Functional programming is scary.  Most developers for whom Erlang may be a relevant alternative are probably doing server-side programming in Java or C# today: they most likely know by experience that concurrent programming is damn hard, and functional programming was something they tried +10 years ago in a computer science class in their undergraduate work.  So if you focus on those two aspects you are almost certain to intimidate people, and convince them that this is really difficult stuff to lean.</p>

<p>As we all know ... <em>"people don't want to buy quarter inch drills, they want quarter inch holes."</em>  Likewise with programming languages: If you want to advocate Erlang to your friends and colleagues, focus on the benefits.  It's not really a key selling point of Erlang that it has certain resemblances with some functional programming languages, neither is it a primary quality that it is really easy to spin up a million processes.  Those are good-for-nothing arguments, that just sound flashy, and focus on some secondary aspects of the artifact called Erlang.</p>

<p>Focusing on concurrency also has the problem that most people don't even know what it means, nor why it is important.  On blogs and online media there is a lot of discussion about on issues with utilizing multi-core CPUs, <em>the free lunch is over</em>, etc. etc.  Combine that with your average engineer's performance fetich, and many people will intuitively think that the concurrency is there to get performance.  Why else would you bring such mind-boggling pains upon yourself?  </p>

<h3>Being wrong</h3>

<p>When I started looking into Erlang two years ago, I was wrong.  I was looking for something to make concurrent asynchronous programming more intuitive, because those things were (and still are) obviously hard in the Java world I'd been living in for the last 15 years.   It is difficult to write programs that utilize multicore; but in many cases -- I've realized -- that is of lessor importance.   I went looking for one thing, but found something much more important.</p>

<blockquote>
  <p>Erlang is about building reliable systems.</p>
</blockquote>

<p>That's it: Erlang is about making software systems that are fault tolerant, given that just about everything about the  system has problems: hardware and networks fail (often because of human err), the software we write has bugs that need fixing, requirements change all the time, and we want the system to run 24x7.</p>

<p>You can almost hear the designers saying: <em>"Let's make a tool to build reliable systems; what do we need to make that happen?"</em>  Then then they went off and solved all the hard problems involved with that, and to this date, Erlang is the only "full package" that can do that.  And as complete packages go, there are some rough edges and individual things that could be made better, but ... as a whole it's pretty damn good.  And don't get me wrong: Software is not automatically reliable because it is written in Erlang ... rather, Erlang is a toolbox that allows you to write reliable software systems.  </p>

<h3>What is Erlang then?</h3>

<p>First of all, Erlang introduces mechanisms to contain and manage faults.  When a problem happens in an Erlang system, it doesn't take down everything with it.  This is hard to grasp for a Java programmer where you're used to a bad null pointer error or something that will take down the entire application.  Erlang is more like an operating system which itself runs inside an OS-level process: if one component faults, then its resources are properly reclaimed and only that component is shut down.  </p>

<p>To manage faults, Erlang has mechanisms much like Unix signal handlers, that will notify other components about faults. These are called links and monitors.  Monitors are one way (used to observe), whereas links are bidirectional, and can be used to establish strong aggregation-structures of Erlang components so that they "die in unison": if one goes down the integrity of the others is also at risk.  </p>

<p>In order to make a system reliable, you also need to support running "the system" on multiple computers.  To this end, Erlang has transparent distribution so you can have a component one one physical machine monitoring (or being linked to) a component on another machine.  If an entire (virtual) machine dies, components on the other machine will observe that as if all the individual components on the failing machine faulted.</p>

<p>The process abstraction is used to capture all of the above.  I said "component" but that really is process, which is something we all know well already.  In Erlang, processes don't have threads, and processes can't see or touch each other's data.  Just like in an operating system process.  Erlang processes are individually sequential; and so an Erlang system is really just a set of Cooperating Sequential Processes.  It reduces the inherent concurrency to just a bunch of sequential programs.   If you want, you can think of processes as <em>actors</em>; which is really just how objects should have been in the first place.  Actors encapsulate their state, and they use message passing to interact.</p>

<p>Further, you need to have a model for fixing bugs while the system is running.  That's the key feature of <a href="http://www.youtube.com/watch?v=uKfKtXYLG78">Erlang, The Movie</a>.  At its core, Erlang has features to support upgrading code in flight, which is also one of the reasons why Erlang is not a statically typed language: if you need to change your data structures in flight, you also need to change the types.  While code upgrade is something which is very handy for development, it is not at all easy to do properly in production.  I've heard that for some of Ericsson's telephony systems where they do live upgrades, they spent as much time developing and testing the upgrade as they do developing and testing new features.  The frameworks and libraries that come with Erlang help you in many cases, as long as you stay within certain limits.</p>

<p>But perhaps most importantly, Erlang is just plain simple.  Erlang code is compact, and (once you get used to it) very easy to read.  Compared to coding Java, it almost feels like cheating.</p>

<p>So to get all these goodies, you have to learn some new syntax.  Get over it.  </p>

<blockquote>
  <p>Before you jump to conclusions and barf at me in the comments below, keep in mind that I do know Erlang very well.  I've written an <a href="http://github.com/trifork/erjang">alternative Erlang VM</a>, and I was awarded "Erlang User of the Year 2010".  So, I do know that Erlang is a concurrent and somewhat functional programming language.  But that's not the point.</p>
</blockquote>
<xhtml:img xmlns:xhtml="http://www.w3.org/1999/xhtml" src="http://feeds.feedburner.com/~r/javalimit/~4/-oPMNDqQnO0" height="1" width="1" /></div></content>



    <feedburner:origLink>http://www.javalimit.com/2011/05/erlang-is-not-a-concurrent-functional-programming-language.html</feedburner:origLink></entry>
    <entry>
        <title>Using Links to Index Riak objects</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/03iC8Tzxsyg/using-to-index-riak-objects.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2011/04/using-to-index-riak-objects.html" thr:count="1" thr:updated="2011-05-03T12:02:45+02:00" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e201538e21d5f6970b</id>
        <published>2011-04-26T13:54:01+02:00</published>
        <updated>2011-04-26T14:25:42+02:00</updated>
        <summary>Riak doesn't come with means to do secondary indexes out of the box. This limits many applications of Riak; and it's a bit tricky to implement correctly oneself. The module [`riak_link_index`](http://github.com/krestenkrab/riak_link_index) provides a mechanism that can be applicable for some...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.javalimit.com/"><div xmlns="http://www.w3.org/1999/xhtml"><p>Riak doesn't come with means to do secondary indexes out of the box.  This limits many applications of Riak; and it's a bit tricky to implement correctly oneself.</p>

<p>The module <a href="http://github.com/krestenkrab/riak_link_index"><code>riak_link_index</code></a> provides a mechanism that can be applicable for some situations, providing means to create synthetic (secondary link index) objects triggered by a Riak commit hook.  The mechanism work by defining a function that names these synthetic objects as a function of the primary object body.</p>

<h2>Basic Example</h2>

<p>Assume the primary object contents being stored under the name <code>dogs/ABC01</code> is</p>

<pre><code>{
  type: "Dog",
  name: "Fido",
  owner: "Peter"
  ...
}
</code></pre>

<p>And the indexing function looks like this:</p>

<pre><code>function indexDogs(metaData, contents) {
   Body = JSON.parse(contents);
   if (Body.type == "dog" &amp;&amp; Body.owner) {
       return [ ["people", Body.owner] ];
   } else {
       return []
   }
}
</code></pre>

<p>Then a secondary index object will be created named <code>/riak/people/Peter</code>, which contains a Riak link pointing back to <code>dogs/ABC01</code>.</p>

<p>That's it, basically.  There are a few extra details though.</p>

<h2>Composability by Tagging</h2>

<p>Indexes are virtual entities not tied to a particular bucket; but the indexing function needs to be "installed" in the bucket being written to.  However, multiple buckets may have objects that get indexed the same way, and the "index buckets" (in the above case the <code>/riak/owns</code> bucket) may contain different kinds of indexes.  This kind of composability is controlled by assigning a unique tag to each indexer.</p>

<p>When you install an indexer, you also name it's tag.  It could be that in the above example you choose the tag "owns_dog", then you can use a link-walk query like this:</p>

<pre><code>curl http://127.0.0.1:8091/riak/people/Peter/_,_,owns_dog
</code></pre>

<p>To return all the dogs that are owned by peter.  But the <code>people/Peter</code> object can also contain links to objects that are indexed by another indexer with it's own tag; say the houses that people own.</p>

<h2>Under the hood</h2>

<p>What really happens in the above example is that the indexer function runs in the precommit phase and creates links attached to the primary object, pointing to the index objects, tagged with <code>idx@owns_dog</code>.  So, the object <code>dogs/ABC01</code> will get a link</p>

<pre><code>Link: &lt;/riak/people/Peter&gt;; riaktag="idx@owns_dog"
</code></pre>

<p>The post-commit phase of storing the dog object, will then go to the targets of all the <code>idx@</code>-prefixed links (the index objects), and make sure that those each have a link pointing back to the dog.</p>

<p>So, in stead of using the indexer function, you can also just provide those links when you push the object in the first place; and then the indexer function doesn't have to be installed.</p>

<p>The index objects contain a data structure used to ensure the consistency of the resulting links; that is if two different PUTs to some primary objects mutate the same index object, then the index object may end up having a write conflict (siblings), and the data structure makes sure that such conflicts are resolved properly with it's own set of vector clocks.</p>

<p>Because of that, you cannot use the index objects to contain other stuff.  The data structure contained therein is only for the use of the <code>riak_link_index</code> stuff.</p>
<xhtml:img xmlns:xhtml="http://www.w3.org/1999/xhtml" src="http://feeds.feedburner.com/~r/javalimit/~4/03iC8Tzxsyg" height="1" width="1" /></div></content>



    <feedburner:origLink>http://www.javalimit.com/2011/04/using-to-index-riak-objects.html</feedburner:origLink></entry>
    <entry>
        <title>Introducing Vector Maps</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/y14yPfqSqJ4/the-beauty-of-vector-clocked-data.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2011/02/the-beauty-of-vector-clocked-data.html" thr:count="4" thr:updated="2011-02-26T14:53:40+01:00" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e20147e2b51462970b</id>
        <published>2011-02-21T02:43:53+01:00</published>
        <updated>2011-03-03T13:28:50+01:00</updated>
        <summary>&gt; This post introduces a new data structure - the vector map - which solves some issues related to storing collections in MVCC data stores. Further, vector maps have some super nice use cases for "occasionally connected" systems. &gt; The...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="html" xml:lang="en-US" xml:base="http://www.javalimit.com/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;blockquote&gt;
  &lt;p&gt;This post introduces a new data structure - the vector map - which solves some issues related to storing collections in MVCC data stores.  Further, vector maps have some super nice use cases for "occasionally connected" systems. &lt;/p&gt;
  
  &lt;p&gt;The idea warrants a more rigorous discourse, but I need to get it off my chest, so here is a blog entry describing it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div style="float: right; margin-left: 1em"&gt;&lt;script type="text/javascript"&gt;
     var topsy_nick = "drkrab";
     var topsy_style = "big";
&lt;/script&gt;
&lt;script type="text/javascript" src="http://cdn.topsy.com/button.js"&gt;&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Modern distributed data stores such as CouchDB and Riak, use variants of &lt;em&gt;Multi-Version Concurrency Control&lt;/em&gt; to detect conflicting database updates and present these as multi-valued responses.&lt;/p&gt;

&lt;p&gt;So, if I and my buddy Ola both update the same data record concurrently, the result may be that the data record now has multiple values - both mine and Ola's - and it will be up to the eventual consumer of the data record to resolve the problem.  The exact schemes used to manage the MVCC differs from system to system, but the effect is the same; the client is left with the turd to sort out.&lt;/p&gt;

&lt;p&gt;This led me to an idea, of trying to create a data structure which is by it's very definition itself able to be merged, and then store such data in these kinds of databases.  So, if you are handed two versions, there is a reconciliation function that will take those two records and "merge" them into one sound record, by some definition of "sound".&lt;/p&gt;

&lt;p&gt;From what I have seen, the "thing" stored is often itself a collection like a list or a hash map, and say that Ola and I both add new elements to the collection and store the results, the resulting multiple records are - with proper definitions - naturally mergeable; namely the list or map that contains the original entries plus both mine and Ola's.&lt;/p&gt;

&lt;p&gt;So, this is the presentation of my idea: A &lt;em&gt;vector map&lt;/em&gt;, which is a data structure that is designed to be used in this context.  It also has other interesting applications as we shall discuss towards the end of this post.&lt;/p&gt;

&lt;h2&gt;Vector Maps&lt;/h2&gt;

&lt;p&gt;A vector map is defined as a set of &lt;em&gt;assignment events&lt;/em&gt;, Key=Value, each such event being time stamped with a &lt;a href="http://en.wikipedia.org/wiki/Vector_clock"&gt;vector clock&lt;/a&gt; (hence the name).  From a high-level point of view, a &lt;em&gt;vector map&lt;/em&gt; can be seen as a hash table i.e., a collection key/value pairs.&lt;/p&gt;

&lt;p&gt;Two vector maps can be reconciled (&lt;em&gt;VectorMap&lt;sub&gt;1&lt;/sub&gt;&lt;/em&gt; ⊕ &lt;em&gt;VectorMap&lt;sub&gt;2&lt;/sub&gt;&lt;/em&gt;), so that for each key, the "most recent assignment event" wins.  If assignment events are in conflict (vector-clock wise concurrent), then the resulting value is multivalued.&lt;/p&gt;

&lt;p&gt;The reconciliation function for vector maps is defined so that it is commutative i.e., it can be applied in any order i.e., &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A &lt;em&gt;⊕&lt;/em&gt; B   =  B &lt;em&gt;⊕&lt;/em&gt; A, &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is also associative, &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A &lt;em&gt;⊕&lt;/em&gt; (B &lt;em&gt;⊕&lt;/em&gt; C)  =  (A &lt;em&gt;⊕&lt;/em&gt; B) &lt;em&gt;⊕&lt;/em&gt; C, &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;which means that reordering done inside the database store, is insignificant to the resulting usage.  &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In fact, &lt;a href="http://wiki.basho.com"&gt;Riak&lt;/a&gt; itself (the distributed key/value store) is just a big distributed and redundant version of this; which just goes to prove the versatility of the idea.  So in a sense, a vector map is just a recursion over the Riak (Dynamo) concepts applied to a data structure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the following we will define things a little more rigorously and provide some examples; and towards the end there is a discussion of how vector maps can be used.&lt;/p&gt;

&lt;h3&gt;Assignments as Vector Clocked Events&lt;/h3&gt;

&lt;p&gt;For the purposes of this discourse, we will model an assignment event as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;em&gt;Key&lt;/em&gt;, &lt;/li&gt;
&lt;li&gt;a &lt;em&gt;Set&lt;/em&gt; of values, and&lt;/li&gt;
&lt;li&gt;a &lt;a href="http://en.wikipedia.org/wiki/Vector_clock"&gt;vector clock&lt;/a&gt;, &lt;em&gt;VC&lt;/em&gt;, describing when the assignment happened,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;so an assignment event has the following form:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Assignment :: VC: Key = [Value, Value, ...]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will let the set contain multiple values in case a conflict has been observed, but to start off with our sets will be single-valued.&lt;/p&gt;

&lt;p&gt;Our system will use the vector clock to determine "who wins".  Let's see what happens ...&lt;/p&gt;

&lt;p&gt;To begin with, I do an assignment "X" = 4, and record this event:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Assignment&lt;sub&gt;1&lt;/sub&gt; = (krab:1) : "X" = [4]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reading: &lt;em&gt;at krab's time 1, "X" is bound to 4&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;Later, after observing my assignment, a colleague Ola, at his time 2, defines "X" to be 5&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Assignment&lt;sub&gt;2&lt;/sub&gt; = (ola:2,krab:1) : "X" = [5]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, the immediate beauty is that because each assignment is time stamped with a vector clock, we can easily determine that Assignment&lt;sub&gt;2&lt;/sub&gt; happened after Assignment&lt;sub&gt;1&lt;/sub&gt; (the vector clock says that Ole did indeed observe Assignment&lt;sub&gt;1&lt;/sub&gt; before creating his own), and so if we see both we can discard the earlier one without loss.&lt;/p&gt;

&lt;h3&gt;Conflict happens&lt;/h3&gt;

&lt;p&gt;Now, what happens if Jens comes in, and based on only observing my original assignment, he reassigns "X" to be 7.  We'll describe this with the following event:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Assignment&lt;sub&gt;3&lt;/sub&gt; = (jens:3,krab:1) : "X" = [7]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To Jens, this is not problematic, but if someone observes both Assignment&lt;sub&gt;2&lt;/sub&gt; and Assignment&lt;sub&gt;3&lt;/sub&gt; they'll know that Jens did not observe Ola's time 2.&lt;/p&gt;

&lt;p&gt;To make some kind of sense out of this, we define the reconciliation operator ⊕, describing the aggregation of knowledge we have when combining the known events.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Assignment&lt;sub&gt;2&lt;/sub&gt; &lt;em&gt;⊕&lt;/em&gt; Assignment&lt;sub&gt;3&lt;/sub&gt; = (krab:1,ola:2,jens:3) : "X" = [5,7]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I.e., we describe that "X" has conflicting values 5 &lt;em&gt;and&lt;/em&gt; 7 at a point in time which is after both Assignment&lt;sub&gt;2&lt;/sub&gt; and Assignment&lt;sub&gt;3&lt;/sub&gt;.   &lt;/p&gt;

&lt;h3&gt;Deleting values&lt;/h3&gt;

&lt;p&gt;A further complication is what happens when we want to delete a binding, but this is handled quite simply by making a new assignment to a unique &lt;code&gt;tombstone&lt;/code&gt; value which is somehow outside scope of other possible values; and then reconciling that into the current event set.  This does have some interesting properties, because there is an observable difference between a binding that was never there, and a binding that was removed.&lt;/p&gt;

&lt;h3&gt;Defining Reconciliation&lt;/h3&gt;

&lt;p&gt;In the example above, we can see from the vector clocks that Jens had not observed Ola's assignment, and so we reconciled the two conflicting events by &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;creating an artificial vector clock &lt;strong&gt;(krab:1,ola:2,jens:3)&lt;/strong&gt; which is logically after both &lt;strong&gt;(ola:2,krab:1)&lt;/strong&gt; and &lt;strong&gt;(jens:3,krab:1)&lt;/strong&gt;, and&lt;/li&gt;
&lt;li&gt;combining the bound values [5] and [7] into a set of values [5,7].&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Had it been obvious that one assignment happened before the other, we would simply had thrown one of them away, but because the two vector clocks were in conflict we have to recognize the conflict.  &lt;/p&gt;

&lt;p&gt;So the actual definition of reconciliation for two assignment events with the same key is as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;VC&lt;sub&gt;1&lt;/sub&gt;:Key=Set&lt;sub&gt;1&lt;/sub&gt;  &lt;em&gt;⊕&lt;/em&gt;   VC&lt;sub&gt;2&lt;/sub&gt;:Key=Set&lt;sub&gt;2&lt;/sub&gt; ≡ &lt;br/&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
          VC&lt;sub&gt;1&lt;/sub&gt; ≤ VC&lt;sub&gt;2&lt;/sub&gt;  → VC2 : Key = Set&lt;sub&gt;2&lt;/sub&gt;;&lt;br/&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
          VC&lt;sub&gt;2&lt;/sub&gt; ≤ VC&lt;sub&gt;1&lt;/sub&gt;  → VC&lt;sub&gt;1&lt;/sub&gt; : Key = Set&lt;sub&gt;1&lt;/sub&gt;;&lt;br/&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
          &lt;code&gt;otherwise&lt;/code&gt;  → lub(VC&lt;sub&gt;1&lt;/sub&gt;,VC&lt;sub&gt;2&lt;/sub&gt;) : Key = (Set&lt;sub&gt;1&lt;/sub&gt; ∪ Set&lt;sub&gt;2&lt;/sub&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The reconciliation operator (o-plus) is commutative (just like good old addition), so we can use it to reconcile assignment events in any order and we'll always arrive at the same result in the end.  Which makes it perfect for making decisions in a distributed system; because it means that even if we get to know about events in different order, the state will eventually reconcile to the same value (eventually meaning when we've seen all the events).&lt;/p&gt;

&lt;p&gt;The definition uses the &lt;code&gt;lub&lt;/code&gt; (least upper bound) on two vector clocks, which combines two such by taking the maximum local time stamp for each agent present in two sets of vector clocks:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;lub(&lt;/strong&gt; VC&lt;sub&gt;1&lt;/sub&gt;, VC&lt;sub&gt;2&lt;/sub&gt; &lt;strong&gt;)&lt;/strong&gt; ≡ &lt;br/&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
        ∀ a ∈ &lt;em&gt;agents&lt;/em&gt;(VC&lt;sub&gt;1&lt;/sub&gt;) ∪ &lt;em&gt;agents&lt;/em&gt;(VC&lt;sub&gt;2&lt;/sub&gt;) &lt;br/&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
          a : max( &lt;em&gt;time&lt;/em&gt;(VC&lt;sub&gt;1&lt;/sub&gt;,a), &lt;em&gt;time&lt;/em&gt;(VC&lt;sub&gt;2&lt;/sub&gt;,a) )&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Where &lt;em&gt;time&lt;/em&gt;(VC,a) is 0 (zero) if VC does not list an agent a.  For example&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;lub(&lt;/strong&gt; (b:3), (a:1, b:2) &lt;strong&gt;)&lt;/strong&gt; = (a:1, b:3)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;What is this good for?&lt;/h2&gt;

&lt;p&gt;You may rightly say that this doesn't solve the problem, it just pushes the problem one level down.  And that's right; but ... it does solve an interesting range of problems, and with some care you can often structure your usage of keys in vector maps so that you can avoid conflicts all together.&lt;/p&gt;

&lt;p&gt;Further, since your favorite data store already does this for you ... you may say that you can just split your map into individual key/value bindings and store those in the database.  But that comes at a price of network round trips and data locality.  &lt;/p&gt;

&lt;h3&gt;Use case: Modeling Relationships in MVCC data stores&lt;/h3&gt;

&lt;p&gt;Vector maps are really nice for modeling relationships inside MVCC databases.  &lt;/p&gt;

&lt;p&gt;Assuming you want to store a one-to-many relationship in Riak (say, order - order-item), you run into the problem on the one-side that it is likely to be concurrently updated if multiple items are added to the same order. &lt;/p&gt;

&lt;p&gt;With vector maps, you can easily model the entire relationship as one order object which is just a vector map, where each item is stored with a distinct key.  If that key is e.g. a sufficiently large random number, making it very unlikely that order-item-id's conflict, then you're pretty much home free.  Alternatively, you can devise a mechanism so that each client of the system is able to construct globally unique keys (agent + sequence number).&lt;/p&gt;

&lt;p&gt;For this use case, you'll see &lt;strong&gt;much&lt;/strong&gt; improved performance also, because of the improved locality of reference.  If your data store needs to go and fetch each individual order-item on the disk somewhere, then performance will be seriously hampered.&lt;/p&gt;

&lt;h3&gt;Use case: off-line data&lt;/h3&gt;

&lt;p&gt;Vector maps are great for off-line data, because they give a well defined meaning to the concept of synchronization (something I would really like my iCal to do :-)   Synchronization is simply defined as the exchange of vector maps, storing the result of the reconciliation on both sides.&lt;/p&gt;

&lt;p&gt;Such synchronization can happen in near-real time (peer-to-peer update) or as a delayed synchronization whenever there is contact to a server/peer.&lt;/p&gt;

&lt;p&gt;This is perhaps the most interesting use case, because it an be used as a simple foundation for making data available to e.g. mobile clients in an "occasionally connected" system, in a way that makes sense for both online &lt;em&gt;and&lt;/em&gt; offline mode.&lt;/p&gt;

&lt;h2&gt;Implementation Issues&lt;/h2&gt;

&lt;p&gt;Since it is a little complicated to manipulate a vector map, we need implementations in the most common languages out there to get it off the ground.  I'm currently hacking on an Erlang and a Java version.&lt;/p&gt;

&lt;p&gt;Working on this, and I have come to the conclusion that it would be great if vector maps have a well defined binary representation so that they can be meaningfully manipulated in a number of different contexts, easily stored and transmitted, etc.  So, a special mime-type that lets multiple parties consume vector maps independent of programming languages.&lt;/p&gt;

&lt;p&gt;If vector maps had it's own mime type and well defined data representation, data stores such as Riak or CouchDB could even do the reconciliation automatically before serving the data to a client.&lt;/p&gt;

&lt;p&gt;So, right now I am working with a protocol buffers definition that looks like this on the wire, to be encoded as Content-Type &lt;code&gt;application/x-protobuf;proto=vectormap&lt;/code&gt;, and likely a also a JSON representation &lt;code&gt;application/json;schema=vectormap&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
message VectorMap {
   repeated Entry entries    = 1;
}

message Entry {
   required string key       = 1;
   repeated Clock  vclocks   = 2;
   repeated Value  value     = 3;
}

message Value {
   optional string mime_type = 1 [ default = "application/json;charset=utf-8" ];
   optional bytes  content   = 2;
   optional bool   deleted   = 3 [ default = false ];
}

message Clock {
  required string node       = 1;
  required uint32 counter    = 2; 
  required uint64 utc_millis = 3;
}

&lt;/pre&gt;

&lt;h2&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;The Dynamo idea of using vector clocks to time stamp data is great, but I think the power of the idea goes quite a bit further if the logic is brought all the way to the client.&lt;/p&gt;

&lt;p&gt;CouchDB tries to do this by suggesting that client devices (mobile devices) should have a full fledged CouchDB running there.  But I think that exposing data this way makes the mobile client model much more manageable.   This entire idea can be wrapped up in a single Java class which is easily deployed in a Android app; and it is sufficiently simple to be implementable in a range of programming languages.&lt;/p&gt;

&lt;p&gt;What do you think?&lt;/p&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/javalimit/~4/y14yPfqSqJ4" height="1" width="1"/&gt;</content>



    <feedburner:origLink>http://www.javalimit.com/2011/02/the-beauty-of-vector-clocked-data.html</feedburner:origLink></entry>
    <entry>
        <title>About Version Vectors (a.k.a. Vector Clocks)</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/2aR4Z6elkCg/understanding-vector-clocks.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2011/01/understanding-vector-clocks.html" thr:count="1" thr:updated="2011-01-27T20:59:36+01:00" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e20147e1ff5fd3970b</id>
        <published>2011-01-26T19:53:11+01:00</published>
        <updated>2011-01-27T19:09:26+01:00</updated>
        <summary>The last few weeks I've been working on understanding vector clocks (or rather, [version vectors](http://en.wikipedia.org/wiki/Version_vector)). When working with distributed data stores like [Riak](http://wiki.basho.com) and [Voldemort](http://project-voldemort.com/) which are using this to manage consistency, it is important to have a deep understanding...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.javalimit.com/"><div xmlns="http://www.w3.org/1999/xhtml"><p>The last few weeks I've been working on understanding vector clocks (or rather, <a href="http://en.wikipedia.org/wiki/Version_vector">version vectors</a>).  When working with distributed data stores like <a href="http://wiki.basho.com">Riak</a> and <a href="http://project-voldemort.com/">Voldemort</a> which are using this to manage consistency, it is important to have a deep understanding of what kind of consistency they provide, and how to design systems that work well with these structures.</p>

<p>So, without further ado; here's my story.  We'll start somewhere else though.</p>

<h3>Versions of shared spreadsheets</h3>

<p>Adam and Eve are working on a shared Excel spreadsheet, and they have devised a clever scheme for versioning it, so they can detect conflicting edits.</p>

<p>Their idea is that the document has <em>two</em> version numbers embedded in the file name.  When Adam saves a new version, he increments his number; and likewise for Eve.  After some exchanges and edits, the document is now called <code>doc_adam3_eve4.xls</code> (Adam in version 3, Eve in version 4). The rules of the game are thus:</p>

<ul>
<li>If Adam updates the document, he shall increment from <code>adam3</code> to <code>adam4</code>, and so name the next version <code>doc_adam4_eve4.xls</code>, whereas </li>
<li>if Eve updates the same document she shall increment <code>eve4</code> to <code>eve5</code> and call the result <code>doc_adam3_eve5.xls</code>.  </li>
</ul>

<p>Because both Adam and Eve have their own version scheme, they can make edits and when they share their updated documents they can easily detect if they have made concurrent edits.  Eve will bring her maximum eve-numbered version, and Adam will bring his maximum adam-numbered version.  Then a mechanism depicted in this diagram can be used to detect a conflict:</p>

<p><img src="http://krab.typepad.com/.a/6a00d83455f7ed69e20148c8102100970c-pi" title="VectorTime_2.png" alt="VectorTime_2.png" border="0" width="406" height="373" /></p>

<p>Given version <code>{adam=3,eve=4}</code> (represented by the white square in the middle), you can see which versions are logially "after" and "before" that version.
Versions colored yellow are in conflict with <code>doc_adam3_eve4.xls</code>, representing logically "concurrent" edits.</p>

<p>The great thing is that this scheme extends to any number of participants.  It's just easier to depict in a two-dimensional way, but the same mechanism works for any number of vector dimensions.  Missing participants are assumed to have version 0.</p>

<blockquote>
  <p>Vector Time.  The numbering scheme above is an example of a <a href="http://en.wikipedia.org/wiki/Vector_clock">vector clock</a> which can be used to describe temporal relations between events in a distributed system.  Generally speaking, a vector clock is a list of (<em>place</em>, <em>version</em>) pairs, in which each place occurs at most once.  </p>
  
  <p><em>Really, we should perhaps talk about <a href="http://en.wikipedia.org/wiki/Version_vector">version vectors</a> because the time-notion does not exactly refer to our intuitive notion of time, but to some monotonous increasing series of "versions" issued at each "place".</em></p>
  
  <p>version vectors and version vectors have a partial ordering, which captures the idea of before/after a given point in <em>vector time</em>.  It's partial because there exists pairs of version vectors so that one is neither before nor after the other; they are "concurrent".</p>
  
  <p>If you have a set of version vectors, there is thus a subset hereof which are "maximal" (most recent).  This set contains only one element if there is no conflict.  </p>
</blockquote>

<p>If you use version vectors to give versions to documents, then it is obviously great if there is only one such "most recent" document.  If there is more than one "most recent" then at least you have narrowed it down to the versions to take a closer look at.</p>

<h3>Assembling the Jigsaw</h3>

<p>Regardless of their cleverness, Adam and Eve are often in trouble, because often they have more than one "most recent" Excel spreadsheet when they get together (say, <code>doc_adam4_eve4.xls</code> and <code>doc_adam3_eve5.xls</code> mentioned before), and so they have to sit there and take their spreadsheet apart, resolve the conflicts, and put it back together.  Once they have resolved their conflicts they can name the new version <code>doc_adam4_eve5.xls</code> which is "after" both of the aforementioned ones and be back on track.</p>

<p>Now Justin (he's a really smart programmer) comes along to help them write a new spreadsheet application called <em>Schemix</em> that solves their issues.  Schemix represents spreadsheets such that each <em>cell value</em> in the spreadsheet has it's own version number using version vectors.  </p>

<p>Here's a document in Schemix </p>

<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://krab.typepad.com/.a/6a00d83455f7ed69e20147e2013547970b-pi" alt="spreadsheet.png" border="0" width="358" height="74" /></p>

<p>And here is how Schemix represents this data after Adam and Eve have been working on it for a while. </p>

<pre><code>A1, ["Anders"],                 { adam:3, eve:4 }
B1, ["anders@somewhere.com"],   { adam:1        }
A2, ["Brandon"],                { adam:2, eve:5 }
B2, ["brandon@elsewhere.com"],  {         eve:4 }
</code></pre>

<p>The right-most column is the version vector timestamp for the corresponding cell.  So, in stead of giving the entire document a single version, each cell in the spreadsheet has its own independent version number.  Whenever Adam saves his document, the cells he has modifies will have their version number bumped up one.</p>

<p>This versioning scheme allows <em>any two such Schemix documents to be merged</em>, by comparing the cells individually using the scheme Adam and Eve were using above.  Assume the aforementioned document was merged with this:</p>

<pre><code>A1, ["Andy"],                   { adam:4, eve:3 }
B1, ["anders@somewhere.com"],   { adam:1        }
A2, ["Bill"],                   { adam:3, eve:5 }
B2, ["brandon@elsewhere.com"],  {         eve:4 }
</code></pre>

<p>Merging two Schemix documents is like assembling a jigsaw puzzle from two sets of jigsaws puzzle pieces:</p>

<ul>
<li>For some pieces, there will be two identically versioned ones (such as cells <code>B1</code> and <code>B2</code>) and so you just choose any one and throw the other away.</li>
<li>For some pieces, one is "newer" than the other (for cell <code>A2</code>); and so you just keep the most recent one and discard the other.</li>
<li><em>but, but, but</em> for some there may be a conflict, and so the cell becomes multi-valued.  Say, both Adam and Eve <em>concurrently</em> change the cell A1, but to distinct values.  Then you're in trouble; but luckily much less so than before because the conflict only pertains to that single cell.</li>
</ul>

<p>The merged document look like this:</p>

<pre><code>A1, ["Andy", "Anders"],         { adam:4, eve:4 }
B1, ["anders@somewhere.com"],   { adam:1        }
A2, ["Bill"],                   { adam:3, eve:5 }
B2, ["brandon@elsewhere.com"],  {         eve:4 }
</code></pre>

<p>When cells are in conflict as a result of merging two Schemix documents, they are allowed to have multiple values.  In Schemix, this is obviously just represented as a multi-values GUI element (a drop-down), so that once you have a merged document, you can easily edit it to resolve the conflict.</p>

<h3>Inremental Updates</h3>

<p>Version vectors are really nice, because you don't need entire documents to be able to do consistent merges.  If Adam and Eve can see each other via a peer-to-peer channel, they can just as well send updates to each other by sending the cell values incrementally.  The fact that each cell carries it's own consistency structure makes this scheme applicable to bulk- or incremental merges alike.  </p>

<h3>Relation to NoSQL</h3>

<p>As mentioned above, this idea of version vectors is important because it is a fundamental notion underlying many of the new distributed NoSQL data stores, such as Voldemort, and Riak.  The cell-names <code>A1</code>, <code>B2</code>, and so on are similar to the keys used in these systems, and the notion of version vectors described here is close to what they do.  A Riak store is really just one giant version of the Schemix spreadsheet I described above.</p>

<p>The interesting thing is that even though they do provide automatic reconciliation, there is no guarantee about the referential integrity of the result.  Two independent edits to two distinct key/values can always be merged; but they could easily break some external invariant which is not expressed explicitly.</p>

<p>What kinds of strategies should we then employ if we want to maintain integrity anyway, say for something simple like a one-to-may relationship?  </p>
<xhtml:img xmlns:xhtml="http://www.w3.org/1999/xhtml" src="http://feeds.feedburner.com/~r/javalimit/~4/2aR4Z6elkCg" height="1" width="1" /></div></content>



    <feedburner:origLink>http://www.javalimit.com/2011/01/understanding-vector-clocks.html</feedburner:origLink></entry>
    <entry>
        <title>Erlang User of the Year 2010</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/xQYvnHrg-Xc/erjang-receives-erlang-user-of-the-year-2010.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2010/11/erjang-receives-erlang-user-of-the-year-2010.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e20133f615453a970b</id>
        <published>2010-11-19T12:09:09+01:00</published>
        <updated>2010-11-19T12:13:32+01:00</updated>
        <summary>At the Erlang User Conference in Stockholm, I received the thirteenth "Erlang User of the Year" award, and was presented with the traditional gift, a beautiful hand-carved Erlang logo made in wood by Kanevad in Gamla Linköping. I have to...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.javalimit.com/"><div xmlns="http://www.w3.org/1999/xhtml"><p><img src="http://krab.typepad.com/.a/6a00d83455f7ed69e20133f615452f970b-pi" alt="erlang_user_of_the_year.png" border="0" width="300" height="224" style="float:right;" />
At the Erlang User Conference in Stockholm, I received the thirteenth "Erlang User of the Year" award, and was presented with the traditional gift, a beautiful hand-carved Erlang logo made in wood by Kanevad in Gamla Linköping. </p>

<p>I have to admit that I did not even know this award existed, but I am honored to join the ranks of Chris Piro and Eugene Letuchy (Facebook chat, 2009), Damien Katz (CouchDB, 2008), John Hughes (QuickCheck, 2007), Alexey Shchepin (ejabberd, 2006), The HiPE team members 2005, Michaël Rémond (ejabberd, 2004).  </p>

<p>The award is given by the Erlang community for technical contribution; in this case my work on Erjang - A JVM-based Erlang VM.  I was quite surprised (pleasantly of course) by this since I am by no stretch an Erlang old-timer. I wrote my first line of Erlang code a little over a year ago during JAOO 2009 when Francesco Cesarini was giving an Erlang tutorial.</p>

<p>The Erjang project is doing really well.  For many systems, Erjang is roughly twice as fast as Open Source Erlang (BEAM).  Recently, we've been working on completing more of the core functionality, and we're already at a level where we can boot and run complex systems like Riak and RabbitMQ.  </p>

<p>Since I did not really have time to prepare an acceptance speech, I'm sorry I did not get around to thanking all the people that have been supporting this project.  Most importantly I should thank Erik Søe Sørensen, who was the <a href="http://www.youtube.com/watch?v=fW8amMCVAJQ">first guy to stand up</a> and contribute code to this lunatic project, my family (for living with my lunacy on a daily basis for a year now), and also the entire Erlang community for being surprisingly helpful and positive to this (literally) bastard project.</p>

<p>Once again, Thank you all!</p>

<p>Kresten Krab Thorup</p>
<xhtml:img xmlns:xhtml="http://www.w3.org/1999/xhtml" src="http://feeds.feedburner.com/~r/javalimit/~4/xQYvnHrg-Xc" height="1" width="1" /></div></content>



    <feedburner:origLink>http://www.javalimit.com/2010/11/erjang-receives-erlang-user-of-the-year-2010.html</feedburner:origLink></entry>
    <entry>
        <title>Erjang - Interpreted Mode</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/9IOpqEn2Qt4/erjang-interpreted.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2010/11/erjang-interpreted.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e20133f5972443970b</id>
        <published>2010-11-04T22:09:17+01:00</published>
        <updated>2010-11-04T22:11:57+01:00</updated>
        <summary>Erik has been hacking the interpreter the last few weeks, and now we're finally at a state where it is useful (though there are still some issues). ### Interpreter?? Yep, now Erjang has two modes of operations. - The default...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="html" xml:lang="en-US" xml:base="http://www.javalimit.com/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div style="float: right; margin-left: 1em"&gt;&lt;script type="text/javascript"&gt;
     var topsy_nick = "drkrab";
     var topsy_style = "big";
&lt;/script&gt;
&lt;script type="text/javascript" src="http://cdn.topsy.com/button.js"&gt;&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Erik has been hacking the interpreter the last few weeks, and now we're finally at a state where it is useful (though there are still some issues).  &lt;/p&gt;

&lt;h3&gt;Interpreter??&lt;/h3&gt;

&lt;p&gt;Yep, now Erjang has two modes of operations.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The default is the &lt;em&gt;Eager JIT&lt;/em&gt; mode, meaning that modules are compiled from &lt;code&gt;.beam&lt;/code&gt; to &lt;code&gt;.jar&lt;/code&gt;-with-class-files eagerly as they are encountered as OTP boots up.  This results in relatively slower start-up time, but fast execution.&lt;/li&gt;
&lt;li&gt;The new option &lt;code&gt;ej +i&lt;/code&gt; lets you run Erjang with the byte-code interpreter execution mode; which starts up faster, uses less memory, but runs slower.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One effect of this can be seen from the launch time of Erjang.  Look at this&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;prompt$ rm .erj/*   ## delete class cache
prompt$ echo 'erlang:halt().' | time ej
Eshell V5.8  (abort with ^G)
1&amp;gt;        13.96 real        14.45 user         1.86 sys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wow, that took 14 seconds to launch the Erjang REPL.  Now, doing the same thing again should speed things up because now the &lt;code&gt;.beam&lt;/code&gt; files have been compiled; see here:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;prompt$ echo 'erlang:halt().' | time ej
Eshell V5.8  (abort with ^G)
1&amp;gt;         4.67 real         4.61 user         0.29 sys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wow! the second launch was much faster because the &lt;em&gt;Eager JIT&lt;/em&gt; does not have to pay the price of the up-front compilation.&lt;/p&gt;

&lt;p&gt;So, running the interpreted Erjang (notice the &lt;code&gt;+i&lt;/code&gt; there) gives you:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;prompt$ echo 'erlang:halt().' | time ej +i
Eshell V5.8  (abort with ^G)
1&amp;gt;         2.47 real         2.64 user         0.20 sys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wow, its only ~55% of the execution time. &lt;/p&gt;

&lt;p&gt;You might be puzzled why this is faster than the pre-compiled case above.  The reason is that Java byte code loading is fairly slow, and that case ends up loading a lot of java code. And the Java JIT has not yet had a chance to optimize the code.&lt;/p&gt;

&lt;p&gt;Unfortunately, running BEAM (the &lt;code&gt;erl&lt;/code&gt; command) yields...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;prompt$ echo 'erlang:halt().' | time ej +i
Eshell V5.8  (abort with ^G)
1&amp;gt;         0.24 real         0.11 user         0.02 sys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;10 times faster!  Urgh.  Fortunately for most erlang systems, launch time is not significant... but still.  Over time (when the Java JIT kicks in) the performance of Erjang and BEAM are currently at-par.&lt;/p&gt;

&lt;h2&gt;Memory Usage&lt;/h2&gt;

&lt;p&gt;Having the interpreter provides two new interesting possibilities.  First, it brings Erjang within reach of running on an Android machine, because (a) this execution mode does not involve runtime generation of code, and (b) the memory load is much smaller.  Lets try to launch mnesia and inspect memory usage.   see:&lt;/p&gt;

&lt;p&gt;First, look at an interpreted mode...&lt;/p&gt;

&lt;pre&gt;prompt$ ej +i
1&gt; mnesia:start().
ok
2&gt; 'java.lang.System':gc().
ok
3&gt; erlang:system_info(allocated_areas).
[{'non_heap:CMS Perm Gen',134217728,10628584},
 {'heap:CMS Old Gen',50331648,7618216},
 {'heap:Par Survivor Space',1638400,0},
 {'heap:Par Eden Space',13500416,1790200},
 {'non_heap:Code Cache',2560000,2529664}]&lt;/pre&gt;

&lt;p&gt;Next, compiled mode...&lt;/p&gt;

&lt;pre&gt;prompt$ ej
Eshell V5.8  (abort with ^G)
1&gt; mnesia:start().
ok
2&gt; 'java.lang.System':gc().
ok
3&gt; erlang:system_info(allocated_areas).
[{'non_heap:CMS Perm Gen',134217728,35051856},
 {'heap:CMS Old Gen',50331648,13346696},
 {'heap:Par Survivor Space',1638400,0},
 {'heap:Par Eden Space',13500416,416592},
 {'non_heap:Code Cache',2494464,2483520}]&lt;/pre&gt;

&lt;p&gt;To make it more readable, here is a table ...&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt; &lt;td&gt;  &lt;/td&gt; &lt;td&gt; compiled&lt;/td&gt; &lt;td&gt; interpreted &lt;/td&gt; &lt;/tr&gt;
  &lt;tr&gt; &lt;td&gt; Old Gen&lt;/td&gt;        &lt;td align=right&gt; 13,346,696&lt;/td&gt; &lt;td align=right&gt; 7,618,216 &lt;/td&gt; &lt;/tr&gt;
  &lt;tr&gt; &lt;td&gt; Survivor Space&lt;/td&gt; &lt;td align=right&gt; 0&lt;/td&gt;        &lt;td align=right&gt; 0 &lt;/td&gt; &lt;/tr&gt;
  &lt;tr&gt; &lt;td&gt; Eden Space&lt;/td&gt;     &lt;td align=right&gt; 416,592&lt;/td&gt;   &lt;td align=right&gt; 1,790,200 &lt;/td&gt; &lt;/tr&gt;
  &lt;tr&gt; &lt;td&gt; Perm Space (&lt;i&gt;Java byte code&lt;/i&gt;)&lt;/td&gt;     &lt;td align=right&gt; 35,051,856&lt;/td&gt; &lt;td align=right&gt; 10,628,584 &lt;/td&gt; &lt;/tr&gt;
  &lt;tr&gt; &lt;td&gt; Code Cache (&lt;i&gt;native code&lt;/i&gt;)&lt;/td&gt;     &lt;td align=right&gt; 2,483,520&lt;/td&gt;  &lt;td align=right&gt; 2,529,664 &lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;With the compiled mode, memory adds up to ~55MB, in interpreted mode, ~20MB.  Over time when the Java JIT kicks in, this difference is going to be even more evident.&lt;/p&gt;

&lt;p&gt;Another interesting measure, is the memory usage before and after starting &lt;code&gt;mnesia&lt;/code&gt;.  With &lt;code&gt;ej +i&lt;/code&gt; starting mnesia adds ~1MB total memory usage (similar to BEAM); but with compiled mode, starting mnesia adds ~9MB memory usage.  So, while the baseline for a booted OTP is higher with Erjang &lt;code&gt;+i&lt;/code&gt; than BEAM (~19MB vs ~3MB), the incremental memory usage when loading code and running is the same order of magnitude.&lt;/p&gt;

&lt;h3&gt;HotSpot Erjang&lt;/h3&gt;

&lt;p&gt;Another interesting potential would be to combine the Erjang interpreter an the Erjang JIT, so that code starts up interpreted and then if something is used "enough" it will get JIT'ed to java byte code.  This is similar to how HotSpot Java does it (but is also one of the things that Oracle has patented and was recently suing Google over ...).&lt;/p&gt;

&lt;p&gt;In such a scenario, there are some more interesting optimizations that would make sense; because if we have more information then it might well make sense to do more agressive optimizations and trade off some extra byte code generated for more speed.&lt;/p&gt;

&lt;h3&gt;Getting there...&lt;/h3&gt;

&lt;p&gt;As I hinted above, there are still issues with the interpreted mode; one is that interpreted mode uses more stack stack space; another is that there are some still some bugs lurking in there.  At lease when running &lt;code&gt;rabbitmq&lt;/code&gt;, something doesn't boot correctly.  So, there is still some wat to go. &lt;/p&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/javalimit/~4/9IOpqEn2Qt4" height="1" width="1"/&gt;</content>



    <feedburner:origLink>http://www.javalimit.com/2010/11/erjang-interpreted.html</feedburner:origLink></entry>
    <entry>
        <title>GOTO Top 20 Talks</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/Hcb2tDP-9IM/goto-top-20-talks.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2010/10/goto-top-20-talks.html" thr:count="3" thr:updated="2010-10-11T17:27:49+02:00" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e20133f4faf032970b</id>
        <published>2010-10-11T12:02:03+02:00</published>
        <updated>2010-10-11T18:13:13+02:00</updated>
        <summary>Here's a quick tally of the top talks at last week's [GOTO Aarhus conference.](http://gotocon.com/aarhus-2010) The rating is based on the red, green and yellow "exit-poll", computed as (#green - #red) / #total votes. &gt; Make sure to [evaluate the conference...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.javalimit.com/"><div xmlns="http://www.w3.org/1999/xhtml"><div style="float: right; margin-left: 1em"><script type="text/javascript">
     var topsy_nick = "drkrab";
     var topsy_style = "big";
</script>
<script type="text/javascript" src="http://cdn.topsy.com/button.js" /></div>

<p>Here's a quick tally of the top talks at last week's <a href="http://gotocon.com/aarhus-2010">GOTO Aarhus conference.</a> The rating is based on the red, green and yellow "exit-poll", computed as (#green - #red) / #total votes.  </p>

<blockquote>
  <p>Make sure to <a href="http://bit.ly/8ZOGKJ">evaluate the conference here</a> and 
  join the raffle for one of five signed copies of Martin Fowler's new 
  book <a href="http://martinfowler.com/books.html#dsl">Domain Specific Languages</a>.</p>
</blockquote>

<p>Mario's technical talk on ASP.NET MVC went straight to the top.  Two people made it onto the list twice: Tim Bray and Brian Goetz.  Gregor Hohpe who stepped in for a cancellation with a talk on Near Field Communication made #2.</p>

<p><a href="http://www.flickr.com/photos/frankvilhelmsen/5062640023/"><img src="http://krab.typepad.com/.a/6a00d83455f7ed69e20133f4faf822970b-pi" alt="jaoo_goes_pink_240x.jpg" border="0" width="240" height="268" style="float:right;" /></a></p>

<ol>
<li><p><em>Mario Szpuszta</em>: <a href="http://gotocon.com/aarhus-2010/presentation/Fall%20in%20Love%20with%20ASP.NET%20MVC%20-%20Testable,%20Dynamic%20Web%20Applications%20with%20.NET">Fall in Love with ASP.NET MVC - Testable, Dynamic Web Applications with .NET</a>   </p></li>
<li><p><em>Gregor Hohpe</em>: <a href="http://gotocon.com/aarhus-2010/presentation/NFC%20-%20Not%20For%20Children?">NFC - Not For Children?</a>   </p></li>
<li><p><em>John Hughes</em>: <a href="http://gotocon.com/aarhus-2010/presentation/Testing%20Asynchronous%20Behaviour%20in%20an%20Instant%20Messaging%20Server">Testing Asynchronous Behaviour</a></p></li>
<li><p><em>John Maloney</em>: <a href="http://gotocon.com/aarhus-2010/presentation/Scratch:%20Making%20Programming%20Easy%20and%20Fun">Scratch: Making Programming Easy and Fun</a>    </p></li>
<li><p><em>Dan North</em>: <a href="http://gotocon.com/aarhus-2010/presentation/From%20months">From months to minutes - upping the stakes</a></p></li>
<li><p><em>Michael T. Nygard</em>: <a href="http://gotocon.com/aarhus-2010/presentation/When%20the%20Fur%20Flies:%20Dev%20and%20Ops%20Cooperation%20when%20the%20Worst%20Happens">Dev and Ops Cooperation when the Worst Happens </a></p></li>
<li><p><em>Tim Bray</em>: <a href="http://gotocon.com/aarhus-2010/presentation/Doing%20It%20Wrong">Doing It Wrong</a></p></li>
<li><p><em>Kati Vilkki</em>: <a href="http://gotocon.com/aarhus-2010/presentation/Becoming+Agile+is+HARD+for+a+Large+Organization">Becoming Agile is HARD for a Large Organization</a></p></li>
<li><p><em>Mary Poppendieck</em>: <a href="http://gotocon.com/aarhus-2010/presentation/What%20is%20this%20thing%20called%20%22Pull%22">What is this thing called "Pull"?</a></p></li>
<li><p><em>Tim Bray</em>: The Mobile Imperative       </p></li>
<li><p><em>Brian Goetz</em>: Java Future at Oracle        </p></li>
<li><p><em>Jim Webber</em>: Lessons Learned in Large HTTP-Centric Systems </p></li>
<li><p><em>Stuart Halloway</em>: Clojure Protocols are <em>not</em> Interfaces!</p></li>
<li><p><em>Jez Humble</em>: Continuous Delivery       </p></li>
<li><p><em>Jonas Jacobi</em>: HTML5 WebSockets        </p></li>
<li><p><em>Brian Goetz</em>: Data parallelism in Java      </p></li>
<li><p><em>Bill Pugh</em>: Defective Java: Mistakes that matter </p></li>
<li><p><em>Arjen Poutsma</em>: Having fun with the RestTemplate </p></li>
<li><p><em>John Allspaw</em>: Dev and Ops Cooperation at Flickr </p></li>
<li><p><em>Dan Ingalls</em>: Forty Years of Fun with Computers     </p></li>
</ol>

<p>Mind you, being #20 out of 84 talks is pretty good, and represents 83% approval.</p>

<p>Once again, we have talks from the so-called "vendor track" pop into the top talks; this. <em>Jez Humble</em>'s and <em>Arjen Poutsma</em>'s talks were very well received.  </p>

<p>Personally, I'm sorry that I only made it to 5 of the talks on this list.  With so much to choose from (and my various other obligations) it was hard to make it.</p>

<h3>Over all distribution</h3>

<p>The over all distribution of evaluations look like this, and I'm happy that 80 out of 84 talks total are above expectations.  Great kudos to <a href="http://gotocon.com/aarhus-2010/speakers/">all the speakers</a> and the <a href="http://gotocon.com/aarhus-2010/programcommittee/">program committee</a> for making this happen! </p>

<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://krab.typepad.com/.a/6a00d83455f7ed69e20134881aa7c9970c-pi" alt="goto2010_eval_scatter.png" border="0" width="500" height="195" /></p>

<p>As can be seen, four talks fell below expectations; and while that's obviously too many it gives us ideas for what to improve for next year's GOTO Aarhus.  I think those bottom ones are one of two reasons: 1. misalignment of expectations, or 2. some speakers found it very difficult to present in the large room where it was difficult to interact with the audience.  </p>

<p>And please don't ask who's at the bottom.  I won't tell.</p>
<xhtml:img xmlns:xhtml="http://www.w3.org/1999/xhtml" src="http://feeds.feedburner.com/~r/javalimit/~4/Hcb2tDP-9IM" height="1" width="1" /></div></content>



    <feedburner:origLink>http://www.javalimit.com/2010/10/goto-top-20-talks.html</feedburner:origLink></entry>
    <entry>
        <title>RabbitMQ on Erjang</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/javalimit/~3/fv9v-vTj13A/rabbitmq-on-erjang.html" />
        <link rel="replies" type="text/html" href="http://www.javalimit.com/2010/09/rabbitmq-on-erjang.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00d83455f7ed69e2013487d223c1970c</id>
        <published>2010-09-29T12:55:46+02:00</published>
        <updated>2010-09-29T13:27:55+02:00</updated>
        <summary>It's been quiet on Erjang for a while, and I've been busy with other things. Going to JavaZone two weeks ago however, got me all psyched up again on my little Erlang on the JVM project. I met some guys...</summary>
        <author>
            <name>Kresten Krab Thorup</name>
        </author>
        
        
<content type="html" xml:lang="en-US" xml:base="http://www.javalimit.com/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div style="float: right; margin-left: 1em"&gt;&lt;script type="text/javascript"&gt;
     var topsy_nick = "drkrab";
     var topsy_style = "big";
&lt;/script&gt;
&lt;script type="text/javascript" src="http://cdn.topsy.com/button.js"&gt;&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;It's been quiet on Erjang for a while, and I've been busy with other things.  Going to JavaZone two weeks ago however, got me all psyched up again on my little Erlang on the JVM project. &lt;/p&gt;

&lt;p&gt;I met some guys from VMWare/SpringSource and we talked about RabbitMQ, so I spent some late nights these past weeks getting things working. 
The prospects of this?  How about a SpringSource developer wanting to use RabbitMQ?  Eventually, this would be a great option  as an integrated part of a pure Java development environment for say, Eclipse.&lt;/p&gt;

&lt;p&gt;It's at the point now where I can run a good deal of the unit tests, though many still fail.  You can read more about the progress below.&lt;/p&gt;

&lt;p&gt;The major improvements are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mnesia is much more stable now&lt;/li&gt;
&lt;li&gt;TCP/IP error handling is much improved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's great to work specifically on something like RabbitMQ because it already has a large base of existing test cases.  Further, RabbitMQ is &lt;em&gt;plain erlang&lt;/em&gt; i.e., no NIFs or linked-in drivers, so it is a perfect candidate for Erjang.&lt;/p&gt;

&lt;p&gt;Looking forward to demo/talk about this next week at &lt;a href="http://jaoo.dk"&gt;JAOO&lt;/a&gt;.  Feel free to follow &lt;a href="http://github.com/krestenkrab/erjang"&gt;Erjang at GitHub&lt;/a&gt; if you want to stay in the loop on this.&lt;/p&gt;

&lt;h2&gt;Additions/Fixes...&lt;/h2&gt;

&lt;p&gt;To get to this point, I added a number of new BIFs, and fixed various bugs.  You can see the glory details in the &lt;a href="http://github.com/krestenkrab/erjang/commits/master"&gt;commit log here&lt;/a&gt;, but here is an outline of the most important fixes/additions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement &lt;code&gt;erlang:hibernate&lt;/code&gt; which is used in &lt;code&gt;gen_server2&lt;/code&gt; and a lot of the other infrastructure modules that come with RabbitMQ.  Hibernating is implemented as an exception which is caught at the top-level of the process so as to remove the call stack before going to sleep.  &lt;/li&gt;
&lt;li&gt;Fix a couple of issues with the tcp_inet driver.  Connections shutdown procedures didn't work completely, and rabbit depends on the owner dying to close connections.   Further, rabbit uses the tcp option &lt;code&gt;{exit_on_close, false}&lt;/code&gt; to allow outgoing communication to flush before the actual tcp socket is closed, and Erjang had some issues with that too. &lt;/li&gt;
&lt;li&gt;Improve the driver select mechanism.&lt;/li&gt;
&lt;li&gt;Implement a few more options for the efile driver.   Rabbit uses the &lt;code&gt;FILE_SETOPT&lt;/code&gt; driver option to configure read-ahead strategies for file usage, and also depends on the integer (file descriptor) returned by &lt;code&gt;FILE_OPEN&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In ETS, I had to implement a few more bif used specifically by Rabbit/Mnesia, such as &lt;code&gt;ets:repair_continuation&lt;/code&gt;, &lt;code&gt;ets:update_counter/3&lt;/code&gt; (the 4-tuple variant).&lt;/li&gt;
&lt;li&gt;Various fixes to the BEAM -&gt; JVM compiler that I stumbled upon when running Rabbit.  There were some cases where the type inference was slightly off, and I optimized the cases when &lt;code&gt;erlc&lt;/code&gt; uses &lt;code&gt;{x,1023}&lt;/code&gt; as a scratch register.   &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I still have an issue with some of the functions in &lt;code&gt;io_lib&lt;/code&gt; being non-tail recursive, causing stack overruns.  The problem is that this often happens when Erjang tries to print an error message, and so it doesn't print the reason why it dies.  And in some cases, the &lt;code&gt;error_logger&lt;/code&gt; process itself dies from a stack overrun, bringing down the entire VM.  &lt;/p&gt;

&lt;p&gt;Going forward, it looks like the issues yet-to-be-fixed are either simple bugs like variants of arguments that are not supported by my BIF implementations, and (more tricky) some cleanup issues with processes. &lt;/p&gt;

&lt;p&gt;Stay tuned!  I'll talk more about these things at &lt;a href="http://jaoo.dk"&gt;JAOO&lt;/a&gt; next week, &lt;a href="http://qconsf.com"&gt;QCon/SF&lt;/a&gt; and &lt;a href="http://www.erlang-factory.com/conference/ErlangFactoryLiteLA"&gt;ErlangFactory Lite LA&lt;/a&gt; in November, &lt;a href="http://yowconference.com.au"&gt;YOW!&lt;/a&gt; Australia in December.  If you want me to come and speak please let me know.&lt;/p&gt;

&lt;h2&gt;Booting RabbitMQ on Erjang&lt;/h2&gt;

&lt;p&gt;Booting rabbit right now happens with the following command line&lt;/p&gt;

&lt;pre&gt;ej -boot /var/lib/rabbitmq/mnesia/rabbit@renaissance/plugins-scratch/rabbit \
   -pa ./ebin -name rabbit2@renaissance.local \
   -sasl sasl_error_logger '{file,"sasl.log"}'
&lt;/pre&gt;

&lt;p&gt;The bootup sequence looks like this (running the latest rabbitmq 0.9.1 build from hg) on Erjang/OTP R14.&lt;/p&gt;

&lt;pre&gt;=INFO REPORT==== 29-Sep-2010::12:03:51 ===
    alarm_handler: {set,{{disk_almost_full,"/"},[]}}

=INFO REPORT==== 29-Sep-2010::12:03:51 ===
    alarm_handler: {set,{{disk_almost_full,"/Volumes/StockMeter"},[]}}

=INFO REPORT==== 29-Sep-2010::12:03:51 ===
    alarm_handler: {set,{{disk_almost_full,"/Volumes/Flash"},[]}}
|
=INFO REPORT==== 29-Sep-2010::12:03:51 ===
    alarm_handler: {set,{system_memory_high_watermark,[]}}
+---+   +---+
|   |   |   |
|   |   |   |
|   |   |   |
|   +---+   +-------+
|                   |
| RabbitMQ  +---+   |
|           |   |   |
| v%%VSN%%  +---+   |
|                   |
+-------------------+
AMQP 0-9-1 / 0-9 / 0-8
Copyright (C) 2007-2010 LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd.
Licensed under the MPL.  See http://www.rabbitmq.com/

node           : rabbit2@renaissance.local
app descriptor : /Users/krab/Projects/rabbitmq-server/ebin/rabbit.app
home dir       : /Users/krab
cookie hash    : pIGTBl0W0HD2xiNguwnLoQ==
log            : tty
sasl log       : sasl.log
database dir   : /Users/krab/Projects/rabbitmq-server/Mnesia.rabbit2@renaissance.local
erlang version : 5.8

starting file handle cache server                                     ...
=INFO REPORT==== 29-Sep-2010::12:04:05 ===
Limiting to approx 10140 file handles (9124 sockets)
done
starting worker pool                                                  ...done
starting codec correctness check                                      ...done
starting database                                                     ...found mnesia running id=&lt;2.0.592&gt;
Sep 29, 2010 12:04:05 PM erjang.EModuleManager$FunctionInfo$1 invoke
INFO: MISSING mnesia_sup:prep_stop/1

=INFO REPORT==== 29-Sep-2010::12:04:05 ===
    application: mnesia
    exited: stopped
    type: permanent

=INFO REPORT==== 29-Sep-2010::12:04:06 ===
Process &lt;2.0.2031&gt; exited abnormally without links/monitors
exit reason was: shutdown
erjang.ErlangExit: shutdown
    at erjang.m.erlang.ErlProc.exit(ErlProc.java:468)
    at erjang.m.mnesia_bup.mnesia_bup.install_fallback_master__2(mnesia_bup.S:207)
    at erjang.m.mnesia_bup.mnesia_bup$FN_install_fallback_master__2.go(Unknown Source)
    at erjang.EProc.execute(EProc.java:498)
    at kilim.Task._runExecute(Task.java:400)
    at kilim.WorkerThread.run(WorkerThread.java:47)

done
-- external infrastructure ready
starting logging server                                               ...done
starting exchange type registry                                       ...done
starting exchange type direct                                         ...done
starting exchange type headers                                        ...done
starting exchange type topic                                          ...done
starting exchange type fanout                                         ...done
starting statistics event manager                                     ...done
-- kernel ready
starting guid generator                                               ...done
starting cluster delegate                                             ...done
starting alarm handler                                                ...done
starting memory monitor                                               ...done
starting node monitor                                                 ...done
-- core initialized
starting empty DB check                                               ...
=INFO REPORT==== 29-Sep-2010::12:04:07 ===
Memory limit set to 1535MB.
done
starting queue supervisor and queue recovery                          ...
=INFO REPORT==== 29-Sep-2010::12:04:07 ===
Added vhost &lt;&lt;"/"&gt;&gt;

=INFO REPORT==== 29-Sep-2010::12:04:07 ===
Created user &lt;&lt;"guest"&gt;&gt;

=INFO REPORT==== 29-Sep-2010::12:04:07 ===
Set user admin flag for user &lt;&lt;"guest"&gt;&gt; to true

=INFO REPORT==== 29-Sep-2010::12:04:07 ===
msg_store_transient: using rabbit_msg_store_ets_index to provide index

=INFO REPORT==== 29-Sep-2010::12:04:07 ===
msg_store_persistent: using rabbit_msg_store_ets_index to provide index

=ERROR REPORT==== 29-Sep-2010::12:04:07 ===
msg_store_persistent: rebuilding indices from scratch
done
starting exchange recovery                                            ...done
-- message delivery logic ready
starting error log relay                                              ...done
starting networking                                                   ...
=INFO REPORT==== 29-Sep-2010::12:04:07 ===
started TCP Listener on 0.0.0.0:5672
done
-- network listeners available

broker running
Eshell V5.8  (abort with ^G)
(rabbit2@renaissance.local)1&gt; 
&lt;/pre&gt;

&lt;h2&gt;Running the tests from &lt;code&gt;rabbitmq-java-client&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;And we can now run some unit tests.  I've been poking around in the &lt;code&gt;rabbit-java-client&lt;/code&gt; unit tests.  Here are some screen shots...&lt;/p&gt;

&lt;p&gt;&lt;img src="http://krab.typepad.com/.a/6a00d83455f7ed69e20133f4b26a38970b-pi" alt="BindingLifecycle.png" border="0" width="512" height="331" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://krab.typepad.com/.a/6a00d83455f7ed69e20133f4b26a44970b-pi" alt="ClientTests.png" border="0" width="389" height="342" /&gt;&lt;/p&gt;

&lt;p&gt;The main tests for &lt;code&gt;rabbitmq-java-client&lt;/code&gt; gets most of the way there, but currently dies with a bug in Erjang's ETS implementation when running the 500 producers/consumer test.  Well well, can be fixed.&lt;/p&gt;

&lt;pre&gt;/com/rabbitmq/examples/TestMain.class
com.rabbitmq.examples.TestMain : javac v50.0 on 1.6.0_20
Channel 0 fully open.
Got message (4 left in q): (0) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Got message (3 left in q): (1) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Got message (2 left in q): (2) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Got message (1 left in q): (3) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Got message (0 left in q): (4) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Drained, remaining in batch = 0.
com.rabbitmq.examples.TestMain$BatchedTracingConsumer@6db3f829.handleConsumeOk(amq.ctag-jM3S9gxr4aSTUqoQC71+lA==)
com.rabbitmq.examples.TestMain$BatchedTracingConsumer@42698403.handleConsumeOk(amq.ctag-lL8JbFN2bq2oWxUgeDTuFQ==)
Async message (0,noack): (5) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (0,ack): (6) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (1,noack): (7) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (1,ack): (8) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (2,noack): (9) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (2,ack): (10) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (3,noack): (11) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (3,ack): (12) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (4,noack): (13) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Async message (4,ack): (14) On the third tone, the time will be Wed Sep 29 12:13:33 CEST 2010
Acking batch.
com.rabbitmq.examples.TestMain$BatchedTracingConsumer@6db3f829.handleCancelOk(amq.ctag-jM3S9gxr4aSTUqoQC71+lA==)
com.rabbitmq.examples.TestMain$BatchedTracingConsumer@42698403.handleCancelOk(amq.ctag-lL8JbFN2bq2oWxUgeDTuFQ==)
About to publish to topic queues
About to drain q1
Got message (2 left in q): B
Got message (1 left in q): C
Got message (0 left in q): D
Drained, remaining in batch = 7.
About to drain q2
Got message (0 left in q): C
Drained, remaining in batch = 9.
About to drain q3
Got message (1 left in q): C
Got message (0 left in q): D
Drained, remaining in batch = 8.
About to try mandatory/immediate publications
Handling return with body one
Returned: #method&lt;basic.return&gt;(reply-code=312,reply-text=NO_ROUTE,exchange=mandatoryTestExchange,routing-key=)
 - props: #contentHeader&lt;basic&gt;(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
 - body: one
Handling return with body two
Returned: #method&lt;basic.return&gt;(reply-code=312,reply-text=NO_ROUTE,exchange=mandatoryTestExchange,routing-key=)
 - props: #contentHeader&lt;basic&gt;(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
 - body: two
Handling return with body three
Returned: #method&lt;basic.return&gt;(reply-code=313,reply-text=NO_CONSUMERS,exchange=mandatoryTestExchange,routing-key=)
 - props: #contentHeader&lt;basic&gt;(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
 - body: three
Handling return with body four
Returned: #method&lt;basic.return&gt;(reply-code=313,reply-text=NO_CONSUMERS,exchange=mandatoryTestExchange,routing-key=)
 - props: #contentHeader&lt;basic&gt;(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
 - body: four
Got message (0 left in q): five
Drained, remaining in batch = 0.
Completed basic.return testing.
Got message (4 left in q): (15) On the third tone, the time will be Wed Sep 29 12:13:34 CEST 2010
Got message (3 left in q): (16) On the third tone, the time will be Wed Sep 29 12:13:34 CEST 2010
Got message (2 left in q): (17) On the third tone, the time will be Wed Sep 29 12:13:34 CEST 2010
Got message (1 left in q): (18) On the third tone, the time will be Wed Sep 29 12:13:34 CEST 2010
Got message (0 left in q): (19) On the third tone, the time will be Wed Sep 29 12:13:34 CEST 2010
Drained, remaining in batch = 0.
Handling return with body mandatory
Returned: #method&lt;basic.return&gt;(reply-code=312,reply-text=NO_ROUTE,exchange=,routing-key=bogus)
 - props: #contentHeader&lt;basic&gt;(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
 - body: mandatory
Handling return with body immediate
Returned: #method&lt;basic.return&gt;(reply-code=313,reply-text=NO_CONSUMERS,exchange=,routing-key=bogus)
 - props: #contentHeader&lt;basic&gt;(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
 - body: immediate
Got message (1 left in q): normal
Got message (0 left in q): mandatory
Drained, remaining in batch = 8.
Closing.
Leaving TestMain.run().
WON'T write statistics.
WILL use server-side auto-acking.
&lt;/pre&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/javalimit/~4/fv9v-vTj13A" height="1" width="1"/&gt;</content>



    <feedburner:origLink>http://www.javalimit.com/2010/09/rabbitmq-on-erjang.html</feedburner:origLink></entry>
 
</feed><!-- ph=1 -->
