ntecs.de
http://www.ntecs.de/blog
blogSwap is Dead - Long Live (SSD) Swap
http://www.ntecs.de/blog/articles/2010/02/08/swap-is-dead-long-live-ssd-swap
<p>Honestly, did you ever actually make use of the swap partition on your operating system? I don’t remember that my server ever made use of it and that with as little as 256 MB main memory. Nowadays, memory is very cheap and if your system starts to use the swap, something is usually going wrong. Most of the time it simply means that too many processes are running or that some processes use up too much memory or that they are configured to use too much memory, because they are optimized for more recent hardware.</p>
<p>Matthew Dillon, the leader of <a href="http://www.dragonflybsd.org/">DragonFly</a> and well-respected “guru” in the community, revived the swap as a system-wide fast filesystem cache when using SSDs. He extended DragonFly so that not only anonymous memory (i.e. memory not backed by a file) is written to the swap in case of a low physical memory situation, but also other types of memory, especially memory used up by the buffer cache. The buffer cache caches data read from a device (e.g. from a hard disk). By default, all unused physical memory is used for the buffer cache, greatly speeding up reads from that device in case of a buffer cache hit. But memory is limited. So the idea is to use SSDs as 2nd level buffer cache, i.e. when data is eleminated from the in-memory buffer cache because new data is read and the cache is full, it is written to the 2nd level SSD buffer cache, which usually is much larger in size (e.g. 40-120 GB). SSDs are much faster when it comes to random accesses (a hard disk can’t do more than 10 MB/sec) and also linear reads (you can get about 200 MB/sec with cheap SSDs) are almost twice as fast as regular SATA disks.</p>
<p>As SSDs have limited per-cell write cycles (1000 to 10000 depending on the technology), it is also important to limit writes to the SSDs depending on how long you want to use the SSD.</p>
<p>Read more in the <a href="http://leaf.dragonflybsd.org/mailarchive/kernel/2010-02/msg00000.html">thread</a> describing various interesting issues and take a look at the <a href="http://leaf.dragonflybsd.org/cgi/web-man?command=swapcache">swapcache manpage</a> of DragonFly.</p>2010-02-08T12:36:36.295241+01:00HAMMER Presentation at KIT
http://www.ntecs.de/blog/articles/2010/01/28/hammer-presentation-at-kit
<p>Yesterday I gave a <a href="http://www.ntecs.de/sysarch09/HAMMER.pdf">presentation</a> about <a href="http://www.dragonflybsd.org/">DragonFlyBSD</a>’s <a href="http://www.dragonflybsd.org/hammer">HAMMER filesystem</a> at the end of the system architecture lecture here at <a href="http://www.kit.edu/">Karlsruhe Institute of Technology</a> (also well known as University of Karlsruhe). It was quite interesting and exciting to stand in our hugest lecture hall and talk to maybe 150 students about an highly “innovative” topic, at least that’s how our Professor announced my presentation.</p>2010-01-28T16:47:01.384695+01:00Panoramas from Tajikistan Day 1
http://www.ntecs.de/blog/articles/2010/01/11/panoramas-tajikistan-day-1
<p>Here is the first round of panorama pictures taken on the Pamir highway from <a href="http://en.wikipedia.org/wiki/Osh">Osh</a> (Kyrgyzstan) to <a href="http://en.wikipedia.org/wiki/Murghab,_Tajikistan">Murgab</a> (Tajikistan). It was the 30th October 2009.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2840_DSC_2842-3.html"><img title="Sunrise in the kzrgyz mountains" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2840_DSC_2842-3.jpg"></a>
<p>Sunrise in the kyrgyz mountains, early in the morning.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2851_DSC_2856-4.html"><img title="The first high pass still in Kyrgyzstan" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2851_DSC_2856-4.jpg"></a>
<p>The first high pass. We are still in Kyrgyzstan. There we saw a crashed truck fallen down the twisting road, which looked like a scrapped wrack.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2879_DSC_2881-3.html"><img title="Mountain view after leaving Sary-Tash" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2879_DSC_2881-3.jpg"></a>
<p>Great panoramic view of 7000m mountains after leaving Sary-Tash, the last kyrgyz village before Tajikistan. We are close to <a href="http://en.wikipedia.org/wiki/Pik_Lenin">Pik Lenin</a>.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2879_DSC_2881-3-darker.html"><img title="Mountain view after leaving Sary-Tash" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2879_DSC_2881-3-darker.jpg"></a>
<p>The same view as before but a bit darker/higher constrast.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2882_DSC_2885-4.html"><img title="Closer to the mountains" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2882_DSC_2885-4.jpg"></a>
<p>Closer to the mountains.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2889_DSC_2890-2.html"><img title="Even more close to the mountains" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2889_DSC_2890-2.jpg"></a>
<p>Even more close to the mountains.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2891_DSC_2896-6.html"><img title="Heading towards Pik Lenin" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2891_DSC_2896-6.jpg"></a>
<p>Heading towards Pik Lenin, the white mountain in the background. Still on kyrgyz territory.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2932_DSC_2935-4.html"><img title="Pamirs in Tajikistan" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2932_DSC_2935-4.jpg"></a>
<p>In the Pamir highland right after crossing the Tajik border. From now on we are above 4000m for the next couple of hours. On the left you see the border fence to China.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2939_DSC_2946-8.html"><img title="Karakul Lake" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2939_DSC_2946-8.jpg"></a>
<p>Great view towards <a href="http://en.wikipedia.org/wiki/Karakul_Lake">Karakul Lake</a></p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2953_DSC_2957-5.html"><img title="Stone circles at Karakul Lake" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2953_DSC_2957-5.jpg"></a>
<p>Stone circles at Karakul Lake. I don’t remember what my russian driver told me about those circles as my conciousness was only half left (due to stomach problems, hydrogen insufficiency and altitude sickness).</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2960_DSC_2964-5.html"><img title="Stone circles again" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2960_DSC_2964-5.jpg"></a>
<p>The same stone circles, but from another perspective.</p>
<a href="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2965_DSC_2966-2.html"><img title="Drinking water source" src="/blog/articles/2010/01/11/panoramas-tajikistan-day-1/DSC_2965_DSC_2966-2.jpg"></a>
<p>After driving for hours through the desert without any water except the water for cooling the machine (which clearly wasn’t drinkable), this is the place where we recharge our driking water. From here it takes us hours to get to Murgab.</p>
<p>When we arrive <a href="http://en.wikipedia.org/wiki/Murghab,_Tajikistan">Murgab</a> at around 8pm we have over 14 hours behind us. The next morning I wake up with heavy headache, the result of altitude sickness, spending half a day at above 4000m and then the whole night at 3500m.</p>
<p>Stay tuned for Day 2, where I am on the way to the Wakhan Corridor which is only a stone’s throw away from the Afghan border.</p>2010-01-11T17:00:26.847067+01:00Delicious Persian Food
http://www.ntecs.de/blog/articles/2010/01/11/delicious-persian-food
<p>I made some really delicious meals during the last couple of weeks using my new cookbook <a href="http://www.amazon.de/Die-persische-K%C3%BCche-Orient-Originalrezepte/dp/3884726927/">Die persische Küche</a>. I started with Abdugh Xiar, a dessert with yoghurt, cucumber, raisins and walnuts and for the main meal I made Adas Polou, which consists of Basmati rice with dates and black lentils.</p>
<p>Last friday I made Kabab Tabei, which basically is minced meat made in a pan. Also very delicious.</p>
<p>But the highlight was clearly my cooking session on saturday, which resulted in Borani Badenjan, eggplant yoghurt (with a bit too much garlic), Shirin Polou, a feastful meal with stewed chicken and sweet orange rice and for dessert Sholeh Zard, golden rice pudding.</p>2010-01-11T14:55:36.384602+01:00Wee 2.0.0 Released
http://www.ntecs.de/blog/articles/2009/04/07/wee-2-0-0-released
<p>Around 4 years have passed since the last release of Wee.</p>
<h2 id="what_is_wee">What is Wee?</h2>
<p>Wee is a Seaside-inspired <a href="http://www.seaside.st/">1</a> web-framework for building highly-dynamic component-based web-applications.</p>
<h2 id="whats_new">What’s new?</h2>
<ul>
<li>100% Rack based</li>
<li>Support for continuations</li>
<li>JQuery AJAX support</li>
<li>Ruby 1.9 ready</li>
</ul>
<h2 id="distinctive_features">Distinctive Features</h2>
<p>Wee is not just another web framework. It is completely different.</p>
<h3 id="continuations">Continuations</h3>
<p>You can use continuations to model the page flow of the your application, in the same way as you’d call a method in a GUI application. Continuations are optional; nothing in Wee depends on them. Example:</p>
<pre><code><font color="#0000c0"># you can write code like this:</font>
<font color="#804000">if</font> <font color="#804000">callcc</font> <font color="#008000">YesNoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Really?</font><font color="#c000c0">'</font>)
<font color="#0000c0"># do something</font>
<font color="#804000">else</font>
<font color="#0000c0"># something else</font>
<font color="#804000">end</font>
</code></pre>
<p>Without continuations one has to use (ugly) Continuation Passing Style (CPS):</p>
<pre><code>call <font color="#008000">YesNoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Really?</font><font color="#c000c0">'</font>) <font color="#804000">do</font> |<font color="#008080">res</font>|
<font color="#804000">if</font> res
<font color="#0000c0"># do something</font>
<font color="#804000">else</font>
<font color="#0000c0"># something else</font>
<font color="#804000">end</font>
<font color="#804000">end</font>
</code></pre>
<h3 id="backtracking">Backtracking</h3>
<p>Backtracking means that the user can naturally use the browsers back button despite Wee’s statefulness. This is not taken for granted for stateful web frameworks. Behind the scenes, Wee keeps multiple states of the application around with only little help by the programmer.</p>
<h3 id="components">Components</h3>
<p>Contrary to the widely used model/view/controller (MVC) paradigm, Wee tighly couples the controller and the view within a <em>component</em>. Components itself are highly decoupled from the rest of the application and can be reused to construct more complex applications. The powerful programmatic HTML rendering approach further reduces wasting the programmers mind by avoiding switching files (controller/view) or languages (Ruby/HTML). Therefore in Wee everything is written in Ruby. The programmatic HTML renderer is not just a simple HTML builder, it provides very powerful methods for easily generating HTML constructs and registering callbacks. Example:</p>
<pre><code><font color="#0000c0">#</font>
<font color="#0000c0"># Generating a <select> tag</font>
<font color="#0000c0">#</font>
<font color="#0000c0"># select an object from these items</font>
items = [<font color="#c00000">1</font>, <font color="#c00000">2</font>, <font color="#c00000">3</font>, <font color="#c00000">4</font>]
<font color="#0000c0"># the labels shown to the user</font>
labels = items.map {|<font color="#008080">i</font>| i.to_s}
<font color="#0000c0"># render it</font>
r.select_list(items).labels(labels).callback {|<font color="#008080">choosen</font>| p choosen}
<font color="#0000c0"># render a multi-select list, with objects 2 and 4 selected</font>
r.select_list(items).multi.labels(labels).selected([<font color="#c00000">2</font>,<font color="#c00000">4</font>])
</code></pre>
<h3 id="callanswer_mechanism">Call/Answer mechanism</h3>
<p>From callback handlers you can call other components which in turn replace the current components view. The called component can later return (or answer) back to the calling componenent. Example:</p>
<pre><code><font color="#c000c0">class</font> <font color="#008000">YesNoMessageBox</font> < <font color="#008000">Wee</font>::<font color="#008000">Component</font>
<font color="#c000c0">def</font> <font color="#008080">initialize</font>(msg)
<font color="#804000">super</font>()
<font color="#008080">@msg</font> = msg
<font color="#c000c0">end</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.bold(<font color="#008080">@msg</font>)
r.form <font color="#804000">do</font>
r.submit_button.value(<font color="#c000c0">'</font><font color="#c00000">YES</font><font color="#c000c0">'</font>).callback { answer <font color="#c00000">true</font> }
r.space
r.submit_button.value(<font color="#c000c0">'</font><font color="#c00000">No</font><font color="#c000c0">'</font>).callback { answer <font color="#c00000">false</font> }
<font color="#804000">end</font>
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
<font color="#0000c0"># Use call (or callcc) as in the Continuation section above</font>
<font color="#0000c0"># to call a component:</font>
call <font color="#008000">YesNoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Really?</font><font color="#c000c0">'</font>)
</code></pre>
<h2 id="the_classical_hello_world_example">The classical Hello World Example</h2>
<pre><code><font color="#c000c0">require</font> <font color="#c000c0">'</font><font color="#c00000">rubygems</font><font color="#c000c0">'</font> <font color="#804000">if</font> <font color="#008080">RUBY_VERSION</font> < <font color="#c000c0">"</font><font color="#c00000">1.9</font><font color="#c000c0">"</font>
<font color="#c000c0">require</font> <font color="#c000c0">'</font><font color="#c00000">wee</font><font color="#c000c0">'</font>
<font color="#c000c0">class</font> <font color="#008000">HelloWorld</font> < <font color="#008000">Wee</font>::<font color="#008000">Component</font>
<font color="#c000c0">def</font> <font color="#008080">initialize</font>
<font color="#804000">super</font>
add_decoration <font color="#008000">Wee</font>::<font color="#008000">PageDecoration</font>.new(title=<font color="#c000c0">"</font><font color="#c00000">Hello World</font><font color="#c000c0">"</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.h1 <font color="#c000c0">"</font><font color="#c00000">Hello World from Wee!</font><font color="#c000c0">"</font>
r.div.onclick_callback { p <font color="#c000c0">"</font><font color="#c00000">clicked</font><font color="#c000c0">"</font> }.with(<font color="#c000c0">"</font><font color="#c00000">click here</font><font color="#c000c0">"</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
<font color="#008000">Wee</font>.run(<font color="#008000">HelloWorld</font>) <font color="#804000">if</font> <font color="#c00000">__FILE__</font> == <font color="#008080">$0</font>
<font color="#0000c0"># Now point your browser to http://localhost:2000/</font>
</code></pre>
<h2 id="installation">Installation</h2>
<pre><code>gem install wee</code></pre>
<h2 id="more_resources">More Resources</h2>
<ul>
<li>
<p>http://rubyforge.org/projects/wee</p>
</li>
<li>
<p>http://www.ntecs.de/projects/wee/doc/rdoc/</p>
</li>
<li>
<p>http://github.com/mneumann/wee</p>
</li>
</ul>2009-04-07T12:49:43.163656+02:00SAP goes Ruby? (Enterprise Ruby)
http://www.ntecs.de/blog/articles/2009/04/01/sap-goes-ruby-enterprise-ruby
<p>After Sun (Java: <a href="http://jruby.codehaus.org/">JRuby</a>), Microsoft (.NET: <a href="http://www.ironruby.net/">IronRuby</a>), Apple (ObjectiveC: <a href="http://www.macruby.org/">MacRuby</a>) and GemStone (Smalltalk: <a href="http://maglev.gemstone.com/">Maglev</a>) showed their interest in Ruby, another big player – no less than SAP – is working on support for Ruby: <a href="/blog/articles/2009/04/01/sap-goes-ruby-enterprise-ruby/https://www.sdn.sap.com/irj/scn/wiki?path=/display/Research/BlueRuby">BlueRuby</a> – a RubyVM that integrates seamlessly with the ABAP environment.</p>2009-04-01T11:01:41.665476+02:00Wee, Ruby 1.9 and Continuations
http://www.ntecs.de/blog/articles/2009/02/25/wee-ruby-1-9-and-continuations
<p>The last couple of days I spent refactoring my web application framework <a href="http://github.com/mneumann/wee/tree/master">Wee</a>, a <a href="http://seaside.st/">Seaside</a>-like framework for Ruby that I started back in 2004 with a lot of mental help from Avi Bryant (one of the main guys behind Seaside). It’s now approaching a 2.0 release. Wee is now fully <a href="http://rack.rubyforge.org/">Rack</a> based (Rack is a commonly used Ruby Webserver Interface) and the code is in general even cleaner than it was before (huge parts were rewritten). Plus one cool feature: Continuations.</p>
<h2 id="continuations">Continuations</h2>
<p>Yesterday I finally thought it’s time to put back in continuations mainly because of some very interesting developments (i.e. patches) for Ruby 1.8.x, which seems to fix memory leaks that occured when using continuations.</p>
<p>Continuations in Wee were never used as extensively as they were used in Seaside. And it’s interesting to read that <a href="http://www.seaside.st/community/development/seaside28">Seaside 2.8</a> reduced heavy usage of continuations – something that Wee did from the beginning :)</p>
<p>An example says more than thousands words, so here we go:</p>
<pre><code><font color="#c000c0">require</font> <font color="#c000c0">'</font><font color="#c00000">wee</font><font color="#c000c0">'</font>
<font color="#c000c0">class</font> <font color="#008000">Page</font> < <font color="#008000">Wee</font>::<font color="#008000">Component</font>
<font color="#c000c0">def</font> <font color="#008080">initialize</font>
add_decoration <font color="#008000">Wee</font>::<font color="#008000">PageDecoration</font>.new(<font color="#c000c0">'</font><font color="#c00000">Title</font><font color="#c000c0">'</font>)
<font color="#804000">super</font>
<font color="#c000c0">end</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.anchor.callback {
<font color="#804000">if</font> <font color="#804000">callcc</font> <font color="#008000">YesNoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Really delete?</font><font color="#c000c0">'</font>)
<font color="#804000">callcc</font> <font color="#008000">InfoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Deleted!</font><font color="#c000c0">'</font>)
<font color="#804000">else</font>
<font color="#804000">callcc</font> <font color="#008000">InfoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Deleted action aborted</font><font color="#c000c0">'</font>)
<font color="#804000">end</font>
}.with(<font color="#c000c0">"</font><font color="#c00000">delete?</font><font color="#c000c0">"</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
<font color="#c000c0">class</font> <font color="#008000">InfoMessageBox</font> < <font color="#008000">Wee</font>::<font color="#008000">Component</font>
<font color="#c000c0">def</font> <font color="#008080">initialize</font>(msg)
<font color="#008080">@msg</font> = msg
<font color="#804000">super</font>()
<font color="#c000c0">end</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.h1(<font color="#008080">@msg</font>)
r.anchor.callback { answer }.with(<font color="#c000c0">'</font><font color="#c00000">OK</font><font color="#c000c0">'</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
<font color="#c000c0">class</font> <font color="#008000">YesNoMessageBox</font> < <font color="#008000">InfoMessageBox</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.h1(<font color="#008080">@msg</font>)
r.anchor.callback { answer <font color="#c00000">true</font> }.with(<font color="#c000c0">'</font><font color="#c00000">YES</font><font color="#c000c0">'</font>)
r.space(<font color="#c00000">1</font>)
r.anchor.callback { answer <font color="#c00000">false</font> }.with(<font color="#c000c0">'</font><font color="#c00000">NO</font><font color="#c000c0">'</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
<font color="#008000">Wee</font>.runcc(<font color="#008000">Page</font>)
</code></pre>
<p>The interesting part of this example is the anchor tag callback handler of component Page. When clicked it will display a YES/NO message box which will return true if you clicked on YES, otherwise false. When it returns, execution resumes exactly at the point after the <tt>callcc</tt> call. In fact, callcc returns the return value of the called component. A called component returns by calling the <tt>answer</tt> method (it behaves mostly like the regular <tt>return</tt> statement). The concrete mechanism how this all works out is a bit more complicated as it involves installing and removing several decorations to delegate rendering and catch exceptions upon answer, but this is totally unrelated to continuations.</p>
<p>So how would it look without the use of continuations? Well, the callback handler would turn from:</p>
<pre><code><font color="#804000">if</font> <font color="#804000">callcc</font> <font color="#008000">YesNoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Really delete?</font><font color="#c000c0">'</font>)
<font color="#804000">callcc</font> <font color="#008000">InfoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Deleted!</font><font color="#c000c0">'</font>)
<font color="#804000">else</font>
<font color="#804000">callcc</font> <font color="#008000">InfoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Deleted action aborted</font><font color="#c000c0">'</font>)
<font color="#804000">end</font>
</code></pre>
<p>into:</p>
<pre><code>call <font color="#008000">YesNoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Really delete?</font><font color="#c000c0">'</font>) <font color="#804000">do</font> |<font color="#008080">res</font>|
<font color="#804000">if</font> res
call <font color="#008000">InfoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Deleted!</font><font color="#c000c0">'</font>)
<font color="#804000">else</font>
call <font color="#008000">InfoMessageBox</font>.new(<font color="#c000c0">'</font><font color="#c00000">Deleted action aborted</font><font color="#c000c0">'</font>)
<font color="#804000">end</font>
<font color="#804000">end</font>
</code></pre>
<p>Actually in this concrete example it’s not hard to rewrite the code without using continuations. But for more complex examples it would get much worse. For example, using continations, a simple sequential flow like the following one:</p>
<pre><code><font color="#804000">callcc</font> page1
<font color="#804000">callcc</font> page2
<font color="#804000">callcc</font> page3
</code></pre>
<p>would turn into the much less readable equivalent using CPS (“continuation passing style”):</p>
<pre><code>call page1 <font color="#804000">do</font>
call page2 <font color="#804000">do</font>
call page3
<font color="#804000">end</font>
<font color="#804000">end</font>
</code></pre>
<p>Which one would you prefer? The good thing: In Wee you can use both, that’s why I have the two methods <tt>call</tt> and <tt>callcc</tt>, the latter not to mix up with <tt>Kernel.callcc</tt>.</p>
<h2 id="performance_and_memory_usage">Performance and Memory Usage</h2>
<p>The reason why continuations were basically unsupported in Wee for a very long time was that they leaked memory. Since a few months there circulated patches on the ruby-core mailing list that seem to fix those leaks. Actually the reason seams to be that some parts of the stack are not overwritten when calling a function and as such old values keep referenced: a leak is born! I haven’t tried those patches, but I think they work. Instead I tried Ruby 1.9.1. And wow! It’s incredible! Memory usage stays constant at 12 MB, regardless of the number of requests. And performance scales nearly linearily as I increase the number of threads.</p>
<p>For 10000 requests (with one thread) Ruby 1.9.1 takes 16 seconds and requires 12 MB of memory. The same example with Ruby 1.8.7 grows to 329 MB of memory and takes 56 seconds. That’s an increase in performance of factor 3.5 and a 27-fold reduction of memory.</p>
<p>The example I’m using for the benchmark is the following 2-level nested callcc component call:</p>
<pre><code><font color="#c000c0">class</font> <font color="#008000">Benchmark</font> < <font color="#008000">Wee</font>::<font color="#008000">Component</font>
<font color="#0000c0">#</font>
<font color="#0000c0"># calls Called2 then returns</font>
<font color="#0000c0">#</font>
<font color="#c000c0">class</font> <font color="#008000">Called1</font> < <font color="#008000">Wee</font>::<font color="#008000">Component</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.anchor.callback { <font color="#804000">callcc</font> <font color="#008000">Called2</font>.new; answer }.with(<font color="#c000c0">'</font><font color="#c00000">back</font><font color="#c000c0">'</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
<font color="#c000c0">class</font> <font color="#008000">Called2</font> < <font color="#008000">Wee</font>::<font color="#008000">Component</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.anchor.callback { answer }.with(<font color="#c000c0">'</font><font color="#c00000">back</font><font color="#c000c0">'</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
<font color="#c000c0">def</font> <font color="#008080">render</font>(r)
r.anchor.callback { <font color="#804000">callcc</font> <font color="#008000">Called1</font>.new }.with(<font color="#c000c0">"</font><font color="#c00000">click</font><font color="#c000c0">"</font>)
<font color="#c000c0">end</font>
<font color="#c000c0">end</font>
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>Continuations seem to be stable enough and not too expensive in terms of memory and performance in Ruby 1.9 so that there is nothing against using them (wisely) within Wee. This makes Wee the only web framework for Ruby to my knowledge that uses continuations. Coupled with other great features provided by Wee, for example reusable components, backtracking or the programmatic HTML generation, this undoubtly allows Wee to be called one of the most advanced web application frameworks for Ruby. Worth to note is that Wee does not focus on RESTful multi-million page-view serving, scaling applications. Instead Wee focuses on very complex applications, similar as found in traditional GUIs, and to get the job done quick <em>and</em> beautiful.</p>2009-02-25T17:33:33.197308+01:00Postgres 8.4 window functions
http://www.ntecs.de/blog/articles/2009/01/22/postgres-8-4-window-functions
<p>As you can read <a href="http://www.depesz.com/index.php/2009/01/21/waiting-for-84-window-functions/">here</a>, PostgreSQL will contain so called <i>window
functions</i> which is part of the SQL 2008 specification. Now that I know how this feature is named, I know what I was missing for the past 10 years. Window functions allow you to produce aggregated values from each row over a specific set of rows (a partition).</p>
<p>Assuming a table <tt>staff</tt> defined as</p>
<pre><code><font color="#804000">create</font> <font color="#c000c0">table</font> staff (
name <font color="#008000">varchar</font>(<font color="#c00000">30</font>),
dept <font color="#008000">varchar</font>(<font color="#c00000">30</font>),
salaray int
);
</code></pre>
<p>we can now show each staff person together with the average salary of the department he/she belongs to using a very simple SQL statement like</p>
<pre><code><font color="#804000">select</font> name, dept, salary,
avg(salary) over (partition <font color="#c000c0">by</font> dept)
<font color="#c000c0">from</font> staff;
</code></pre>
<p>Without using window functions the necessary SQL statement is considerably more complex and requires ugly subselects and joins:</p>
<pre><code><font color="#804000">select</font> s.name, s.dept, s.salary,
a.avg_salary
<font color="#c000c0">from</font> staff s,
(<font color="#804000">select</font> dept, avg(salary) <font color="#c000c0">as</font> avg_salary
<font color="#c000c0">from</font> staff <font color="#c000c0">group</font> <font color="#c000c0">by</font> dept) <font color="#c000c0">as</font> a
<font color="#c000c0">where</font> s.dept = a.dept
</code></pre>
<p>Window functions can do a lot more, so for example can produce cummulative sums easily.</p>2009-01-22T08:05:23.342068+01:00From VirtualBox to Kvm/Qemu
http://www.ntecs.de/blog/articles/2008/12/04/from-virtualbox-to-kvm-qemu
<p><a href="http://www.virtualbox.org/">VirtualBox</a> is a nice piece of software that lets you easily run another operating system (e.g. Windows) from your host system which in my case is Linux at the moment. But for some obscure timer-related reasons, VirtualBox cannot run <a href="http://www.dragonflybsd.org/">DragonFlyBSD</a>, the system of my desire, whereas all the other “emulators” like <a href="http://www.vmware.com/">VMware</a>, <a href="http://bellard.org/qemu/">Qemu</a> or <a href="http://kvm.qumranet.com/">KVM</a> have no problems running DragonFly.</p>
<p>I tried to <a href="http://leaf.dragonflybsd.org/mailarchive/kernel/2008-12/msg00005.html">patch</a> DragonFly to be able to run within VirtualBox, inspired by an idea of someone else. It’s not perfect, but it works. Nevertheless, the rest of this article is about how to migrate from VirtualBox to Kernel Virtual Machine (KVM<a href="http://kvm.qumranet.com/">5</a>).</p>2008-12-04T10:12:20.06375+01:00O'Browser - OCaml in the Browser
http://www.ntecs.de/blog/articles/2008/11/18/obrowser-ocaml-in-the-browser
<p><a href="http://www.pps.jussieu.fr/~canou/obrowser/tutorial/">O’Browser</a> is an <a href="http://www.ocaml.org/">Objective Caml</a> bytecode interpreter written in Javascript. It is capable of running a stripped down version of OCaml’s standard library. Some example applications can be seen <a href="http://www.pps.jussieu.fr/~canou/obrowser/examples.html">here</a>.</p>
<p>The implementation of the runtime counts around 6000 lines of Javascript code, plus another 7000 lines of OCaml code for the standard library. That’s quite a lot when compared against the approx. 4000 lines of Ruby code, including inline Javascript code of the Ruby core classes, of <a href="http://www.ntecs.de/projects/rubyjs">RubyJS</a>. But it’s definitively a great way to run little OCaml applications within the browser, for those that use OCaml. Unfortunately I never made it to write any larger application in OCaml, I only ever used SML (<a href="http://www.mlton.org/">MLTon</a>) in a more extensive way.</p>
<p>Before I started to work on <a href="http://www.ntecs.de/projects/rubyjs">RubyJS</a> (that’s now around 2 years ago), I also thought about compiling OCaml down to Javascript. My idea was to emit Javascript code instead of running OCaml bytecode within Javascript, and I think together with OCaml’s object model, this approach could be a viable alternative to Google’s Java to Javascript compiler when it comes to performance and static typing. <a href="http://www.ntecs.de/projects/rubyjs">RubyJS</a> can’t simply give you all those static type guarantees and due to it’s dynamic typing system of Ruby where everything is a method call, it can’t be all that fast. But then, we all use Ruby or a similar dynamic language and it is just fast enough, so why stick with Java?</p>2008-11-18T10:36:30.589387+01:00