<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>has_many :thoughts: Starting to Get Thin, v0.6.3</title>
    <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Musings from a Ruby on Rails development team</description>
    <item>
      <title>Starting to Get Thin, v0.6.3</title>
      <description>&lt;p&gt;When I first heard about Thin I was slightly intrigued, but less enthusiastic when I attempted to run it (not sure what version). Anyway, now that Thin has matured a bit more, and Merb 0.9 is bringing the love of &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; to the masses&amp;#8230; I&amp;#8217;m &lt;strong&gt;really&lt;/strong&gt; &lt;strong&gt;really&lt;/strong&gt; &lt;strong&gt;really&lt;/strong&gt; starting to see what all the fuss is about. 3000+ requests a second of fuss.&lt;/p&gt;


	&lt;h2&gt;The Skinny&lt;/h2&gt;


	&lt;p&gt;Thin is actually a mash-up of current back-end web serving technologies.&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;the Mongrel parser, I&amp;#8217;m &lt;strong&gt;speculating&lt;/strong&gt; its the &lt;a href="http://www.cs.queensu.ca/~thurston/ragel/"&gt;Ragel executable state machine&lt;/a&gt; portion&lt;/li&gt;
&lt;li&gt;Event Machine, and the tough, concurrent service request handling of the &lt;a href="http://www.cs.wustl.edu/~schmidt/PDF/reactor-siemens.pdf"&gt;Reactor Pattern&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;and Rack, our new hero which brings a common &lt;a href="http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface"&gt;web server gateway interface&lt;/a&gt; to all of our favorite Ruby web frameworks.&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;Fancy technologies (and citations), but how&amp;#8217;s this going to help good&amp;#8217;ole &lt;a href="http://www.peepcode.com"&gt;Geoffrey Grosenbach&lt;/a&gt;?&lt;/p&gt;


	&lt;h2&gt;Installation&lt;/h2&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_shell "&gt;$ sudo gem install thin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;...or if you know what your doing&amp;#8230;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_shell "&gt;$ git clone git://github.com/macournoyer/thin.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&lt;small&gt;If not, go directly to &lt;span class="caps"&gt;FAIL&lt;/span&gt;&amp;#8230;&lt;/small&gt;&lt;/p&gt;


	&lt;h2&gt;Show&amp;#8217;em Some Ruby&lt;/h2&gt;


	&lt;p&gt;Lets take a quick glimpse at the adapter example that is included with the gem (&lt;small&gt;examples/adapter.rb&lt;/small&gt;).&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll try not to ramble on about Rack too long but&amp;#8230; This really shows you how damn simple it can be to plug and play applications into a Rack stack, and the power that Thin brings along with its speed!&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;dirname&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;__FILE__&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/../lib/thin&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;SimpleAdapter&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;env&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;body&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;hello!&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;]&lt;/span&gt;
      &lt;span class="punct"&gt;[&lt;/span&gt;      &lt;span class="number"&gt;200&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;  
        &lt;span class="punct"&gt;{&lt;/span&gt;
          &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Content-Type&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;   &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;text/plain&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
          &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Content-Length&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;body&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;join&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;size&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
        &lt;span class="punct"&gt;},&lt;/span&gt; &lt;span class="ident"&gt;body&lt;/span&gt;
      &lt;span class="punct"&gt;]&lt;/span&gt;  
   &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt; 

&lt;span class="constant"&gt;Thin&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Server&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;start&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;0.0.0.0&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="number"&gt;3000&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;  

  &lt;span class="ident"&gt;use&lt;/span&gt; &lt;span class="constant"&gt;Rack&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;CommonLogger&lt;/span&gt;

  &lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/test&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;    
    &lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="constant"&gt;SimpleAdapter&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;  
  &lt;span class="keyword"&gt;end&lt;/span&gt;  

  &lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/files&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;    
    &lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="constant"&gt;Rack&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;.&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;  
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="constant"&gt;Rack&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Adapter&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Rails&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:root&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &#8216;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;Users&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;justin&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;apps&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;whatsyomammabeensmokin&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;com&#8216;&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Very briefly, this example is a thin/Thin adapter specification and server initialization. Its also an insanely small example of a Rack adapter (&lt;small&gt;which may, or may not work; reference the real examples in the gem&lt;/small&gt;).&lt;/p&gt;


	&lt;p&gt;We can see, after loading our necessary library file, we create a class used as an adapter, called SimpleAdapter.&lt;/p&gt;


	&lt;p&gt;This holds in it a means to handle status code 200 requests. With a simple output of plain text content-type, set in its header hash. It also includes a simple body of text, &amp;#8220;hello!&amp;#8221; to be returned as content. Literally the Rack adapter, handling a request, need only return this sort of array as a response. [status, header, body].&lt;/p&gt;


	&lt;p&gt;Finishing up the script is Thin&amp;#8217;s server stack initialization. Resembling a Rack config.ru configuration file, Thin initializes a server for our localhost on port 3000. As well as some middle ware setups using our SimpleAdapter.&lt;/p&gt;


	&lt;p&gt;First, inside the setup block you should quickly notice a few &amp;#8220;map&amp;#8221; method calls that resemble Rails routes. &amp;#8220;map&amp;#8221; is actually just that, a simple way to set Rack::URLMap&amp;#8217;s, or web &lt;span class="caps"&gt;URI&lt;/span&gt; paths, inside the main server start block.&lt;/p&gt;


	&lt;p&gt;Second, the &amp;#8220;use&amp;#8221; method actually adds middle ware to the stack.&lt;/p&gt;


	&lt;p&gt;Finally, notice &amp;#8220;run&amp;#8221;. This literally dispatches middle ware logic to the server.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve taken the liberty of adding a call to a local Rails application to point out how easy it is to include new applications straight into a running Rack/Thin server stack. Pretty much just as easy as it is to &amp;#8220;include&amp;#8221; a mix-in into a class in Ruby.&lt;/p&gt;


	&lt;p&gt;If you would like to work more closely with some real code, take a look &lt;a href="http://macournoyer.wordpress.com/2008/02/09/the-flexible-thin-anorexic-gymnast-that-democratized-deployment/"&gt;here&amp;#8230;&lt;/a&gt;&lt;/p&gt;


	&lt;h2&gt;Thin Rails&lt;/h2&gt;


	&lt;p&gt;Ok&amp;#8230; woosh, back to the easy stuff&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Since Thin supports Rails natively through what I believe is an included Rack adapter&amp;#8230; you can start playing with it right out of the box on any of your current Rails projects.&lt;/p&gt;


	&lt;p&gt;Once you have the Thin gem installed, simply do a&amp;#8230;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_shell "&gt;$ thin start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If you&amp;#8217;d like to explicitly set your Rails environment&amp;#8230;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_shell "&gt;$ thin start -e development&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&amp;#8220;&amp;#8212;help&amp;#8221; provides more information as usual. Thin&amp;#8217;s main site has a lovely amount of info with a beautiful web design. Be it tiny lil text (get it, thin).&lt;/p&gt;


	&lt;p&gt;You can also try out a middle ware script that comes with Thin called &amp;#8220;stats&amp;#8221;.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_shell "&gt;$ thin --stats=/public_thin/stats start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This will give you a technical details of your Thin server stats, map&amp;#8217;d to &amp;#8220;localhost:3000/public_thin/stats&amp;#8221;.&lt;/p&gt;


	&lt;h2&gt;To Deployment, and Beyond&lt;/h2&gt;


	&lt;p&gt;I have yet to really attempt a deployment with Thin, but I have one coming up shortly to assist with and will definitely be trying this out.&lt;/p&gt;


	&lt;p&gt;From what I&amp;#8217;ve read you can just as easily replace mongrel_cluster with thin like so.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_shell "&gt;# thin config -C config/thin.yml --servers 3 --port 5000 --chdir ...
# thin start -C config/thin.yml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If anyone has tried this yet please let me know how it went.&lt;/p&gt;


	&lt;h2&gt;The Year 2000&lt;/h2&gt;


	&lt;p&gt;Hopefully your interested now and will check into this speedy fast Mongrel replacement. Did I even mention it was fast&amp;#8230;? &amp;gt;;)&lt;/p&gt;


	&lt;p&gt;In the near future I&amp;#8217;ll attempt to report back on deployments and middle ware scripts. I&amp;#8217;m eager to see what useful little apps I can come up with that sit between the web server and my actual Rails application. But I can imagine 8 bazillion possibilities (especially logging and transparent statistics harvesting).&lt;/p&gt;


	&lt;p&gt;So yeah&amp;#8230; cheers to the author!!&lt;/p&gt;</description>
      <pubDate>Tue, 12 Feb 2008 22:16:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:2dbbe8c9-a52c-4652-b5f3-6ad131491c12</guid>
      <author>Justin Reagor</author>
      <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3</link>
      <category>thin</category>
      <category>rack</category>
      <category>ruby</category>
      <category>mongrel</category>
    </item>
    <item>
      <title>"Starting to Get Thin, v0.6.3" by Justin</title>
      <description>I guess nobody really knows yet what mod_rubinius is going to be like for implementing, since its just now being started... :)</description>
      <pubDate>Wed, 13 Feb 2008 19:36:58 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:43433ca4-05c7-402a-894c-dc43523e2c03</guid>
      <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3#comment-222</link>
    </item>
    <item>
      <title>"Starting to Get Thin, v0.6.3" by Justin</title>
      <description>Yooo topfunky, thanks for letting me use your name there. I thought it was kinda funny, more then the typical "how's this going to help you out?".

Yes, I agree on how promising this is. I am very eager to see what kinds of smaller, middle ware scripts/apps I can place in between my Rails/Merb applications and our clients. Interested in possibly starting to write my own statistical back ends to the apps I develop, as well as better real time visitor stats. Hoping that this lightweight framework ease some of that (which I'm pretty sure it can).

I'm also EXTREMELY happy to hear that this could possibly remove the need for a web server all together. Though I do enjoy the classical rewrite rules and configurations of Nginx. Though, those are easily replaced, ;) Awww, poor web servers... sending out static content for the rest of their lives... Until mod_rubinius! ;)

Speaking of mod_rubinius, I wonder if Thin will support that in any way (or rubinius in general).</description>
      <pubDate>Wed, 13 Feb 2008 19:29:11 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d5b3e899-2ba4-42e8-b4a7-179bc9abacc8</guid>
      <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3#comment-221</link>
    </item>
    <item>
      <title>"Starting to Get Thin, v0.6.3" by macournoyer</title>
      <description>@Geoffrey: exactly! I'm already getting performances similar to Nginx w/ Swifitiply (even a tab faster, 4-5 req/sec!) which is coming in next release of Thin.</description>
      <pubDate>Wed, 13 Feb 2008 17:43:42 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:c822d2ae-5fcd-4acc-88f9-5f92465d2032</guid>
      <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3#comment-220</link>
    </item>
    <item>
      <title>"Starting to Get Thin, v0.6.3" by Geoffrey Grosenbach</title>
      <description>&lt;p&gt;Yes, how IS this going to help me? That's what I'd like to know.&lt;/p&gt;

&lt;p&gt;Seriously, it looks promising. From my benchmarks, the benefit is more noticeable on leaner actions that don't do much processing. &lt;/p&gt;

&lt;p&gt;However, having a speedy Ruby application server starts to open up the possibility of skipping the webserver altogether in some situations. If you can run Peter Cooper's SwitchPipe on the front, you may be able to get away with some thins on the backend and not need Nginx at all.&lt;/p&gt;</description>
      <pubDate>Wed, 13 Feb 2008 13:23:42 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:6f10b26a-bf03-4d8e-a1dc-3a5005796e52</guid>
      <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3#comment-219</link>
    </item>
    <item>
      <title>"Starting to Get Thin, v0.6.3" by Justin</title>
      <description>I'm not 100% sure if Ruby is all that great for my ADD, seeing as there is just great projects scattered across the community and its hard to stay focused on one! Thin is definitely turning out to be a lovely lil server and its definitely got me hooked in... Hope to contribute back at some point, thanks!</description>
      <pubDate>Wed, 13 Feb 2008 10:57:51 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:9a8cafed-be7a-4caf-94e6-d5a2ea2d91c2</guid>
      <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3#comment-218</link>
    </item>
    <item>
      <title>"Starting to Get Thin, v0.6.3" by macournoyer</title>
      <description>Hey Justin,
thx for the great review of my project. I'm glad you like it.

If you have any problem or question about Thin, feel free to join the Google group &lt;a href="http://groups.google.com/group/thin-ruby/topics" rel="nofollow"&gt;http://groups.google.com/group/thin-ruby/topics&lt;/a&gt; or come chat on #thin on freenode.

And stay tuned for the next big release (0.7) for 2 big surprises (well not real surprises if you spy on me on the git repo, but act like you were surprised ok?).</description>
      <pubDate>Wed, 13 Feb 2008 01:24:17 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:dc62bbff-0a9a-42ae-af8d-e5d4d3558051</guid>
      <link>http://blog.kineticweb.com/articles/2008/02/12/starting-to-get-thin-v0-6-3#comment-217</link>
    </item>
  </channel>
</rss>
