<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:media="http://search.yahoo.com/mrss"
	>

<channel>
	<title>Marc-André Cournoyer's blog</title>
	<atom:link href="http://macournoyer.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://macournoyer.wordpress.com</link>
	<description>My software passion spreading place</description>
	<pubDate>Thu, 24 Apr 2008 16:31:43 +0000</pubDate>
	<generator>http://wordpress.org/?v=MU</generator>
	<language>en</language>
			<item>
		<title>Speaking at meshU</title>
		<link>http://macournoyer.wordpress.com/2008/04/18/speaking-at-meshu/</link>
		<comments>http://macournoyer.wordpress.com/2008/04/18/speaking-at-meshu/#comments</comments>
		<pubDate>Fri, 18 Apr 2008 13:54:58 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/04/18/speaking-at-meshu/</guid>
		<description><![CDATA[On May 20th, I&#8217;ll be in Toronto presenting at meshU. Probably about climate change or Thin, haven&#8217;t decided yet.
From meshU site:

meshU is a one-day event of 12 focused workshops in three streams (design, development, management) given by those who have earned their stripes in the startup game; people who can talk knowledgeably about everything from [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://www.meshconference.com/meshu/images/meshu.gif" alt="meshU" width="150" align="right" />On May 20th, I&#8217;ll be in Toronto presenting at <a href="http://www.meshconference.com/meshu/" title="meshU">meshU</a>. Probably about climate change or <a href="http://code.macournoyer.com/thin/" title="Thin - yet another web server">Thin</a>, haven&#8217;t decided yet.</p>
<p>From meshU site:</p>
<blockquote><p>
meshU is a one-day event of 12 focused workshops in three streams (design, development, management) given by those who have earned their stripes in the startup game; people who can talk knowledgeably about everything from interface design to using Amazon’s S3 distributed server network. We hope this addition to mesh will meet a growing need in Toronto: the need for practical, down-to-earth information about tools, knowledge and expertise for startups, web designers and developers of all kinds.
</p></blockquote>
<p>There will be some awesome and famous speakers: Daniel Burka and Leah Culver of Pounce, John Resign, creator of jQuery, Kevin Hale of Wufoo, Avi Bryant of Dabble DB, Jon Lax, Ryan Carson, Allistair Croll and Reg Braithwaite, it&#8217;s gonna be crazy-sexy-cool!</p>
<p>I hope to see you there!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/216/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/216/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/216/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=216&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/04/18/speaking-at-meshu/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://www.meshconference.com/meshu/images/meshu.gif" medium="image">
			<media:title type="html">meshU</media:title>
		</media:content>
	</item>
		<item>
		<title>Ruby to C, a couple snippets</title>
		<link>http://macournoyer.wordpress.com/2008/04/16/ruby-to-c-a-couple-snippets/</link>
		<comments>http://macournoyer.wordpress.com/2008/04/16/ruby-to-c-a-couple-snippets/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 20:20:54 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/04/16/ruby-to-c-a-couple-snippets/</guid>
		<description><![CDATA[As you might already know, the Ruby interpreter you&#8217;re (probably) using (the one at ruby-lang.org) know as MRI, for Matz Ruby Interpreter, is written in C. The VM is entirely written in C and most of the standard libraries too. So it seems that the way to make code run faster is really to dive [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>As you might already know, the Ruby interpreter you&#8217;re (probably) using (the one at <a href="http://www.ruby-lang.org/en/" title="Ruby Programming Language">ruby-lang.org</a>) know as <em>MRI</em>, for Matz Ruby Interpreter, is written in C. The VM is entirely written in C and most of the standard libraries too. So it seems that the way to make code run faster is really to dive into C.</p>
<p>Now I hear you yell with your ears all red, eyes full of blood and a big vein pumping on your forehead: <em>But it will be unmaintainable!</em></p>
<blockquote><p>If everything seems under control, you&#8217;re not going fast enough</br><br />
<em><a href="http://www.quotedb.com/quotes/102" title="If everything seems under control, you're just not going fast enough. by Mario Andretti">- Mario Andretti</a></em></p></blockquote>
<p>The hard part is that the C API of MRI lacks documentation. You either have to search through the mailinglist, look at other people&#8217;s code or try to guess from Ruby&#8217;s code. I recently ported a bit of code from Ruby to C and here are a couple of Ruby to C mapping that might help you.</p>
<p>If you&#8217;ve never written or looked at a Ruby extension before, I suggestion reading <a href="http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html" title="How to create a Ruby extension in C in under 5 minutes">Peter Cooper excellent and very simple tutorial</a> on how to set things up.</p>
<h4>Objects are VALUEs</h4>
<table width="100%">
<tr>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>my_var <span style="color:#E28964;">=</span> <span style="color:#3387CC;">nil</span>
this_is_true <span style="color:#E28964;">=</span> <span style="color:#3387CC;">true</span>
some_fixnum <span style="color:#E28964;">=</span> <span style="color:#3387CC;">1</span>
</pre>
<p></code></pre>
</td>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>VALUE my_var = Qnil;
VALUE this_is_true = Qtrue;
VALUE some_fixnum = INT2FIX(<span style="color:#3387CC;">1</span>);
</pre>
<p></code></pre>
</td>
</tr>
</table>
<h4>Strings</h4>
<table width="100%">
<tr>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>string <span style="color:#E28964;">=</span> <span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>hi<span style="color:#65B042;">&quot;</span></span>
</pre>
<p></code></pre>
</td>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>VALUE string = rb_str_new2(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>hi<span style="color:#65B042;">&quot;</span></span>);

<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> Ruby string to C string <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
<span style="color:#99CF50;">char</span> *s = RSTRING_PTR(str);
<span style="color:#99CF50;">int</span> len = RSTRING_LEN(str);
</pre>
<p></code></pre>
</td>
</tr>
</table>
<h4>Object to C struct</h4>
<p>In C you&#8217;ll probably want to store your data in a struct. Ruby provide some things to wrap a struct inside a Ruby object. Also, since Ruby is not aware of the stuff created in the C world we have to be pretty explicit about everything.</p>
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre><span style="color:#E28964;">module</span> <span style="text-decoration:underline;">MyModule</span>
  <span style="color:#E28964;">class</span> <span style="text-decoration:underline;">MyClass</span>
    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">close</span>
      <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>closed</span> <span style="color:#E28964;">=</span> <span style="color:#3387CC;">true</span>
    <span style="color:#E28964;">end</span>
  <span style="color:#E28964;">end</span>
<span style="color:#E28964;">end</span>
</pre>
<p></code></pre>
<p>In C</p>
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre><span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> This is called by Ruby GC when the object is freed</span>
<span style="color:#AEAEAE;font-style:italic;"> * so free all resources used here. We hook it up</span>
<span style="color:#AEAEAE;font-style:italic;"> * in the Data_Wrap_Struct call down there.  <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
<span style="color:#99CF50;">void</span> my_obj_free(my_struct_t *s)
{
  <span style="color:#DAD085;">free</span>(s);
}

<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> Called by Ruby then and instance of your class is created</span>
<span style="color:#AEAEAE;font-style:italic;"> * hooked by rb_define_alloc_func. <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
VALUE <span style="color:#89BDFF;">my_obj_all<span style="color:#89BDFF;">oc</span></span>(VALUE klass)
{
  my_struct_t *s = ALLOC_N(my_struct_t, <span style="color:#3387CC;">1</span>);
  <span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> This stores the struct inside the Ruby object, so you</span>
<span style="color:#AEAEAE;font-style:italic;">   * can get the struct back on each method call. <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
  <span style="color:#E28964;">return</span> Data_Wrap_Struct(klass, <span style="color:#3387CC;">NULL</span>, my_obj_free, s);
}

<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> The actual MyClass#close method, first argument is the</span>
<span style="color:#AEAEAE;font-style:italic;"> * instance object. It&#8217;s hook into our class by the rb_define_method</span>
<span style="color:#AEAEAE;font-style:italic;"> * call in Init_ <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
VALUE <span style="color:#89BDFF;">my_obj_clo<span style="color:#89BDFF;">se</span></span>(VALUE self)
{
  my_struct_t *s;
  <span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> This is where we get the struct back from the Ruby object <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
  Data_Get_Struct(self, my_struct_t, s);

  s-&gt;closed = <span style="color:#3387CC;">1</span>;
}

<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> Init_* is magically called by Ruby to bootstrap your extension,</span>
<span style="color:#AEAEAE;font-style:italic;"> * it&#8217;s like a main function if you will. <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
<span style="color:#99CF50;">void</span> Init_name_of_your_extension()
{
  VALUE mMyModule = rb_define_module(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>MyModule<span style="color:#65B042;">&quot;</span></span>);
  VALUE cMyClass = rb_define_class_under(mMyModule, <span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>MyClass<span style="color:#65B042;">&quot;</span></span>, rb_cObject);  

  rb_define_alloc_func(cMyClass, my_obj_alloc);
  rb_define_method(cMyClass, <span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>close<span style="color:#65B042;">&quot;</span></span>, my_obj_close, <span style="color:#3387CC;">0</span>);
}
</pre>
<p></code></pre>
<h4>Calling methods</h4>
<table width="100%">
<tr>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>obj.<span style="color:#89BDFF;">method_name</span>

result <span style="color:#E28964;">=</span> <span style="color:#E28964;">begin</span>
  obj.<span style="color:#89BDFF;">method_name</span>(arg)
<span style="color:#E28964;">rescue</span>
<span style="color:#AEAEAE;font-style:italic;">  <span style="color:#AEAEAE;font-style:italic;">#</span> …</span>
<span style="color:#E28964;">end</span>
</pre>
<p></code></pre>
</td>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>rb_funcall(obj, rb_intern(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>method_name<span style="color:#65B042;">&quot;</span></span>), <span style="color:#3387CC;">0</span>);
<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> if an error is raised, result will be set to Qundef <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
VALUE result = rb_funcall_rescue(obj, rb_intern(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>method_name<span style="color:#65B042;">&quot;</span></span>), <span style="color:#3387CC;">1</span>, arg);
</pre>
<p></code></pre>
</td>
</tr>
</table>
<h4>Blocks</h4>
<table width="100%">
<tr>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>my_ary.<span style="color:#89BDFF;">each</span> <span style="color:#E28964;">do </span>|<span style="color:#3E87E3;">i</span>|
  puts i
<span style="color:#E28964;">end</span>
</pre>
<p></code></pre>
</td>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>VALUE <span style="color:#89BDFF;">i_ea<span style="color:#89BDFF;">ch</span></span>(VALUE elem, VALUE *obj)
{
  <span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> elem is the yielded object and obj is a pointer to obj down there v <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
  <span style="color:#DAD085;">printf</span>(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span><span style="color:#DDF2A4;">%d</span><span style="color:#DDF2A4;">\n</span><span style="color:#65B042;">&quot;</span></span>, FIX2INT(elem));
  <span style="color:#E28964;">return</span> Qnil;
}
rb_iterate(rb_each, my_ary, i_each, (VALUE) obj);
</pre>
<p></code></pre>
</td>
</tr>
</table>
<h4>Error handling</h4>
<table width="100%">
<tr>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre><span style="color:#E28964;">raise</span> <span style="color:#3E87E3;">ArgumentError</span>, <span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>&#8230;<span style="color:#65B042;">&quot;</span></span>
</pre>
<p></code></pre>
</td>
<td width="50%" valign="top">
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>rb_raise(rb_eArgError, <span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>&#8230;<span style="color:#65B042;">&quot;</span></span>);
<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> To raise an error corresponding to the one in errno <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
rb_sys_fail(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>oops<span style="color:#65B042;">&quot;</span></span>);
</pre>
<p></code></pre>
</td>
</tr>
</table>
<h4>Garbage Collection</h4>
<p>When creating Ruby objects in the C world, Ruby is not aware of the scope of each, it&#8217;s impossible to track when a variable is used and when it&#8217;s not, so it&#8217;s impossible for the garbage collector to know when do leave or sweep objects. If you create a long live object, that will persist for several method calls you have to tell Ruby&#8217;s garbage collector when it&#8217;s in use and when you&#8217;re finished with it. If you don&#8217;t, Ruby GC will free your variable in the worst possible time, ending up with unthinkable tragedies around the world, leaving you homeless and poor for all eternity.</p>
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>VALUE var = rb_str_new2(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span>prout<span style="color:#65B042;">&quot;</span></span>);

<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> Tell Ruby GC this object is in use <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
rb_gc_register_address(&amp;var);
<span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">/*</span> when you&#8217;re finished you can unregister it and let the GC free it <span style="color:#AEAEAE;font-style:italic;">*/</span></span>
rb_gc_unregister_address(&amp;var);
</pre>
<p></code></pre>
<p>Note that you don&#8217;t need to do this if you only use the variable in one method since the control is not given back to Ruby during the method call. Also if the variable is still referenced in the Ruby world it&#8217;s already registered.</p>
<h4>More, more, more!</h4>
<p>This is far from a complete guide to MRI, you&#8217;ll need to dig the <a href="http://ruby-doc.org/doxygen/current/" title="Main Page">Ruby doxygen doc</a> if you need more info.</p>
<p>Now lets port Rails to C!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/215/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/215/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/215/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=215&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/04/16/ruby-to-c-a-couple-snippets/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>
	</item>
		<item>
		<title>How many applications can you fit in your VM ?</title>
		<link>http://macournoyer.wordpress.com/2008/03/21/how-many-applications-does-it-take-to-fill-a-vm/</link>
		<comments>http://macournoyer.wordpress.com/2008/03/21/how-many-applications-does-it-take-to-fill-a-vm/#comments</comments>
		<pubDate>Fri, 21 Mar 2008 21:26:17 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/03/21/how-many-applications-does-it-take-to-fill-a-vm/</guid>
		<description><![CDATA[So there I was last night, unable to sleep after Simone finally did went to sleep. I started to play with Why&#8217;s Freaky Freaky Sandbox. I knew some people thought about using this to run multiple Rails applications inside the same VM but nobody actually did.
Installing the Sandbox
Installing the Sandbox is kinda scary cause you [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://www.colewiebe.com/blog/wp-content/uploads/2007/10/sandbox.jpg" alt="Sanbox" width="200" align="left" />So there I was last night, unable to sleep after Simone finally did went to sleep. I started to play with <a href="http://code.whytheluckystiff.net/sandbox/" title="clone and gut Ruby itself!">Why&#8217;s Freaky Freaky Sandbox</a>. I knew some people thought about using this to run multiple Rails applications inside the same VM but nobody actually did.</p>
<h4>Installing the Sandbox</h4>
<p>Installing the Sandbox is kinda scary cause you have to patch Ruby and install it using <code>setup.rb</code> which is not the typical <code>gem install</code>.</p>
<p>Patch Ruby 1.8.6:</p>
<pre>cd /path/to/src/ruby-1.8.6
wget http://code.whytheluckystiff.net/svn/sandbox/trunk/patch/ruby-1.8.6-sandbox_needs.patch
patch -p1 &lt; ruby-1.8.6-sandbox_needs.patch
make
sudo make install</pre>
<p>Install the Extension:</p>
<pre>svn co http://code.whytheluckystiff.net/svn/sandbox/trunk sandbox
cd sandbox
sudo ruby setup.rb</pre>
<p>See <a href="http://code.whytheluckystiff.net/sandbox/wiki/InstallingTheSandbox" title="InstallingTheSandbox on (Freaky Freaky) Sandbox">InstallingTheSandbox</a> for the official guide.</p>
<h4>What the Sandbox allows?</h4>
<p>It clones the Ruby environment and keeps all the objects seperated in their own freaky freaky sandbox! It&#8217;s a bit like running a VM inside another VM!</p>
<p>Rails + Multiple VMs, yeaaaah baby you guessed it!</p>
<h4>Rack Sandbox</h4>
<p>So I&#8217;m hacking on this thing: <a href="http://github.com/macournoyer/rack_sandbox/tree/master" title="macournoyer's rack_sandbox at master &mdash; GitHub">http://github.com/macournoyer/rack_sandbox</a> that runs a Rack application inside a Sandbox. I was able to run 2 very-very bare bone Rails applications (no db, no session, no plugins) inside the same VM, all served by one single Thin instance!</p>
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre>map <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>http://myfirstapp.com<span style="color:#65B042;">&#8216;</span></span> <span style="color:#E28964;">do</span>
  run <span style="color:#9B859D;">Rack</span>::<span style="color:#89BDFF;">Adapter</span>::<span style="color:#89BDFF;">SandboxedRails</span>.<span style="color:#89BDFF;">new</span>(<span style="color:#3387CC;"><span style="color:#3387CC;">:</span>root</span> =&gt; <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>/path/to/a/rails_app<span style="color:#65B042;">&#8216;</span></span>)
<span style="color:#E28964;">end</span>
map <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>http://mysecondapp.com<span style="color:#65B042;">&#8216;</span></span> <span style="color:#E28964;">do</span>
  run <span style="color:#9B859D;">Rack</span>::<span style="color:#89BDFF;">Adapter</span>::<span style="color:#89BDFF;">SandboxedRails</span>.<span style="color:#89BDFF;">new</span>(<span style="color:#3387CC;"><span style="color:#3387CC;">:</span>root</span> =&gt; <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>/path/to/another/rails_app<span style="color:#65B042;">&#8216;</span></span>)
<span style="color:#E28964;">end</span></pre>
<p></code></pre>
<p>I don&#8217;t fully understand how the Sandbox works, I had to do some crazy hacking to make it work and haven&#8217;t tested it with several Rails applications. A lot more work needs to be done before this is even usable.</p>
<p>But this allows to save all the memory overhead of running a separate ruby process which is about 60 MB on my machine. So instead of costing you 120 MB to run 2 simple Rails app it&#8217;s only around 63 MB.</p>
<p><code>git clone git://github.com/macournoyer/rack_sandbox.git</code></p>
<p>Feel free to clone, pull and fork!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/214/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/214/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/214/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/214/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/214/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/214/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/214/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/214/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/214/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/214/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/214/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/214/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=214&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/03/21/how-many-applications-does-it-take-to-fill-a-vm/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://www.colewiebe.com/blog/wp-content/uploads/2007/10/sandbox.jpg" medium="image">
			<media:title type="html">Sanbox</media:title>
		</media:content>
	</item>
		<item>
		<title>Simone Cournoyer</title>
		<link>http://macournoyer.wordpress.com/2008/03/10/simone-cournoyer/</link>
		<comments>http://macournoyer.wordpress.com/2008/03/10/simone-cournoyer/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 21:05:07 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/03/10/simone-cournoyer/</guid>
		<description><![CDATA[Since a few days now, I have the pleasure to be the father of the most beautiful baby girl in the world. You might say that all parents think their child is the most beautiful, but that&#8217;s because you haven&#8217;t seen mine. I&#8217;m totally objective, ok?
I&#8217;ve already started to teach her some basic Ruby.
  [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://macournoyer.files.wordpress.com/2008/03/simone.jpg?w=150" alt="Simone" width="150" align="left">Since a few days now, I have the pleasure to be the father of the most beautiful baby girl in the world. You might say that all parents think their child is the most beautiful, but that&#8217;s because you haven&#8217;t seen mine. I&#8217;m totally objective, ok?</p>
<p>I&#8217;ve already started to teach her some basic Ruby.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/213/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/213/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/213/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/213/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/213/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/213/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/213/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/213/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/213/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/213/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/213/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/213/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=213&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/03/10/simone-cournoyer/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://macournoyer.files.wordpress.com/2008/03/simone.jpg" medium="image">
			<media:title type="html">Simone</media:title>
		</media:content>
	</item>
		<item>
		<title>Staying Alive with Thin!</title>
		<link>http://macournoyer.wordpress.com/2008/02/24/staying-alive-with-thin/</link>
		<comments>http://macournoyer.wordpress.com/2008/02/24/staying-alive-with-thin/#comments</comments>
		<pubDate>Mon, 25 Feb 2008 04:39:47 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[thin]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/?p=211</guid>
		<description><![CDATA[Thin was the first Ruby server to be able to connect to UNIX domain sockets, giving you a little more speed, so you could spend less time browsing and more time dancing and eating ice creams with the people you love. But only Nginx (that I know of) supports UNIX domain sockets. Non-Nginx users might [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://images.amazon.com/images/P/B00003CXCH.01.LZZZZZZZ.jpg" alt="Travolta" width="200" align="right" />Thin was the <a href="http://macournoyer.wordpress.com/2008/01/26/get-intimate-with-your-load-balancer-tonight/">first Ruby server to be able to connect to UNIX domain sockets</a>, giving you a little more speed, so you could spend less time browsing and more time dancing and eating ice creams with the people you love. But only Nginx (that I know of) supports UNIX domain sockets. Non-Nginx users might like to have time to dance and eat ice creams with the people they love too!</p>
<p>So that&#8217;s why Thin new release (<a href="http://groups.google.com/group/thin-ruby/browse_thread/thread/4eb696ea517fba2b">0.7.0 codename Spherical Cow</a>) supports persistent connections (aka <a href="http://www.io.com/~maus/HttpKeepAlive.html" title="HttpKeepAlive">Keep-Alive</a>).</p>
<h4>Apache &amp; mod_proxy</h4>
<p>Under Apache, if a client requests a persistent connection, the connection to the backend server (through mod_proxy) will also be persistent. That means the time spent opening the connection is saved for subsequent requests because all requests will be sent through the same connection. Even cooler is that you have nothing to do to set that up, unless you&#8217;ve turned Keep-Alive off.</p>
<p>I ran some benchmarks and I got an average gain of 200 req/sec with Keep-Alive on.<br />
<img src="http://macournoyer.files.wordpress.com/2008/02/keep-alive-benchmark.png?w=600" alt="Keep-Alive benchmark" width="600"></p>
<p>Sadly Nginx doesn&#8217;t support persistent connections to backends yet, but it seems to be a <a href="http://wiki.codemongers.com/NginxFeatureRequests" title="NginxFeatureRequests - Nginx Wiki">highly requested feature</a>, and Igor Syseov (author of Nginx) said he&#8217;s working on it several times on the mailing list. Imagine that: UNIX sockets + persistent connections, oooh man!</p>
<h4>Hey we develop too, sometimes!</h4>
<p>Of course you&#8217;ll take advantage of that feature when it&#8217;s just you, Thin and your browser. And we can also benchmark it, just for fun, to get numbers that are sure to give you goose bumps: 7800 req/sec is just, ooooh, aaahh, hummm, yeah, that was good!</p>
<p><img src="http://macournoyer.files.wordpress.com/2008/02/keep-alive.png?w=600" alt="Keep-Alive" width="600"></p>
<h4>Swiftiply</h4>
<p>If you&#8217;re looking for even more speed. Thin can now be used as a <a href="http://swiftiply.swiftcore.org/" title="Swiftcore Swiftiply">Swiftiply</a> client. And it&#8217;s very easy to use:</p>
<pre>thin start --servers 3 --port 8000 --swiftiply</pre>
<p>Just add the <code>--swiftiply</code> option. This also means that any Rack adapter can be run through Swiftiply (using the <code>--rackup</code> option) including Ramaze, Camping, Merb, YourCrazyLittleFrameworkThatIsSoooBetterThenAllTheOtherAndThatSupportRack etc.</p>
<h4>Speed with control</h4>
<p>But what is speed with no control, right?</p>
<p>The main reason why Mongrel couldn&#8217;t support persistent connections was because of Ruby 1024 file/socket descriptors limitation. If you don&#8217;t close the connection (keep them alive) it&#8217;s one less descriptor you can use to process another connection or open a file.</p>
<p>Although EventMachine doesn&#8217;t have an infinite number of file descriptors it was reported to handle more then <a href="http://wisteria.swiftcore.org/index.html">20 000 concurrent connections</a>.</p>
<p>You can now tune the number of connections a Thin server can handle.</p>
<p><code>--max-conns</code>: This sets the maximum number of concurrent connections your Thin server can handle. Setting higher then 1024 might require superuser privileges on some system.</p>
<p><code>--max-persistent-conns</code>: This sets the maximum number of persistent connections your Thin server can handle at the same time. If resource usage is important, you might want to turn that down. You can turn Keep-Alive support off by setting to 0.</p>
<h4>Get it!</h4>
<p>Spherical Cow also comes with a couple bug fixes and tweak.<br />
As usual, you can get the latest version from RubyForge:</p>
<pre>sudo gem install thin</pre>
<p>If you have any question, join the <a href="http://groups.google.com/group/thin-ruby/topics">Google Group</a> or the #thin channel on freenode.</p>
<p>I hope you like it!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/211/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/211/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/211/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=211&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/02/24/staying-alive-with-thin/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://images.amazon.com/images/P/B00003CXCH.01.LZZZZZZZ.jpg" medium="image">
			<media:title type="html">Travolta</media:title>
		</media:content>

		<media:content url="http://macournoyer.files.wordpress.com/2008/02/keep-alive-benchmark.png" medium="image">
			<media:title type="html">Keep-Alive benchmark</media:title>
		</media:content>

		<media:content url="http://macournoyer.files.wordpress.com/2008/02/keep-alive.png" medium="image">
			<media:title type="html">Keep-Alive</media:title>
		</media:content>
	</item>
		<item>
		<title>MoR7 Presentation</title>
		<link>http://macournoyer.wordpress.com/2008/02/20/mor7-presentation/</link>
		<comments>http://macournoyer.wordpress.com/2008/02/20/mor7-presentation/#comments</comments>
		<pubDate>Wed, 20 Feb 2008 19:05:22 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[StandoutJobs]]></category>

		<category><![CDATA[montreal]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[thin]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/02/20/mor7-presentation/</guid>
		<description><![CDATA[Here&#8217;s the code and slides of my presentation : http://github.com/macournoyer/mor7/
Hope you liked it!
       ]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://farm3.static.flickr.com/2237/1904885861_61e35ad169.jpg" alt="Image" width="200" align="right" />Here&#8217;s the code and slides of <a href="http://macournoyer.wordpress.com/2008/02/17/presenting-thin-at-montreal-on-rails/" title="Presenting Thin at Montreal on Rails &laquo; Marc-André Cournoyer&#8217;s blog">my presentation</a> : <a href="http://github.com/macournoyer/mor7/" title="macournoyer's mor7 at master &mdash; GitHub">http://github.com/macournoyer/mor7/</a></p>
<p>Hope you liked it!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/208/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/208/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/208/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=208&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/02/20/mor7-presentation/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://farm3.static.flickr.com/2237/1904885861_61e35ad169.jpg" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>
	</item>
		<item>
		<title>Presenting Thin at Montreal on Rails</title>
		<link>http://macournoyer.wordpress.com/2008/02/17/presenting-thin-at-montreal-on-rails/</link>
		<comments>http://macournoyer.wordpress.com/2008/02/17/presenting-thin-at-montreal-on-rails/#comments</comments>
		<pubDate>Sun, 17 Feb 2008 22:17:55 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[conference]]></category>

		<category><![CDATA[montreal]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[thin]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/02/17/presenting-thin-at-montreal-on-rails/</guid>
		<description><![CDATA[If you&#8217;re in Montreal next Tuesday, be sure to come to the next Montreal on Rails. I&#8217;ll be presenting Thin with a fanfare, dancers and pizza.
RSVP if not already done and do it fast, places are limited.
I&#8217;ll present some new features in the upcoming Spherical Cow release and recode Thin like I did at DempCampCUSEC, [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://farm2.static.flickr.com/1039/1474172910_2f0297017d_t.jpg" alt="MoR" align="left" />If you&#8217;re in Montreal next Tuesday, be sure to come to the <a href="http://www.montrealonrails.com/2008/01/22/announcing-mor-7-presenters-that-was-fast/" title="Montreal on Rails &raquo; Blog Archive &raquo; Announcing MoR 7 presenters (that was fast!)">next Montreal on Rails</a>. I&#8217;ll be presenting Thin with a fanfare, dancers and pizza.</p>
<p><a href="http://upcoming.yahoo.com/event/413826/" title="Montreal on Rails #7 at Standout Jobs (Tuesday, February 19, 2008) - Upcoming">RSVP</a> if not already done and do it fast, places are limited.</p>
<p>I&#8217;ll present some new features in the upcoming <em>Spherical Cow</em> release and recode Thin like I did at <a href="http://macournoyer.wordpress.com/2008/01/18/democampcusec-follow-up/" title="DemoCampCUSEC follow-up &laquo; Marc-André Cournoyer&#8217;s blog">DempCampCUSEC</a>, but this time, with one hand tied being my back and someone yelling at me in Russian. All this in 2 minutes (I don&#8217;t know yet what I&#8217;ll do with the remaining time).</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/207/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/207/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/207/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=207&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/02/17/presenting-thin-at-montreal-on-rails/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://farm2.static.flickr.com/1039/1474172910_2f0297017d_t.jpg" medium="image">
			<media:title type="html">MoR</media:title>
		</media:content>
	</item>
		<item>
		<title>The Flexible Thin Anorexic Gymnast that Democratized Deployment</title>
		<link>http://macournoyer.wordpress.com/2008/02/09/the-flexible-thin-anorexic-gymnast-that-democratized-deployment/</link>
		<comments>http://macournoyer.wordpress.com/2008/02/09/the-flexible-thin-anorexic-gymnast-that-democratized-deployment/#comments</comments>
		<pubDate>Sat, 09 Feb 2008 18:56:16 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<category><![CDATA[thin]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/02/09/the-flexible-thin-anorexic-gymnast-that-democratized-deployment/</guid>
		<description><![CDATA[Thin is fast, I don&#8217;t think I need to prove that again. But what I&#8217;d like to showcase now is Thin extensibility. Most of it is due to Thin being based on Rack. It&#8217;s also why lots of framework are supporting Thin already.
Can Thin replace all images with LOLCAT pics on my site when it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://www.lacourphoto.net/uploaded_images/Headless-Gymnast-WEB-2-742131.jpg" alt="Image" height="200" align="right" /><a href="http://macournoyer.wordpress.com/2008/01/26/get-intimate-with-your-load-balancer-tonight/" title="Get intimate with your load balancer tonight! &laquo; Marc-André Cournoyer&#8217;s blog">Thin is fast</a>, I don&#8217;t think I need to prove that again. But what I&#8217;d like to showcase now is <a href="http://code.macournoyer.com/thin/" title="Thin - yet another web server">Thin</a> extensibility. Most of it is due to Thin being based on <a href="http://rack.rubyforge.org/">Rack</a>. It&#8217;s also why <a href="http://github.com/wycats/merb-core/" title="merb-core on GitHub">lots</a> of <a href="http://vintage.devjavu.com/" title="vintage">framework</a> are <a href="http://ramaze.net/" title="Ramaze">supporting</a> Thin already.</p>
<h4>Can Thin replace all images with LOLCAT pics on my site when it&#8217;s my birthday of a leap year, plz, plz, plz? Cause it should!</h4>
<p>Yeah, you&#8217;re not the first one to ask.</p>
<p><em>config.ru file</em></p>
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre><span style="color:#E28964;">require</span> <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>open-uri<span style="color:#65B042;">&#8216;</span></span>
<span style="color:#E28964;">require</span> <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>hpricot<span style="color:#65B042;">&#8216;</span></span>

<span style="color:#E28964;">class</span> <span style="text-decoration:underline;">LolCater</span>
  <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">initialize</span>(<span style="color:#3E87E3;">app</span>)
    <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>app</span> <span style="color:#E28964;">=</span> app
  <span style="color:#E28964;">end</span>

  <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">call</span>(<span style="color:#3E87E3;">env</span>)
    status, headers, body <span style="color:#E28964;">=</span> <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>app</span>.<span style="color:#89BDFF;">call</span>(env)

    <span style="color:#E28964;">if</span> iz_ma_burdae? <span style="color:#E28964;">&amp;&amp;</span> leap_year?
      doc <span style="color:#E28964;">=</span> <span style="color:#3E87E3;">Hpricot</span>(body)
      doc.<span style="color:#89BDFF;">search</span>(<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>img<span style="color:#65B042;">&#8216;</span></span>).<span style="color:#89BDFF;">set</span>(<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>src<span style="color:#65B042;">&#8216;</span></span>, lolcat_pic_url)
      body <span style="color:#E28964;">=</span> doc.<span style="color:#89BDFF;">to_html</span>
    <span style="color:#E28964;">end</span>

    [status, headers, body]
  <span style="color:#E28964;">end</span>

  <span style="color:#E28964;">private</span>
    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">iz_ma_burdae?</span>
      <span style="color:#9B859D;">Date</span>.<span style="color:#89BDFF;">today</span>.<span style="color:#89BDFF;">month</span> <span style="color:#E28964;">==</span> <span style="color:#3387CC;">11</span> <span style="color:#E28964;">&amp;&amp;</span> <span style="color:#9B859D;">Date</span>.<span style="color:#89BDFF;">today</span>.<span style="color:#89BDFF;">day</span> <span style="color:#E28964;">==</span> <span style="color:#3387CC;">7</span>
    <span style="color:#E28964;">end</span>

    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">leap_year?</span>
      <span style="color:#9B859D;">Date</span>.<span style="color:#89BDFF;">today</span>.<span style="color:#89BDFF;">leap?</span>
    <span style="color:#E28964;">end</span>

    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">lolcat_pic_url</span>
      doc <span style="color:#E28964;">=</span> <span style="color:#3E87E3;">Hpricot</span>(<span style="color:#89BDFF;">open</span>(<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>http://icanhascheezburger.com/?random#top<span style="color:#65B042;">&#8216;</span></span>))
      pic <span style="color:#E28964;">=</span> (doc<span style="color:#E28964;">/</span><span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>div.snap_preview img<span style="color:#65B042;">&#8216;</span></span>).<span style="color:#89BDFF;">first</span>.<span style="color:#89BDFF;">attributes</span>[<span style="color:#65B042;"><span style="color:#65B042;">'</span>src<span style="color:#65B042;">'</span></span>]
    <span style="color:#E28964;">end</span>
<span style="color:#E28964;">end</span>

use <span style="color:#3E87E3;">LolCater</span>
run <span style="color:#9B859D;">Rack</span>::<span style="color:#89BDFF;">Adapter</span>::<span style="color:#89BDFF;">Rails</span>.<span style="color:#89BDFF;">new</span>(<span style="color:#3387CC;"><span style="color:#3387CC;">:</span>root</span> =&gt; <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>/path/to/my/app<span style="color:#65B042;">&#8216;</span></span>)</pre>
<p></code></pre>
<p>That&#8217;s called a Rack <strong>middleware</strong>. It must have a <code>call</code> method and receive a Rack app as the first argument of <code>new</code>. You then tell Thin to <strong>use</strong> this middleware when <strong>run</strong>ning your Rails application. Save the file as <code>config.ru</code>. <strong>.ru</strong> is for Rackup config file.</p>
<p>You can now launch your application with the <code>thin</code> script:</p>
<pre>thin start --rackup config.ru</pre>
<h4>Wai-wai-wait that means I can built my own framework in like 30 LOC and use all of Thin goodness?</h4>
<p>Right! You can start a cluster of your lolcat image replacer app like you would for a Rails app, but specify the <code>--rackup</code> option, which tell Thin to load your application from this file instead to go with the default Rails adapter.</p>
<pre>thin start --rackup config.ru --servers 3</pre>
<p>In fact, here&#8217;s a lil&#8217; framework I built in 35 LOC:</p>
<pre style="background-color:#000;color:#F8F8F8;overflow:auto;line-height:12px;font-size:12px;padding:6px;"><code>
<pre><span style="color:#AEAEAE;font-style:italic;"><span style="color:#AEAEAE;font-style:italic;">#</span> Start w/ thin start -r invisible.rb</span>
<span style="color:#E28964;">require</span> <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>tenjin<span style="color:#65B042;">&#8216;</span></span>

<span style="color:#E28964;">module</span> ::<span style="color:#89BDFF;">Invisible</span>
  <span style="color:#E28964;">class</span> <span style="text-decoration:underline;">Adapter</span>
    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">initialize</span>
      <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>template</span> <span style="color:#E28964;">=</span> <span style="color:#9B859D;">Tenjin</span>::<span style="color:#89BDFF;">Engine</span>.<span style="color:#89BDFF;">new</span>(<span style="color:#3387CC;"><span style="color:#3387CC;">:</span>postfix</span>=&gt;<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>.rbhtml<span style="color:#65B042;">&#8216;</span></span>, <span style="color:#3387CC;"><span style="color:#3387CC;">:</span>layout</span>=&gt;<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>../layout.rbhtml<span style="color:#65B042;">&#8216;</span></span>, <span style="color:#3387CC;"><span style="color:#3387CC;">:</span>path</span>=&gt;<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>home<span style="color:#65B042;">&#8216;</span></span>)
      <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>file</span> <span style="color:#E28964;">=</span> <span style="color:#9B859D;">Rack</span>::<span style="color:#89BDFF;">File</span>.<span style="color:#89BDFF;">new</span>(<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>public<span style="color:#65B042;">&#8216;</span></span>)
    <span style="color:#E28964;">end</span>
    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">call</span>(<span style="color:#3E87E3;">env</span>)
      path <span style="color:#E28964;">=</span> env[<span style="color:#65B042;"><span style="color:#65B042;">'</span>PATH_INFO<span style="color:#65B042;">'</span></span>]
      <span style="color:#E28964;">if</span> path.<span style="color:#89BDFF;">include?</span>(<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>.<span style="color:#65B042;">&#8216;</span></span>)
        <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>file</span>.<span style="color:#89BDFF;">call</span>(env)
      <span style="color:#E28964;">else</span>
        _, controller, action <span style="color:#E28964;">=</span> env[<span style="color:#65B042;"><span style="color:#65B042;">'</span>PATH_INFO<span style="color:#65B042;">'</span></span>].<span style="color:#89BDFF;">split</span>(<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>/<span style="color:#65B042;">&#8216;</span></span>)
        <span style="color:#9B859D;">Invisible</span>.<span style="color:#89BDFF;">const_get</span>(<span style="color:#65B042;"><span style="color:#65B042;">&quot;</span><span style="color:#DAEFA3;"><span style="color:#DAEFA3;">#{</span><span style="color:#DAEFA3;">(</span>controller <span style="color:#E28964;">||</span> <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>home<span style="color:#65B042;">&#8216;</span></span><span style="color:#DAEFA3;">)</span><span style="color:#DAEFA3;"><span style="color:#DAEFA3;">.</span><span style="color:#89BDFF;">capitalize</span></span><span style="color:#DAEFA3;">}</span></span>Controller<span style="color:#65B042;">&quot;</span></span>).<span style="color:#89BDFF;">new</span>(<span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>template</span>, env).<span style="color:#89BDFF;">call</span>(action <span style="color:#E28964;">||</span> <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>index<span style="color:#65B042;">&#8216;</span></span>)
      <span style="color:#E28964;">end</span>
    <span style="color:#E28964;">end</span>
  <span style="color:#E28964;">end</span>
  <span style="color:#E28964;">class</span> <span style="text-decoration:underline;">Controller</span>
    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">initialize</span>(<span style="color:#3E87E3;">template<span style="color:#3E87E3;">,</span> env</span>)
      <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>template</span>, <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>status</span>, <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>env</span>, <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>headers</span> <span style="color:#E28964;">=</span> template, <span style="color:#3387CC;">200</span>, env, {<span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>Content-Type<span style="color:#65B042;">&#8216;</span></span> =&gt; <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>text/html<span style="color:#65B042;">&#8216;</span></span>}
    <span style="color:#E28964;">end</span>
    <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">call</span>(<span style="color:#3E87E3;">action</span>)
      <span style="color:#89BDFF;">send</span>(action)
      <span style="color:#89BDFF;">render</span>(action) <span style="color:#E28964;">unless</span> <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>body</span>
      [<span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>status</span>, <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>headers</span>.<span style="color:#89BDFF;">merge</span>(<span style="color:#65B042;"><span style="color:#65B042;">'</span>Content-Length<span style="color:#65B042;">'</span></span>=&gt;<span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>body</span>.<span style="color:#89BDFF;">size</span>.<span style="color:#89BDFF;">to_s</span>), [<span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>body</span>]]
    <span style="color:#E28964;">end</span>
    <span style="color:#E28964;">protected</span>
      <span style="color:#E28964;">def</span> <span style="color:#89BDFF;">render</span>(<span style="color:#3E87E3;">action<span style="color:#E28964;">=</span><span style="color:#3387CC;">nil</span></span>)
        <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>body</span> <span style="color:#E28964;">=</span> <span style="color:#3E87E3;"><span style="color:#3E87E3;">@</span>template</span>.<span style="color:#89BDFF;">render</span>(action.<span style="color:#89BDFF;">to_sym</span>, instance_variables.<span style="color:#89BDFF;">inject</span>({}) {|<span style="color:#3E87E3;">h</span>,<span style="color:#3E87E3;">v</span>| h[v[<span style="color:#3387CC;">1</span>..<span style="color:#E28964;">-</span><span style="color:#3387CC;">1</span>]] <span style="color:#E28964;">=</span> <span style="color:#89BDFF;">instance_variable_get</span>(v); h})
      <span style="color:#E28964;">end</span>
  <span style="color:#E28964;">end</span>
<span style="color:#E28964;">end</span>

<span style="color:#E28964;">require</span> <span style="color:#65B042;"><span style="color:#65B042;">&#8216;</span>app/controllers<span style="color:#65B042;">&#8216;</span></span>
run <span style="color:#9B859D;">Invisible</span>::<span style="color:#89BDFF;">Adapter</span>.<span style="color:#89BDFF;">new</span></pre>
<p></code></pre>
<p>Full code on my github repo: <a href="http://github.com/macournoyer/invisible/" title="macournoyer's invisible at master &mdash; GitHub">http://github.com/macournoyer/invisible/</a>.</p>
<p>And you know I can&#8217;t help myself but benchmark it:<br />
merb-core: 1865.19 req/sec<br />
invisible: 2428.17 req/sec</p>
<p>(Disclamer: it&#8217;s just for fun, don&#8217;t use that framework ever or I will come in your house when you sleep and steel all your left foot socks).</p>
<h4>Democratizing deployment</h4>
<p>I don&#8217;t know if you get what this means? It means, deploying a Rails or Merb, Ramaze, etc, app is just a matter of writing a simple Rack config file and playing w/ the &#8211;rackup option. <strong>It&#8217;s all the same script and tools now!</strong></p>
<p>For example, there&#8217;s a Ramaze Rack config file in <a href="http://github.com/macournoyer/thin/tree/master/example/ramaze.ru" title="macournoyer's thin at master">example/ramaze.ru</a>, so to deploy your Ramaze application you would.</p>
<pre>thin start --servers 3 --rackup ramaze.ru</pre>
<p>Or create a config file and install it as a runlevel script:</p>
<pre>thin config --rackup ramaze.ru -C myapp.yml
edit myapp.yml
sudo thin install # Installs the runlevel script
mv myapp.yml /etc/thin/myapp.yml</pre>
<p>Or if you prefer to monitor your clusters with God, check out the <a href="http://github.com/macournoyer/thin/tree/master/example/thin.god" title="example/thin.god at master from macournoyer's thin &mdash; GitHub">sample God config</a> file that is a drop-in replacement for Thin&#8217;s runlevel script.</p>
<p>Happy hacking &amp; deploying!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/206/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/206/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/206/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=206&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/02/09/the-flexible-thin-anorexic-gymnast-that-democratized-deployment/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://www.lacourphoto.net/uploaded_images/Headless-Gymnast-WEB-2-742131.jpg" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>
	</item>
		<item>
		<title>Standout Jobs: launched</title>
		<link>http://macournoyer.wordpress.com/2008/01/30/standout-jobs-launched/</link>
		<comments>http://macournoyer.wordpress.com/2008/01/30/standout-jobs-launched/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 21:36:14 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[StandoutJobs]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/2008/01/30/standout-jobs-launched/</guid>
		<description><![CDATA[Yeah I know, I&#8217;m very late on this. I&#8217;m the latest one of the gang to blog about it.
StandoutJobs.com has launched a couple days ago and demoed at DEMO earlier today.
We&#8217;ve worked very hard on this and I&#8217;m really proud of the result!



Please give it a look and let me know what you think!
  [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Yeah I know, I&#8217;m very late on this. I&#8217;m the <a href="http://www.instigatorblog.com/standout-jobs-goes-live/2008/01/28/" title="Standout Jobs Goes Live!">latest</a> <a href="http://siliconisland.ca/2008/01/30/standout-jobs-launching-at-demo-08-live-broadcast-today/" title="Standout Jobs Launching at DEMO 08 - Live Broadcast Today! &laquo; Silicon Island">one</a> of <a href="http://www.danielharan.com/2008/01/29/standoutjobs-is-live-tales-of-a-harrowing-launch/" title="tales of a harrowing launch &#8212; Some French Guy">the</a> <a href="http://www.fsbrainstorm.com/?p=518" title="fsbrainstorm Standout Jobs Launches!">gang</a> to <a href="http://www.garyharan.com/index.php/2008/01/30/standout-jobs-launched-at-demo2008/" title="Gary Haran.com Standout Jobs Launched at DEMO2008">blog</a> <a href="http://blog.alainwong.com/2008/01/28/standout-jobs-launched-today/" title="alain&#8217;s dance blog  &raquo; Blog Archive   &raquo; Standout Jobs launched today">about</a> <a href="http://tvtang.wordpress.com/2008/01/30/standoutjobs-live-from-demo08/" title="StandoutJobs Live From DEMO08 &laquo; Maybe Guard Cats After Series A?">it</a>.</p>
<p><a href="http://standoutjobs.com" title="Changing the Face of Recruiting &laquo; Standout Jobs">StandoutJobs.com</a> has launched a couple days ago and demoed at DEMO earlier today.</p>
<p>We&#8217;ve worked very hard on this and I&#8217;m really proud of the result!</p>
<p><a href="http://standoutjobs.com" title="Changing the Face of Recruiting &laquo; Standout Jobs"><br />
<img src="http://macournoyer.files.wordpress.com/2008/01/soj.png?w=600&h=433" alt="Soj" height="433" width="600"><br />
</a></p>
<p>Please give it a look and let me know what you think!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/203/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/203/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/203/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=203&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/01/30/standout-jobs-launched/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://macournoyer.files.wordpress.com/2008/01/soj.png" medium="image">
			<media:title type="html">Soj</media:title>
		</media:content>
	</item>
		<item>
		<title>Get intimate with your load balancer tonight!</title>
		<link>http://macournoyer.wordpress.com/2008/01/26/get-intimate-with-your-load-balancer-tonight/</link>
		<comments>http://macournoyer.wordpress.com/2008/01/26/get-intimate-with-your-load-balancer-tonight/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 17:46:02 +0000</pubDate>
		<dc:creator>macournoyer</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<category><![CDATA[thin]]></category>

		<guid isPermaLink="false">http://macournoyer.wordpress.com/?p=201</guid>
		<description><![CDATA[The Thin Cheesecake release is out (v0.6.1)!
sudo gem install thin
That tasty and sweet Cheesecake release comes with some new sweet topping: config file support, uses less memory, some speed tweaks, but that&#8217;s nothing new regarding what we all know and use from other web servers. Nothing very innovative, breath taking, crazy, revolutionary or surprising you [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>The Thin Cheesecake release is out (v0.6.1)!</p>
<p><code>sudo gem install thin</code></p>
<p>That tasty and sweet Cheesecake release comes with some new sweet topping: config file support, uses less memory, some speed tweaks, but that&#8217;s nothing new regarding what we all know and use from other web servers. Nothing very innovative, breath taking, crazy, revolutionary or surprising you say.</p>
<p>You&#8217;re right!</p>
<p>Almost &#8230;</p>
<p>There&#8217;s another feature that as never been seen amongst Ruby web servers (indeed, haven&#8217;t found any that does that). But first, lets explore the typical deployment of a Rails app.</p>
<h4>Let&#8217;s deploy Rails shall we?</h4>
<p>Typically you&#8217;d deploy your rails application using mongrel like this:</p>
<pre>
mongrel_rails cluster::configure -C config/mongrel_cluster.yml --servers 3 --chdir /var/www/app/current ...
mongrel_rails cluster::start -C config/mongrel_cluster.yml
</pre>
<p>Then on your web server / load balancer configuration file (Nginx in this case):<br />
<em>nginx.conf</em></p>
<pre>
upstream  backend {
  server   127.0.0.1:5000;
  server   127.0.0.1:5001;
  server   127.0.0.1:5002;
}
</pre>
<p>Now with Thin, it&#8217;s the same</p>
<pre>
thin config -C config/thin.yml --servers 3 --port 5000 --chdir ...
thin start -C config/thin.yml
</pre>
<p>That will start 3 servers running on port 5000, 5001 and 5002.<br />
And your web server configuration stays the same.</p>
<h4>Really, between you and me, is Thin really really faster?</h4>
<p><img src="http://macournoyer.files.wordpress.com/2008/01/benchmarks.png?w=600" alt="Benchmarks" width="600"><br />
<em>Simple &#8220;hello world&#8221; app, running one server</em></p>
<p>And uses less memory too:<br />
<img src="http://macournoyer.files.wordpress.com/2008/01/memory.png?w=600" alt="Memory" width="600"><br />
<em>Mesured after running: <code>ab -n5000 -c3</code></em></p>
<h4>What about that new, crazy, amazing feature you mentioned?</h4>
<p>Ever wanted to keep closer to you web server? Sometimes connecting through a TCP port on 127.0.0.1 feels a bit &#8230; disconnected. What if we&#8217;d get closer to it, get intimate with it, share some feelings, exchange toothbrush?</p>
<h4>Introducing UNIX socket connections</h4>
<p>When using more then one server (a cluster) behind a load balancer, we need to connect those servers to the load balancer through dedicated ports like in the previous &#8220;Let&#8217;s deploy Rails&#8221; section. But this connect the 2 using a TCP socket which means, all requests have to go though the network interface stuff twice! Once from the client (browser) to the load balancer / web server and again to the backend server.</p>
<p>There&#8217;s a better approach to this. Some load balancer (like Nginx) support connecting to a <a href="http://lists.freebsd.org/pipermail/freebsd-performance/2005-February/001143.html">UNIX domain socket</a>.</p>
<p><em>nginx.conf</em></p>
<pre>
upstream  backend {
  server   unix:/tmp/thin.0.sock;
  server   unix:/tmp/thin.1.sock;
  server   unix:/tmp/thin.2.sock;
}
</pre>
<p>Then start your Thin servers, like this:<br />
<code>thin start --server 3 --socket /tmp/thin.sock</code></p>
<p>And yes, it is faster:<br />
<img src="http://macournoyer.files.wordpress.com/2008/01/socket.png?w=600" alt="Socket" width="600"><br />
<em>3 servers running a simple Rails application, behind Nginx</em></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/macournoyer.wordpress.com/201/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/macournoyer.wordpress.com/201/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/macournoyer.wordpress.com/201/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/macournoyer.wordpress.com/201/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/macournoyer.wordpress.com/201/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/macournoyer.wordpress.com/201/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/macournoyer.wordpress.com/201/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/macournoyer.wordpress.com/201/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/macournoyer.wordpress.com/201/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/macournoyer.wordpress.com/201/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/macournoyer.wordpress.com/201/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/macournoyer.wordpress.com/201/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=macournoyer.wordpress.com&blog=343861&post=201&subd=macournoyer&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://macournoyer.wordpress.com/2008/01/26/get-intimate-with-your-load-balancer-tonight/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/macournoyer-128.jpg" medium="image">
			<media:title type="html">macournoyer</media:title>
		</media:content>

		<media:content url="http://macournoyer.files.wordpress.com/2008/01/benchmarks.png" medium="image">
			<media:title type="html">Benchmarks</media:title>
		</media:content>

		<media:content url="http://macournoyer.files.wordpress.com/2008/01/memory.png" medium="image">
			<media:title type="html">Memory</media:title>
		</media:content>

		<media:content url="http://macournoyer.files.wordpress.com/2008/01/socket.png" medium="image">
			<media:title type="html">Socket</media:title>
		</media:content>
	</item>
	</channel>
</rss>