<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Jabberwocky</title>
  <id>http://jabberwocky.eu</id>
  <updated>2008-09-12T00:00:00Z</updated>
  <author>
    <name>Elise Huard</name>
  </author>
  <entry>
    <title>Transparency</title>
    <link href="http://jabberwocky.eu/2011/09/17/transparency/" rel="alternate"/>
    <id>http://jabberwocky.eu/2011/09/17/transparency/</id>
    <published>2011-09-17T00:00:00Z</published>
    <updated>2011-09-17T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;2 weeks ago, we watched some of the &lt;a href="http://oreillynet.com/pub/e/2036"&gt;Strata preview&lt;/a&gt; from the Office. Strata is a conference about bhe business of big data which takes place every year.&lt;/p&gt;

&lt;p&gt;Michael Nelson's story: after Wikileaks broke some highly sensitive stories, not only governments but also organizations decided to clamp down on every possible leak and information source. Michael Nelson argued that this is a bad approach - a much better oneis to strive for maximum transparency.  The brazilian company SEMCO, striving for total transparency, was one of his examples&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;2 weeks ago, we watched some of the &lt;a href="http://oreillynet.com/pub/e/2036"&gt;Strata preview&lt;/a&gt; from the Office. Strata is a conference about bhe business of big data which takes place every year.&lt;/p&gt;

&lt;p&gt;Michael Nelson's story: after Wikileaks broke some highly sensitive stories, not only governments but also organizations decided to clamp down on every possible leak and information source. Michael Nelson argued that this is a bad approach - a much better oneis to strive for maximum transparency.  The brazilian company SEMCO, striving for total transparency, was one of his examples.&lt;/p&gt;

&lt;p&gt;He posited that in most organizations there is a kind of Pareto principle of sensitivity of information: a large majority of data could be disclosed without any damage, only a few percentage are of strategic importance.&lt;/p&gt;

&lt;p&gt;Even better, disclosing that non-sensitive information creates a sense of trust and familiarity in the customers. Being open is simply good PR.&lt;/p&gt;

&lt;p&gt;I do agree with those points, especially the last one: as examples see the blog post by a &lt;a href="http://randfishkin.com/blog/128/misadventures-venture-capital-funding"&gt;Rand Fishkin&lt;/a&gt;, and the &lt;a href="http://blogs.balsamiq.com/peldi/"&gt;Peldi's blog&lt;/a&gt;. Both company founders talk about milestones, decisions, joys and disappointments in an earnest way. Their sharing creates a personal connection.  The reader feels like cheering for their successes, and lamenting their losses, which does no end of good to their brand.&lt;/p&gt;

&lt;p&gt;A more cynical part of me also senses that if you look transparent, people won't look that closely because they think they know all there is to know. Also, one could be drowning out relevant information in noise, as it were. Not to mention that any displayed infomation can be given the spin it requires.&lt;/p&gt;

&lt;p&gt;On the other hand, I feel that a lot of organizations would still be reluctant to go that far: unfortunately, companies can be dysfunctional enough that they wouldn't like to wash their dirty laundry in public.&lt;/p&gt;

&lt;p&gt;While in fact, transparency might be very beneficial for these organizations: public shaming is a strong motivator for change.  Something they might want to come to terms with, because in the age of porous boundaries, disclosure might happen whether they want to or not.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Interlude</title>
    <link href="http://jabberwocky.eu/2011/08/23/interlude/" rel="alternate"/>
    <id>http://jabberwocky.eu/2011/08/23/interlude/</id>
    <published>2011-08-23T00:00:00Z</published>
    <updated>2011-08-23T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;I've been slack on the blogging front for several months now - been fairly busy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;moved to London&lt;/li&gt;
&lt;li&gt;found a new job at &lt;a href="http://forward.co.uk"&gt;Forward&lt;/a&gt;, also known from the concept of &lt;a href="http://www.infoq.com/presentations/Leaner-Programmer-Anarchy"&gt;Programmer Anarchy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;spoke at a motherload of conferences (&lt;a href="http://euruko2011.org"&gt;euruko&lt;/a&gt;, &lt;a href="http://rulu.eu"&gt;rulu.eu&lt;/a&gt;, &lt;a href="http://nordicruby.org/"&gt;Nordic Ruby&lt;/a&gt;, &lt;a href="http://rubykaigi.org/2011/en"&gt;Rubykaigi&lt;/a&gt;, &lt;a href="http://www.spaconference.org/spa2011/index.php"&gt;SPA&lt;/a&gt; ) resulting in a lot of traveling&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;

</summary>
    <content type="html">&lt;p&gt;I've been slack on the blogging front for several months now - been fairly busy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;moved to London&lt;/li&gt;
&lt;li&gt;found a new job at &lt;a href="http://forward.co.uk"&gt;Forward&lt;/a&gt;, also known from the concept of &lt;a href="http://www.infoq.com/presentations/Leaner-Programmer-Anarchy"&gt;Programmer Anarchy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;spoke at a motherload of conferences (&lt;a href="http://euruko2011.org"&gt;euruko&lt;/a&gt;, &lt;a href="http://rulu.eu"&gt;rulu.eu&lt;/a&gt;, &lt;a href="http://nordicruby.org/"&gt;Nordic Ruby&lt;/a&gt;, &lt;a href="http://rubykaigi.org/2011/en"&gt;Rubykaigi&lt;/a&gt;, &lt;a href="http://www.spaconference.org/spa2011/index.php"&gt;SPA&lt;/a&gt; ) resulting in a lot of traveling.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I'm slowly regrouping and have a little bit more time to settle here in London.  Time to start blogging again - plenty of material to do so.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Getting cosy with MRI Ruby</title>
    <link href="http://jabberwocky.eu/2011/04/28/getting-cosy-with-mri-ruby/" rel="alternate"/>
    <id>http://jabberwocky.eu/2011/04/28/getting-cosy-with-mri-ruby/</id>
    <published>2011-04-28T00:00:00Z</published>
    <updated>2011-04-28T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;Have you ever wondered what is going on in the entrails of MRI Ruby ?
I certainly have. I started out studying engineering because I wanted to know how everything works. As it turned out, every fact just generated more questions, but that won't keep me from trying.&lt;/p&gt;

&lt;p&gt;A little bit of poring through the source code (ruby 1.9.2) yielded some tools which can provide helpful insights for this research&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Have you ever wondered what is going on in the entrails of MRI Ruby ?
I certainly have. I started out studying engineering because I wanted to know how everything works. As it turned out, every fact just generated more questions, but that won't keep me from trying.&lt;/p&gt;

&lt;p&gt;A little bit of poring through the source code (ruby 1.9.2) yielded some tools which can provide helpful insights for this research.&lt;/p&gt;

&lt;p&gt;You're probably already aware that a Ruby program is executed like so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;parsing&lt;/em&gt;: the program is tokenized, lexed and interpreted into an Abstract Syntax Tree (AST). This AST is basically the source code reduced to a tree form, which looks vaguely lispy in construction.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;compilation&lt;/em&gt;: this tree is compiled to a set of instructions for the Ruby virtual machine.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;execution&lt;/em&gt;: the instructions are then executed by the ruby virtual machine.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here are some tools, built-in in ruby, to see what happens to a bit of code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parsing&lt;/strong&gt;&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;ruby --dump parsetree code.rb&lt;/pre&gt;


&lt;p&gt;say code.rb contains just one statement:&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;answer = 42&lt;/pre&gt;


&lt;p&gt;The corresponding AST yielded by this option:&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;
# @ NODE_SCOPE (line: 1)
# +- nd_tbl: :answer
# +- nd_args:
# |   (null node)
# +- nd_body:
#     @ NODE_DASGN_CURR (line: 1)
#     +- nd_vid: :answer
#     +- nd_value:
#         @ NODE_LIT (line: 1)
#         +- nd_lit: 42
&lt;/pre&gt;


&lt;p&gt;This gives us an insight in what constitutes an AST node for Ruby.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compilation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2 ways to see the instructions produced by compilation.&lt;/p&gt;

&lt;p&gt;The first one is a dump parameter like the one above:&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;ruby --dump insns code.rb&lt;/pre&gt;


&lt;p&gt;outputs:&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;== disasm: &lt;RubyVM::InstructionSequence:&lt;main&gt;@test&gt;====================
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] answer     
0000 trace            1                                               (   1)
0002 putobject        42
0004 dup              
0005 setdynamic       answer, 0
0008 leave
&lt;/pre&gt;


&lt;p&gt;The second way to get information somewhat more tricky - in this case a C macro needs to be 'turned on' for it to work.  A hint in the comments of &lt;a href="https://github.com/ruby/ruby/blob/trunk/compile.c"&gt;compile.c&lt;/a&gt;:&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;
 * debug level:
 *  0: no debug output
 *  1: show node type
 *  2: show node important parameters
 *  ...
 *  5: show other parameters
 * 10: show every AST array
&lt;/pre&gt;


&lt;p&gt;There are two ways to set CPDEBUG: you can add a parameter to the compilation in the makefile
-DCPDEBUG=5
Or you can change the default value directly in compile.c&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;
#ifndef CPDEBUG
#define CPDEBUG 5
#endif
&lt;/pre&gt;


&lt;p&gt;In both cases, recompilation is necessary, and will produce more output than usual.
Running the same minimal program code.rb yields a whole lot of output about the generated instructions, maybe more than is useful, depending on how deep you want to go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution in the VM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to see output at the execution level: pointers, heaps, frame pointers, there's another debug constant you can activate.  In &lt;a href="https://github.com/ruby/ruby/blob/trunk/vm.c"&gt;vm.c&lt;/a&gt;, change the value of PROCDEBUG to a non-zero value:&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;
#define PROCDEBUG 1
&lt;/pre&gt;


&lt;p&gt;Apparently, this causes segmentation faults out of the box, but by &lt;a href="http://redmine.ruby-lang.org/issues/4630"&gt;commenting out some stuff&lt;/a&gt; I was able to get it compiled.  This causes an output like so:&lt;/p&gt;

&lt;pre  class="brush: cpp"&gt;
---
envptr: 0x100482f48
orphan: 0x100887358
inheap: 0x0
lfp:    0x100482f48
dfp:    0x100482f48
&lt;internal:gem_prelude&gt;:1:in `require': cannot load such file -- rubygems.rb (LoadError)
  from &lt;internal:gem_prelude&gt;:1:in `&lt;compiled&gt;'
&lt;/pre&gt;


&lt;p&gt;OK, not very enlightening still. Waiting for the ruby-core's feedback on that one.&lt;/p&gt;

&lt;br/&gt;


&lt;p&gt;By running these few commands on extremely simple programs, it seems to me that we can get a better insight into how it works.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: setting tabstop=8 (in vim, or tab = 8 spaces in other editors) gives you the proper incrementation for the Ruby source code.  I had to find out.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The rise and fall of methodologies</title>
    <link href="http://jabberwocky.eu/2011/03/31/the-rise-and-fall-of-methodologies/" rel="alternate"/>
    <id>http://jabberwocky.eu/2011/03/31/the-rise-and-fall-of-methodologies/</id>
    <published>2011-03-31T00:00:00Z</published>
    <updated>2011-03-31T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;In my years as a software developer, I've seen several methodologies primed as the next big thing, the one way that would ensure a higher success rate of all software projects.&lt;/p&gt;

&lt;p&gt;Let's see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;waterfall in large enterprise (ah, the scores of UML diagrams)&lt;/li&gt;
&lt;li&gt;XP-scrum-agile&lt;/li&gt;
&lt;li&gt;Kanban&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There's an eternal hype curve, as with technology. Oh look, &lt;em&gt;this&lt;/em&gt; will solve all our problems. Then some years laters, outcries because the results don't match the expectations&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;In my years as a software developer, I've seen several methodologies primed as the next big thing, the one way that would ensure a higher success rate of all software projects.&lt;/p&gt;

&lt;p&gt;Let's see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;waterfall in large enterprise (ah, the scores of UML diagrams)&lt;/li&gt;
&lt;li&gt;XP-scrum-agile&lt;/li&gt;
&lt;li&gt;Kanban&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There's an eternal hype curve, as with technology. Oh look, &lt;em&gt;this&lt;/em&gt; will solve all our problems. Then some years laters, outcries because the results don't match the expectations.&lt;/p&gt;

&lt;p&gt;Recently, there's been some backlash against dogmatic agile.  Dan North's &lt;a href="http://www.infoq.com/presentations/Deliberate-Discovery"&gt;deliberate discovery&lt;/a&gt; is one, Fred George's &lt;a href="http://www.infoq.com/presentations/Leaner-Programmer-Anarchy"&gt;Programming Anarchy&lt;/a&gt; (both good talks, both coincidentally ex-Thoughtworkers), or Zed Shaw's macho &lt;a href="http://programming-motherfucker.com/"&gt;'Programming, Motherfucker'&lt;/a&gt;, a (hopefully) less serious one.&lt;/p&gt;

&lt;p&gt;Here's the thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's NEVER easy to drive a project.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every project needs to be considered on its own, the task to accomplish, the shareholders, the team. Time needs to go into pondering how to handle each of these, how to navigate the ecosystem.&lt;/p&gt;

&lt;p&gt;I know we, as developers, would like to be given the golden receipe. Laziness is our virtue, and we would like to have a clear algorithm so that we can just concentrate on the fun parts. And this makes us easy targets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gurus will not tell you about complexity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm sure most gurus are genuinely convinced of what they're selling. They have worked in software, stumbled upon a good idea, and in their own context, applied it with the necessary creativity (hell, they were inventing), it works.&lt;/p&gt;

&lt;p&gt;But they're also in the business of convincing (and maybe to sell books, courses, talks etc). That requires one-liners, clear and simple ideas.  Theories that can be grasped immediately. They won't add multiple caveats to every simple statements, because that could be confusing and off-putting.&lt;/p&gt;

&lt;p&gt;There are no easy receipes. Every practice needs to be assessed with a critical eye, and reassessed constantly. In some environments, with some people they'll work, and sometimes they won't, and then we need to think, ponder and improvise instead of sticking to the letter of any book.&lt;/p&gt;

&lt;p&gt;Not saying that there is no value in existing methodologies. But the only methodology that works lives in the negative space between methodologies.&lt;br/&gt;
Read. Pick and mix.  Use brains.&lt;/p&gt;

&lt;p&gt;A bit like growing up - time to start relying on our own hearts and minds.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>HTML5, pubsub and browser push</title>
    <link href="http://jabberwocky.eu/2011/02/02/html5-pubsub-and-browser-push/" rel="alternate"/>
    <id>http://jabberwocky.eu/2011/02/02/html5-pubsub-and-browser-push/</id>
    <published>2011-02-02T00:00:00Z</published>
    <updated>2011-02-02T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;I'm currently part of the team working on the prototype of an &lt;a href="http://www.youtube.com/user/vrtmedialab#p/a/u/1/ExCqfVwlnxU"&gt;interesting web application&lt;/a&gt;.  One of the features of this application is a constant message stream (think Twitter) pushed to the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The browser&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a first phase of the project we can count on a HTML5 enabled browser, so that allows us to use one of the options HTML5 offers for browser push, basically functionalities built in the browser which can be accessed with javascript. These are:&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I'm currently part of the team working on the prototype of an &lt;a href="http://www.youtube.com/user/vrtmedialab#p/a/u/1/ExCqfVwlnxU"&gt;interesting web application&lt;/a&gt;.  One of the features of this application is a constant message stream (think Twitter) pushed to the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The browser&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a first phase of the project we can count on a HTML5 enabled browser, so that allows us to use one of the options HTML5 offers for browser push, basically functionalities built in the browser which can be accessed with javascript. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;websockets: these sockets allow bidirectional communication&lt;/li&gt;
&lt;/ul&gt;


&lt;pre class="brush: javascript"&gt;
 var ws = new WebSocket("ws://websocket_host/websocket");

 ws.onmessage = function(evt) {
   doSomethingWithMessage(evt);
 }

 ws.onopen = function() {
   subscribe();
 }

 ws.onclose = function() {
   alert('whoops !  lost connection');
 }
&lt;/pre&gt;


&lt;p&gt;obviously, the events callbacks should be modified to the desired action.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;eventsource: one directional, push only&lt;/li&gt;
&lt;/ul&gt;


&lt;pre class="brush: javascript"&gt;
var source = new EventSource('/eventsource');

source.onmessage = function (event)
{
  doSomethingWithMessage(evt);
};

source.onerror = function (event)
{
  alert('whoops !  lost connection');
};

source.onopen = function (event)
{
  subscribe();
};
&lt;/pre&gt;


&lt;p&gt;For older browsers (anything that is not Chrome, Firefox 4, Safari or Opera at the time of writing) the push mechanism needs to be replaced by long polling, i.e. a regular check for the resource.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The interaction between browser and back-end is different from our usual client-server relationship.
Essentially, the browser establishes a subscribe relationship to the server.
Websockets create a bidirectional relationship, in that they both subscribe to something on server side but also publish back to the server (hence pubsub).&lt;/p&gt;

&lt;p&gt;Your standard apache is not equipped for this, because it only handles classic request-response (as far as I can tell, I might be missing something). A server needs to be able to react to events: what is called an evented server.  Added to that a publish-subscribe mechanism should be used, to dialogue with the browser.&lt;/p&gt;

&lt;p&gt;I investigated two possible configurations, in Ruby: mongrel2 with ZeroMQ, and thin with cramp and redis.  &lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt; would certainly have been another option, but I stuck with Ruby since it might be easier for maintenance, for the time being at least (node might still be an alternative later).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mongrel2 with 0MQ&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I fell for &lt;a href="http://www.zeromq.org/intro:read-the-manual"&gt;0MQ&lt;/a&gt; immediately, and will certainly be considering it for future projects, because it has a nice bare-bones feel to it.  It aims to supercharge existing sockets and connections. It also has easy ruby bindings.&lt;/p&gt;

&lt;blockquote&gt;A 0MQ socket is what you get when you take a normal TCP socket, inject it with a mix of radioactive isotopes stolen from a secret Soviet atomic research project, bombard it with 1950-era cosmic rays, and put it into the hands of a drug-addled comic book author with a badly-disguised fetish for bulging muscles clad in spandex.&lt;/blockquote&gt;


&lt;p&gt;Mongrel2 is another story.  While I like what it promises, the documentation is a bit sparse, and I had to dig through the internets to get my configuration right.  Mongrel2 integrates with 0MQ.  It offers handlers, which can be managed with Ruby.
Mongrel2 is language agnostic, and stores its configuration in sqlite3. People who have looked at the code (I haven't yet) tell me it's clean and well-structured.&lt;/p&gt;

&lt;p&gt;Mongrel2's basic config offers publish and subscribe handler, to have the bidirectional communication with the websocket. Good examples &lt;a href="http://www.ioncannon.net/programming/1410/browser-based-push-notifications-with-mongrel2-and-eventsource/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So I got it running, but it took a certain amount of pain, especially in getting routing right.&lt;/p&gt;

&lt;p&gt;But it works: mongrel2 creates 2 handlers (0mq queues with pubsub) to interact with the websocket.  These 0mq sockets can be connected to from any other process, and that other process can publish any data it needs to push the browser, and handle any messages that come in.
Excerpt of mongrel configuration:&lt;/p&gt;

&lt;pre class="brush: ruby"&gt;
root_dir = Dir(base='html/', index_file='index.html', default_ctype='text/plain')

esupdates = Handler(send_spec='tcp://127.0.0.1:9999', send_ident='54c6755b-9628-40a4-9a2d-cc82a816345e',
                    recv_spec='tcp://127.0.0.1:9998', recv_ident='')

routes = {
    '/websocket': esupdates,
    '/': root_dir
}
(...)
&lt;/pre&gt;


&lt;p&gt;Since the code of the corresponding ruby handler is a bit long, I put a bare-bones commented handler in &lt;a href="https://gist.github.com/819022"&gt;this gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redis with Cramp and thin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the meantime, I'd found another, &lt;a href="https://gist.github.com/348262"&gt;pure ruby example&lt;/a&gt; in the Redis documentation.&lt;/p&gt;

&lt;p&gt;Basically, &lt;a href="https://github.com/lifo/cramp.git"&gt;cramp&lt;/a&gt; is a layer on top of sinatra which adds the functionality to talk with websockets.  It makes writing a controller for the websocket blindingly simple, by adding a couple of handy callbacks.
Sinatra (well, Rack) can then run on top of thin, which is an evented server.
You need to use the edge version of cramp at the moment, because older versions have MySQL dependencies.  The ORM has been removed in newer versions to just leave the controller DSL.&lt;/p&gt;

&lt;p&gt;This choice ended up winning, because Redis is also used in another local project so the know-how is there.  The fact that configuration and use were extremely simple and in ruby contributed to the choice.  It also turned out that having named pubsub channels and the ability to subscribe based on a regular expression fitted well with our problem domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://redis.io/"&gt;Redis&lt;/a&gt; has a lot of good functionality combined with a friendly programmer interface: we also use the sets, sorted sets and the key-value store. It's blazingly fast.  Check out the &lt;a href="http://try.redis-db.com/"&gt;interactive tutorial&lt;/a&gt; if you haven't played with it yet. The maintainer, Salvatore Sanflippo is a nice guy (being paid by VMWare to work on his stuff full time), which always helps.&lt;/p&gt;

&lt;p&gt;The principle is basically the same as for the mongrel2 setup: starting a sinatra-cramp app on Thin with eventmachine, which will listen to the browser and publish to it. Cramp provides a number of callbacks to handle incoming messages.&lt;/p&gt;

&lt;pre class="brush: ruby"&gt;
require 'sinatra/base'
require 'cramp'
require 'yajl'
require 'daemons'

class ApplicationStreamController &lt; Cramp::Websocket
  on_start :create_redis
  on_finish :destroy_redis
  on_data :received_data

  def create_redis
    @pub = EventedRedis.connect
    @sub = EventedRedis.connect
  end
  def destroy_redis
    @pub.close_connection_after_writing
    @sub.close_connection_after_writing
  end

  def received_data(data)
    msg = parse_json(data)

    # handle received data here
    case msg[:action]
    when 'join'
      handle_join(msg)
    end
  end

  # message channel is the redis channel which the socket subscribes to
  def handle_join
    @sub.subscribe(msg[:channel]) do |type, channel, message|
       render message
    end
  end

end
&lt;/pre&gt;


&lt;p&gt;Redis is used in this example as the publish-subscribe pipe to make any other process send information to this process, which is then pushed to the browser.
I'd like to add the functionality to talk with Eventsource to Cramp (instead of websockets), since we only push to the browser - I'll see if I find the time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: people suggest using &lt;a href="https://github.com/mloughran/em-hiredis"&gt;em-hiredis&lt;/a&gt; for non-blocking redis, and the slimmer &lt;a href="https://github.com/igrigorik/em-websocket"&gt;em-websocket&lt;/a&gt; instead of going through the layers of cramp. Sounds interesting, and I'll definitely investigate. socket.io is rumored to provide graceful degradation from the html5 features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ingredients for browser push:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;javascript websocket or eventsource in the browser&lt;/li&gt;
&lt;li&gt;back-end evented server to interact/react to pubsub&lt;/li&gt;
&lt;li&gt;back-end mechanism that speaks the right http to push messages to the browser&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Two possible configurations were presented here, one with mongrel2 and zeromq, the other with sinatra/cramp on thin and redis.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Tail call optimization</title>
    <link href="http://jabberwocky.eu/2010/11/23/tail-call-optimization/" rel="alternate"/>
    <id>http://jabberwocky.eu/2010/11/23/tail-call-optimization/</id>
    <published>2010-11-23T00:00:00Z</published>
    <updated>2010-11-23T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Tail_call"&gt;Tail call optimization&lt;/a&gt;: when in recursion, you can just reuse the stack of the recursive function you're calling again and again, instead of creating a new stack every time.  This means saving memory and gaining speed, and that count for a lot when you're, say, calculating a large fibonacci number.&lt;/p&gt;

&lt;p&gt;Now I'd been told time and again that Ruby doesn't do that out of the box, unlike languages like Lisp and Erlang&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Tail_call"&gt;Tail call optimization&lt;/a&gt;: when in recursion, you can just reuse the stack of the recursive function you're calling again and again, instead of creating a new stack every time.  This means saving memory and gaining speed, and that count for a lot when you're, say, calculating a large fibonacci number.&lt;/p&gt;

&lt;p&gt;Now I'd been told time and again that Ruby doesn't do that out of the box, unlike languages like Lisp and Erlang.&lt;/p&gt;

&lt;p&gt;Today, I saw &lt;a href="http://twitter.com/#!/jimweirich/status/7077200209645568"&gt;this tweet&lt;/a&gt; by Jim Weirich, where he pointed to &lt;a href="http://timeless.judofyr.net/tailin-ruby"&gt;a blog post&lt;/a&gt; implementing tail call in Ruby.  The code is very clever - it took me a good few minutes to parse it.  Have a look for yourself, it's worth it !&lt;/p&gt;

&lt;p&gt;Coincidentally &lt;em&gt;(note: not so coincidentally after all, the person reporting the bug, Magnus Holm, is also the person having posted the blog)&lt;/em&gt;, this very morning ruby-core &lt;a href="http://redmine.ruby-lang.org/issues/show/4082"&gt;closed an issue&lt;/a&gt;, showing a &lt;a href="http://redmine.ruby-lang.org/issues/show/1256"&gt;feature on ruby 1.9&lt;/a&gt; I didn't even know existed: the possibility to tell the VM you want tail call !&lt;/p&gt;

&lt;p&gt;To use the same example used in the beautiful ruby code I referred to&lt;/p&gt;

&lt;pre class="brush: ruby"&gt;
 RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization =&gt; true,
  :trace_instruction =&gt; false
}

RubyVM::InstructionSequence.new(&lt;&lt;-EOF).eval
class TCOTest
  # tail-recursive factorial
  def fact( n, acc = 1 )
    if n &lt; 2 then acc else fact( n-1, n*acc ) end
  end

  # length of factorial
  def fact_size( n )
    fact( n ).size
  rescue
    $!
  end   
end
EOF
&lt;/pre&gt;


&lt;p&gt;The performance of the vm-based tail call seems to be slightly better than the ruby one, as could be expected.&lt;/p&gt;

&lt;p&gt;How does it work:&lt;br/&gt;
The main difference seems to be in compile.c, in the function responding to the friendly name of iseq_peephole_optimize.&lt;br/&gt;
As far as I understand, this function deals with a linked list of binary instructions (corresponding to the program), and tries to optimize its execution by introducing some shortcuts where appropriate.&lt;/p&gt;

&lt;p&gt;The relevant code (iobj is the linked list of instructions):&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
if (do_tailcallopt &amp;&amp; iobj-&gt;insn_id == BIN(leave)) {
  /*
   *  send ...
   *  leave
   * =&gt;
   *  send ..., ... | VM_CALL_TAILCALL_BIT, ...
   *  leave # unreachable
   */
  INSN *piobj = (INSN *)get_prev_insn((INSN *)list);

  if (piobj-&gt;insn_id == BIN(send) &amp;&amp;
      piobj-&gt;operands[2] == 0 /* block */
      ) {
      piobj-&gt;operands[3] = FIXNUM_OR(piobj-&gt;operands[3], VM_CALL_TAILCALL_BIT);
  }
}
&lt;/pre&gt;


&lt;p&gt;If we're in the right situation, the instruction gets a VM_CALL_TAILCALL_BIT.
We find our friend the tailcall bit in vm_insnhelper.c in vm_setup_method&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
VALUE *sp, *rsp = cfp-&gt;sp - argc;
/* ... */
rb_iseq_t *iseq = me-&gt;def-&gt;body.iseq;
/* ... */
sp = rsp + iseq-&gt;arg_size;

if (LIKELY(!(flag &amp; VM_CALL_TAILCALL_BIT))) {
  /* ... */
  /* clear local variables */
  for (i = 0; i &lt; iseq-&gt;local_size - iseq-&gt;arg_size; i++) {
      *sp++ = Qnil;
  }
  vm_push_frame(th, iseq,
          VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
          iseq-&gt;iseq_encoded + opt_pc, sp, 0, 0);
    }
  cfp-&gt;sp = rsp - 1 /* recv */;

} else {

  VALUE *p_rsp;
  th-&gt;cfp++; /* pop cf */
  p_rsp = th-&gt;cfp-&gt;sp;

  /* copy arguments */
  for (i=0; i &lt; (sp - rsp); i++) {
      p_rsp[i] = rsp[i];
  }

  sp -= rsp - p_rsp;
  vm_push_frame(th, iseq,
          VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
          iseq-&gt;iseq_encoded + opt_pc, sp, 0, 0);
    }
}
&lt;/pre&gt;


&lt;p&gt;&lt;em&gt;iseq&lt;/em&gt; contains the method instruction sequence.  &lt;em&gt;rsp&lt;/em&gt; contains the stack pointer of the control frame minus the size of the given arguments.  &lt;em&gt;sp&lt;/em&gt; contains the rsp augmented with the new methods' arguments size.&lt;br/&gt;
In the case of tailcall optimization (else) the next frame gets rewritten to the method instructions, else a frame gets pushed normally.&lt;br/&gt;
As far as I understand. I'm not blown away by the naming of the variables or the structure, though I can't claim I would have done an any better job since I'm not that familiar with the subject matter.&lt;/p&gt;

&lt;p&gt;Since this tailcall optimization is an option and not a default, and since it's not one that is widely publicized (to my knowledge) (although I did find some threads when googling), I'm guessing that it's either experimental or that there are some downsides to it.  Does someone know ?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update: Magnus Holm (@judofyr) added notes in &lt;a href="http://timeless.judofyr.net/tailin-ruby"&gt;his blog post&lt;/a&gt; about this feature, and also benchmarking between about 5 ways to implement this !  nice.&lt;/em&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Rubyconf 2010</title>
    <link href="http://jabberwocky.eu/2010/11/14/rubyconf-2010/" rel="alternate"/>
    <id>http://jabberwocky.eu/2010/11/14/rubyconf-2010/</id>
    <published>2010-11-14T00:00:00Z</published>
    <updated>2010-11-14T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;Last few days I attended (and spoke at) Rubyconf. It was the 10th edition, but the first time I did attend.&lt;/p&gt;

&lt;p&gt;Excellent conference.  A good level of presentations, a city that seems made for partying, warm and clear weather.  Kudos to Chad Fowler, Kelly Jeane and crew for making it such a success. I met lots of people, and was glad to see others I'd met at Railsconf in june.&lt;/p&gt;

&lt;p&gt;I was giving a &lt;a href="http://www.rubyconf.org/presentations/34"&gt;talk about concurrency&lt;/a&gt; with &lt;a href="http://games-with-brains.com/"&gt;Eleanor McHugh&lt;/a&gt;.  It was a challenge in 2 ways:&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Last few days I attended (and spoke at) Rubyconf. It was the 10th edition, but the first time I did attend.&lt;/p&gt;

&lt;p&gt;Excellent conference.  A good level of presentations, a city that seems made for partying, warm and clear weather.  Kudos to Chad Fowler, Kelly Jeane and crew for making it such a success. I met lots of people, and was glad to see others I'd met at Railsconf in june.&lt;/p&gt;

&lt;p&gt;I was giving a &lt;a href="http://www.rubyconf.org/presentations/34"&gt;talk about concurrency&lt;/a&gt; with &lt;a href="http://games-with-brains.com/"&gt;Eleanor McHugh&lt;/a&gt;.  It was a challenge in 2 ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first time I presented with Ellie, also the first time for me to present with anyone else at all.&lt;/li&gt;
&lt;li&gt;it's such a vast subject there is too much to say for a 45 minutes session.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;As we found out, Ellie and I have very different presentation styles.  She told me that she prepares slides, but basically ignores them to launch into inspired improvisations.  Being the hacker she is, this leaves most people in the dust but is extremely interesting to those who can keep up.&lt;/p&gt;

&lt;p&gt;I, on the other hand, have to prepare.  I like to rehearse the whole presentation at least 3 times, if possible in front of others.  If I don't I have trouble finding my words, english not being my native language. I forget part of the things I wanted to say. I've found careful preparation allows me to give decent presentations.&lt;/p&gt;

&lt;p&gt;The result of the combination was a bit unsatisfactory for both of us: she probably felt constrained by the prepared slides, and I felt woefully underprepared and more than a little bit nervous. You live and learn.&lt;/p&gt;

&lt;p&gt;The subject, concurrency, is very interesting, fortunately.  You can start from the hardware, dally at the VM, and go into language specifics. Playing around with different languages is great fun. Our slides are &lt;a href="http://www.slideshare.net/ehuard/concurrency-rubies-plural"&gt;here&lt;/a&gt;.  I'm pondering whether to open source all my experiments.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Where is the Global Interpreter Lock ?</title>
    <link href="http://jabberwocky.eu/2010/10/02/where-is-the-global-interpreter-lock-/" rel="alternate"/>
    <id>http://jabberwocky.eu/2010/10/02/where-is-the-global-interpreter-lock-/</id>
    <published>2010-10-02T00:00:00Z</published>
    <updated>2010-10-02T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;MRI Ruby and Rubinius are both blessed with what is called the &lt;a href="http://en.wikipedia.org/wiki/Global_Interpreter_Lock"&gt;Global Interpreter Lock&lt;/a&gt;.  This means that only execute one thread can be executed at a time per VM instance (per CPU core).  See also &lt;a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/"&gt;Ilya Grigorik's&lt;/a&gt; and &lt;a href="http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/"&gt;Yehuda Katz's article&lt;/a&gt; on the subject&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;MRI Ruby and Rubinius are both blessed with what is called the &lt;a href="http://en.wikipedia.org/wiki/Global_Interpreter_Lock"&gt;Global Interpreter Lock&lt;/a&gt;.  This means that only execute one thread can be executed at a time per VM instance (per CPU core).  See also &lt;a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/"&gt;Ilya Grigorik's&lt;/a&gt; and &lt;a href="http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/"&gt;Yehuda Katz's article&lt;/a&gt; on the subject.&lt;/p&gt;

&lt;p&gt;This is not entirely a bad thing, since it means C extensions don't have to be thread-safe (thanks Benoit Daloze for the input). And as the wikipedia entry says, full concurrency can be achieved by spawning separate processes, which each have their own VM, and no shared state at all.&lt;/p&gt;

&lt;p&gt;Rubinius is now getting rid of this lock in its Hydra branch.  This is pretty cool, but it also means that all the C extensions you want to run concurrently will need to be thread-safe. Locks will have to happen at a more fine-grained level: if you need to modify a shared resource, it needs to be protected from indeterministic accesses by different threads.&lt;/p&gt;

&lt;p&gt;But this aside, my aim in this post is to have a look at the MRI code, and see which bits of the code implement the lock.
In ruby 1.9.2, MRI ruby uses native threads, &lt;a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#BASICS"&gt;POSIX threads&lt;/a&gt; for *nix (thread_pthread.c), and windows threads for win (thread_win32.c).  The native interfaces are wrapped in thread.c.&lt;/p&gt;

&lt;p&gt;Native threads have a mechanism to block access to a resource, which is called mutex (as in &lt;a href="http://en.wikipedia.org/wiki/Mutual_exclusion"&gt;mutual exclusion&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So, which resource is protected in this case ? vm_core.h provides a hint
in thread.c, you find the top comment:&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
model 2:
    A thread has mutex (GVL: Global VM Lock or Giant VM Lock) can run.
    When thread scheduling, running thread release GVL.  If running thread
    try blocking operation, this thread must release GVL and another
    thread can continue this flow.  After blocking operation, thread
    must check interrupt (RUBY_VM_CHECK_INTS).
&lt;/blockquote&gt;
&lt;/pre&gt;


&lt;p&gt;vmcore.h:&lt;/p&gt;

&lt;pre&gt;
#if RUBY_VM_THREAD_MODEL == 2
&lt;/pre&gt;


&lt;p&gt;Ruby always has a 'current thread'.&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
RUBY_EXTERN rb_thread_t *ruby_current_thread;
extern rb_vm_t *ruby_current_vm;
&lt;/pre&gt;


&lt;p&gt;The entry point of Ruby is, of course, main.c.
main calls (amongst others) ruby_init (eval.c), which calls (amongst others) Init_BareVM.  There we find rb_thread_set_current_raw(th), which is defined as&lt;/p&gt;

&lt;pre&gt;
#define rb_thread_set_current_raw(th) (void)(ruby_current_thread = (th))
&lt;/pre&gt;


&lt;p&gt;The actual thread creation happens in Init_native_thread, a bit lower in Init_BareVM.  This is a call to the native library to create a thread.&lt;/p&gt;

&lt;p&gt;Nearly every function in the VM (vm.c) starts by getting a thread GET_THREAD(), which gets the current thread to work with.&lt;/p&gt;

&lt;pre&gt;
#define GET_THREAD() ruby_current_thread
&lt;/pre&gt;


&lt;p&gt;There are a few mutexes in the Ruby source, but it's hard to miss the one used for the global interpreter (or VM) lock, thanks to the thread struct member being locked on: global_vm_lock.&lt;/p&gt;

&lt;p&gt;At load time, the mutex in question is initialized (thread.c) in Init_Thread:&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
    /* init thread core */
    {
        /* main thread setting */
        {
            /* acquire global vm lock */
            rb_thread_lock_t *lp = &amp;GET_THREAD()-&gt;vm-&gt;global_vm_lock;
            native_mutex_initialize(lp);
            native_mutex_lock(lp);
            native_mutex_initialize(&amp;GET_THREAD()-&gt;interrupt_lock);
        }
    }
&lt;/pre&gt;


&lt;p&gt;At thread scheduling (thread.c) in rb_thread_schedule_rec: grab current thread and unlock the lock, run the Thread block, and then relock the lock on current thread again.&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
    thread_debug("rb_thread_schedule\n");
    if (!rb_thread_alone()) {
        rb_thread_t *th = GET_THREAD();

        thread_debug("rb_thread_schedule/switch start\n");

        RB_GC_SAVE_MACHINE_CONTEXT(th);
        native_mutex_unlock(&amp;th-&gt;vm-&gt;global_vm_lock);
        {
            native_thread_yield();
        }
        native_mutex_lock(&amp;th-&gt;vm-&gt;global_vm_lock);

        rb_thread_set_current(th);
        thread_debug("rb_thread_schedule/switch done\n");
&lt;/pre&gt;


&lt;p&gt;The function thread_start_func2 (in thread.c) is called at thread creation:&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
/* ... */
    native_mutex_lock(&amp;th-&gt;vm-&gt;global_vm_lock);
    {
        thread_debug("thread start (get lock): %p\n", (void *)th);
        rb_thread_set_current(th);
/* ... */
/* and at the end : if the thread is not the 'main' thread, it releases the mutex */
    if (th-&gt;vm-&gt;main_thread == th) {
        ruby_cleanup(state);
    }
    else {
        thread_cleanup_func(th);
        native_mutex_unlock(&amp;th-&gt;vm-&gt;global_vm_lock);
    }
/* ... */
&lt;/pre&gt;


&lt;p&gt;&lt;em&gt;Interesting factoid&lt;/em&gt;: it seems to be possible to run bits of code without GVL, in a 'blocking region'.  I think this fact is not widely advertized because, as mentioned earlier, anything you want to run that way needs to be thread-safe.&lt;/p&gt;

&lt;pre class="brush: cpp"&gt;
/*
blocking region to release GVL
  rb_thread_blocking_region - permit concurrent/parallel execution.
 
  This function does:
    (1) release GVL.
        Other Ruby threads may run in parallel.
    (2) call func with data1.
    (3) acquire GVL.
        Other Ruby threads can not run in parallel any more.
*/
&lt;/pre&gt;


&lt;p&gt;For my next blog post, I'll try to do a similar analysis for Rubinius, and how they managed to make a branch that is GVL-free.
I needn't add that JRuby, since it benefits from the JVM threading, has never had a global interpreter lock at all.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Why I like giving talks</title>
    <link href="http://jabberwocky.eu/2010/09/27/why-i-like-giving-talks/" rel="alternate"/>
    <id>http://jabberwocky.eu/2010/09/27/why-i-like-giving-talks/</id>
    <published>2010-09-27T00:00:00Z</published>
    <updated>2010-09-27T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;I've had great news last week: the proposal &lt;a href="http://www.slideshare.net/feyeleanor"&gt;Ellie McHugh&lt;/a&gt; and I made was accepted for Rubyconf !
This means I have 3 confirmed speaking engagements this fall, all around the same topic: concurrency.  Once in Amsterdam at &lt;a href="http://rubyandrails.eu/speakers/elise-huard"&gt;RubyAndRails&lt;/a&gt;, once in Ghent, at &lt;a href="http://arrrrcamp.be/talks#talk_82"&gt;arrrrcamp&lt;/a&gt;, and then at &lt;a href="http://rubyconf.org/presentations/34"&gt;Rubyconf&lt;/a&gt;&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I've had great news last week: the proposal &lt;a href="http://www.slideshare.net/feyeleanor"&gt;Ellie McHugh&lt;/a&gt; and I made was accepted for Rubyconf !
This means I have 3 confirmed speaking engagements this fall, all around the same topic: concurrency.  Once in Amsterdam at &lt;a href="http://rubyandrails.eu/speakers/elise-huard"&gt;RubyAndRails&lt;/a&gt;, once in Ghent, at &lt;a href="http://arrrrcamp.be/talks#talk_82"&gt;arrrrcamp&lt;/a&gt;, and then at &lt;a href="http://rubyconf.org/presentations/34"&gt;Rubyconf&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Why speak at all ?  It means tons of extra work, the preparation, the slides ... and there's no immediate return on investment - it actually costs you money, traveling doesn't come cheap.  I'm also a fairly shy person, so there's some nerves involved.
I'll tell you my reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I usually pick a topic that interests me, and take it as an opportunity to dig into it until I know all I possibly ever wanted to know about it.  Take concurrency: I'm reading about threads, CPUs, architectures, writing examples in different languages, academic papers, blog posts, mailing topics ... Nothing to sharpen the mind and create an incentive like the prospect of having to talk about it in front of a group of experts.&lt;/li&gt;
&lt;li&gt;the talk grows organically, as does your knowledge of the subject, every time you give it. You get questions, feedback, new tracks to research.&lt;/li&gt;
&lt;li&gt;you get to meet lots of people. The other speakers, who are often the programmers whose projects we use every day.  But also other devs, who come up to you to discuss things after you talked.&lt;/li&gt;
&lt;li&gt;well, I won't lie, you also get your name about, of course.  As long as your talk is decent, that is.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Anyway, I'd really recommend it.  If you have something to say, and you feel like those reasons would apply to you too, why not give it a try ?&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The distributed Facebook killer</title>
    <link href="http://jabberwocky.eu/2010/09/17/the-distributed-facebook-killer/" rel="alternate"/>
    <id>http://jabberwocky.eu/2010/09/17/the-distributed-facebook-killer/</id>
    <published>2010-09-17T00:00:00Z</published>
    <updated>2010-09-17T00:00:00Z</updated>
    <author>
      <name>Elise Huard</name>
    </author>
    <summary type="html">&lt;p&gt;Last spring, 4 students launched a new project called &lt;a href="http://www.joindiaspora.com/"&gt;Diaspora&lt;/a&gt;.  Their ambition was to create a distributed social network: everyone has their own node, and has total control over their data and how they decide to share them.  They were asking for donations via the Kickstarter platform.&lt;/p&gt;

&lt;p&gt;As it happened, they had the right idea at the right time, as Facebook had just changed their privacy policy in a murky, vaguely threatening way, which made many geeks very suspicious&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Last spring, 4 students launched a new project called &lt;a href="http://www.joindiaspora.com/"&gt;Diaspora&lt;/a&gt;.  Their ambition was to create a distributed social network: everyone has their own node, and has total control over their data and how they decide to share them.  They were asking for donations via the Kickstarter platform.&lt;/p&gt;

&lt;p&gt;As it happened, they had the right idea at the right time, as Facebook had just changed their privacy policy in a murky, vaguely threatening way, which made many geeks very suspicious.&lt;br/&gt;
Plus, it sounded cool, right ?  Never mind that this &lt;a href="http://opensource.appleseedproject.org/"&gt;kind&lt;/a&gt; &lt;a href="http://identi.ca/doc/source"&gt;of&lt;/a&gt; &lt;a href="http://diso-project.org/"&gt;projects&lt;/a&gt; had been floating around for quite a while.&lt;/p&gt;

&lt;p&gt;So they hit the jackpot, and got more than 100,000 dollars to start working on their idea.&lt;/p&gt;

&lt;p&gt;Fast-forward to this week.  Their work, a Rails3 project, is &lt;a href="http://github.com/diaspora/diaspora"&gt;open sourced on github&lt;/a&gt;.  There's much loud disappointment in the developers' community, because there are almost no tests, the code's not that great, the license is wonky ... and generally, they were expecting something, I don't know ... more spectacular ?&lt;/p&gt;

&lt;p&gt;Hello ?  These are 4 inexperienced students.  What are the odds that even one of them is a genius ?  Will throwing money at them make it so ? They only had 4 or 5 months. The budget they got, while very decent seed money, is small change by Facebook development standard.&lt;/p&gt;

&lt;p&gt;Let's not throw out the baby (distributed social networking) with the bath water just yet.&lt;/p&gt;

&lt;blockquote&gt;will someone just write a goddamned "social networking" protocol on top of XMPP already so people will shut up about diaspora. (&lt;a href="http://twitter.com/#!/aeden/status/24769186664"&gt;aeden on twitter&lt;/a&gt;)&lt;/blockquote&gt;


&lt;p&gt;I'll go one further.  The result should be deliverable as executables for (gasp) Windows and Mac, with large friendly letters and pretty, non-threatening icons.  Because if you want your gran and the baker next door to replace Facebook with it, it'd better not be a bare Rails application.&lt;/p&gt;
</content>
  </entry>
</feed>

