<?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:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ivan Kuznetsov &#187; Ruby on Rails</title>
	<atom:link href="http://www.ivankuznetsov.com/category/ruby-on-rails/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ivankuznetsov.com</link>
	<description>Entrepreneur, Ruby on Rails and Ubuntu fanatic, consultant</description>
	<lastBuildDate>Fri, 01 Jul 2011 22:03:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>REE segfaults when Rails application has too many localisation files</title>
		<link>http://www.ivankuznetsov.com/2011/07/ree-segfaults-when-rails-application-has-too-many-localisation-files.html</link>
		<comments>http://www.ivankuznetsov.com/2011/07/ree-segfaults-when-rails-application-has-too-many-localisation-files.html#comments</comments>
		<pubDate>Fri, 01 Jul 2011 22:03:56 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=349</guid>
		<description><![CDATA[We ran into an interesting problem &#8211; at some point of time our Rails application started to fail occaionally because of REE segfaults on startup. Even starting the console with &#8216;script/console production&#8217; was occasionally failing with REE segfault. Application was growing, new features were added and segfaults started happening more and more often. There was [...]]]></description>
			<content:encoded><![CDATA[<p>We ran into an interesting problem &#8211; at some point of time our Rails application started to fail occaionally because of REE segfaults on startup. Even starting the console with &#8216;script/console production&#8217; was occasionally failing with REE segfault. Application was growing, new features were added and segfaults started happening more and more often. There was no one single place where crashes occurred, so there was no clear understanding how to tackle this problem.</p>
<p>Examples of crashes we observed:</p>
<pre>/vendor/rails/actionpack/lib/action_controller/routing/route.rb:205):2:
   [BUG] Segmentation fault
/opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/1.8/yaml.rb:133:
   [BUG] Segmentation fault
/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.3.7/i18n/
   backend/base.rb:257: [BUG] Segmentation fault
/vendor/rails/actionpack/lib/action_view/template.rb:226: [BUG] Segmentation fault
/opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/pauldix-sax-machine-0.0.14/
   lib/sax-machine/sax_document.rb:30: [BUG] Segmentation fault
/vendor/rails/activesupport/lib/active_support/memoizable.rb:32: [BUG] Segmentation fault</pre>
<p>After banging my head against the wall for a week I found a solution (even two) and what might seem to be a likely reason for the segfaults. Two &#8220;suspects&#8221; &#8211; lack of available memory and incorrect version of libxml were ruled out. What seems to be the actual reason is the total size of the localisation files in config/locales loaded upon startup:</p>
<pre>$ du -shb config/locales
1665858    config/locales</pre>
<pre>$ cd config/locales
$ find . -type f | wc -l
805</pre>
<p>So ~1.6Mb in 805 files give occasional segfaults. Adding 200Kb of localisation files more started giving 100% segfaults on script/console startup.</p>
<p>Now I&#8217;ve found two workarounds for this problem.</p>
<p>1. Recompile REE with &#8211;no-tcmalloc flag</p>
<pre>./ruby-enterprise-1.8.7-2011.03/installer --no-tcmalloc</pre>
<p>Note that on 64-bit platforms tcmalloc is disabled by default.</p>
<p>2. Enable large pages feature in tcmalloc</p>
<p>This is described in <a href="http://google-perftools.googlecode.com/svn/tags/perftools-1.6/INSTALL" target="_blank">tcmalloc documentation</a> as: &#8220;Internally, tcmalloc divides its memory into &#8220;pages.&#8221;  The default page size is chosen to minimize memory use by reducing fragmentation. The cost is that keeping track of these pages can cost tcmalloc time. We&#8217;ve added a new, experimental flag to tcmalloc that enables a larger page size.  In general, this will increase the memory needs of applications using tcmalloc.  However, in many cases it will speed up the applications as well, particularly if they allocate and free a lot of memory.  We&#8217;ve seen average speedups of 3-5% on Google applications.&#8221;</p>
<p>There&#8217;s a warning &#8211; &#8220;this feature is still very experimental&#8221;, but it works to solve the problem with too many localisation files.</p>
<p>To compile REE with tcmalloc with large pages enables I just edited ruby-enterprise-1.8.7-2011.03/source/distro/google-perftools-1.7/src/common.h &#8211; replaced</p>
<pre>#if defined(TCMALLOC_LARGE_PAGES)
static const size_t kPageShift  = 15;
static const size_t kNumClasses = 95;
static const size_t kMaxThreadCacheSize = 4 &lt;&lt; 20;
#else
static const size_t kPageShift  = 12;
static const size_t kNumClasses = 61;
static const size_t kMaxThreadCacheSize = 2 &lt;&lt; 20;
#endif</pre>
<p>with</p>
<pre>static const size_t kPageShift  = 15;
static const size_t kNumClasses = 95;
static const size_t kMaxThreadCacheSize = 4 &lt;&lt; 20;</pre>
<p>On production servers I opted for no tcmalloc for now &#8211; but I hope there&#8217;ll be a <a href="http://code.google.com/p/rubyenterpriseedition/issues/detail?id=73" target="_blank">better way to deal with this issue</a> soon.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2011%2F07%2Free-segfaults-when-rails-application-has-too-many-localisation-files.html&amp;title=REE%20segfaults%20when%20Rails%20application%20has%20too%20many%20localisation%20files" id="wpa2a_2"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2011/07/ree-segfaults-when-rails-application-has-too-many-localisation-files.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pitfalls of Rails fragment caching with memcached</title>
		<link>http://www.ivankuznetsov.com/2011/06/pitfalls-of-rails-fragment-caching-with-memcached.html</link>
		<comments>http://www.ivankuznetsov.com/2011/06/pitfalls-of-rails-fragment-caching-with-memcached.html#comments</comments>
		<pubDate>Wed, 29 Jun 2011 15:52:36 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=319</guid>
		<description><![CDATA[Fragment caching is a powerful technique for improving performance of your web application. Rails site describes in detail how to apply this technique. Rails are providing developers with really excellent abstractions, but it&#8217;s always good to know what&#8217;s under the hood and how it all works. There are a few things that might potentially cause [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-356" title="300px-Ruby_on_Rails_logo" src="http://www.ivankuznetsov.com/wp-content/uploads/300px-Ruby_on_Rails_logo.jpg" alt="" width="150" />Fragment caching is a powerful technique for improving performance of your web application. Rails site <a href="http://guides.rubyonrails.org/caching_with_rails.html#fragment-caching" target="_blank">describes in detail</a> how to apply this technique.</p>
<p>Rails are providing developers with really excellent abstractions, but it&#8217;s always good to know what&#8217;s under the hood and how it all works.</p>
<p>There are a few things that might potentially cause bugs in your code, or waste your time (speaking from my own experience). So here goes:</p>
<p>1. Beware of globally keyed fragments</p>
<p>Let&#8217;s take example from Rails tutorial:</p>
<pre>&lt;% cache do %&gt;
  All available products:
  &lt;% Product.all.each do |p| %&gt;
    &lt;%= link_to p.name, product_url(p) %&gt;
  &lt;% end %&gt;
&lt;% end %&gt;</pre>
<p>Now if you need to deal with a multi-language site you might want to make cache fragment language dependent. What might seem a convenient solution:</p>
<pre>&lt;%- cache([user.locale.to_s]) do -%&gt;</pre>
<p>will turn into a source of very interesting problems. While calling the cache method without parameters will automatically create a controller/action specific cache key, calling it with a key will make this fragment a globally keyed fragment. Cache key in the first case is going to look like &#8220;views/localhost:3000/controller-name&#8221;, and in the other case &#8220;views/en&#8221; &#8211; this is not as unique identifier any more.</p>
<p>While automatic cache key naming provided by rails is very convenient, it is very easy to run into a problem with duplicate cache key names used in different places.</p>
<p>2. Another pitfall of automatic cache key naming is that you shall never assume that when creating a cache with global key you can later find it using e.g. <a href="http://lzone.de/articles/memcached.htm" target="_blank">telnet interface</a> to memcache. Example &#8211; add</p>
<pre>&lt;%- cache('unique_cache_key') do -%&gt;
&lt;%- end -%&gt;</pre>
<p>in your view and then try to read directly from memcache:</p>
<pre>$ telnet localhost 11211
GET unique_cache_key
END</pre>
<p>At the same time</p>
<pre>GET views/unique_cache_key</pre>
<p>will work. It&#8217;s easy to make this mistake trying to check or delete cache keys directly from memcache when using Rails cache methods.</p>
<p>3. delete_matched is not supported by memcached (see rails/activesupport/lib/active_support/cache/mem_cache_store.rb)</p>
<p>In practice that means that if you&#8217;re using memcached as Rails cache engine and trying to delete or expire fragment cache using standard Rails methods and regexp &#8211; you&#8217;ll fail.</p>
<p>expire_fragment(/base\/xyz.*/)</p>
<p>will fail miserably. Ideal solution is not to use explicit cache expiration, but rather create cache keys in such a way that doesn&#8217;t require expiration. Alternatively it&#8217;s possible to use <a href="https://github.com/jkassemi/memcache-store-extensions" target="_blank">extensions</a> implementing delete_matched for memcached (haven&#8217;t tried it myself though).</p>
<p><em>Tip: one very useful tool for checking memcached is <a href="https://github.com/fauna/peep" target="_blank">peep</a> by Evan Weaver &#8211; allows you to peek into the cache and see what&#8217;s really cached and how it is used.</em></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2011%2F06%2Fpitfalls-of-rails-fragment-caching-with-memcached.html&amp;title=Pitfalls%20of%20Rails%20fragment%20caching%20with%20memcached" id="wpa2a_4"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2011/06/pitfalls-of-rails-fragment-caching-with-memcached.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes from Gothenburg &#8211; Nordic Ruby 2011 conference</title>
		<link>http://www.ivankuznetsov.com/2011/06/notes-from-gothenburg-nordic-ruby-2011-conference.html</link>
		<comments>http://www.ivankuznetsov.com/2011/06/notes-from-gothenburg-nordic-ruby-2011-conference.html#comments</comments>
		<pubDate>Tue, 21 Jun 2011 22:00:52 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web/Tech]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=334</guid>
		<description><![CDATA[Here are my notes from Nordic Ruby conference in Göteborg, Sweden. I&#8217;d like to say big thanks to the organisers of the conference (especially CJ @cjkihlbom) &#8211; everything went really smooth, even though there&#8217;s been 150 people attending this year compared to 90 last year. Some points that I&#8217;d really like to highlight are: a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/nordicruby.png"><img class="alignleft size-full wp-image-335" title="nordicruby" src="http://www.ivankuznetsov.com/wp-content/uploads/nordicruby.png" alt="" width="254" height="135" /></a>Here are my notes from <a href="http://nordicruby.org/" target="_blank">Nordic Ruby</a> conference in Göteborg, Sweden.</p>
<p>I&#8217;d like to say big thanks to the organisers of the conference (especially CJ <a href="https://twitter.com/#%21/cjkihlbom" target="_blank">@cjkihlbom</a>) &#8211; everything went really smooth, even though there&#8217;s been 150 people attending this year compared to 90 last year.<br />
Some points that I&#8217;d really like to highlight are:</p>
<ul>
<li>a lot of time to meet people and discuss: 30 minutes talks followed by  30 minutes breaks, no q&amp;a &#8211; those who had questions had an  opportunity to talk to the speakers during the breaks</li>
<li>venue was  great (of course, the boat <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  &#8211; there was enough space for everyone to  move around, but at the same time it was compact enough not to get lost also everyone had an opportunity to have lunch and dinner together</li>
<li>&#8220;job board&#8221; a huge white board where anyone can post information about  open positions in their companies &#8211; it got filled withing firts few  hours &#8211; job market is really hot</li>
<li>lightning talks that any participant can give &#8211; 5 minute talks in the end of the day &#8211; it was really great</li>
<li>real coffee <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  espresso, latte, cappuccino, americano &#8211; you name it &#8211; professional baristas were at your service</li>
<li><a href="http://runconfapp.com/races/226e14f45b6303b98e48bab49af60683" target="_blank">5K Nordic Ruby run</a> organised on the second day&#8217;s morning</li>
</ul>
<h2><span id="more-334"></span>Day 0</h2>
<p>The conference started with a party on <a href="http://en.wikipedia.org/wiki/G%C3%B6theborg_%28ship%29" target="_blank">Göthenborg ship</a>. It was a great way to get to know the speakers and participants in an informal setting.</p>
<h2>Day 1</h2>
<p><strong>&#8220;GitHub Flavored Ruby&#8221; was by Tom Preston-Werner (@mojombo) from GitHub.</strong></p>
<p>Tom had a hard task of waking up the auidence after yesterday&#8217;s pre-conference party, and he succeeded in this task. Tom explained what is a <a href="http://tom.preston-werner.com/2010/08/23/readme-driven-development.html" target="_blank">README driven development</a> that he and some of his colleagues in GitHub are using &#8211; a golden mean between waterfall and cowboy coding.<br />
Start a new project with writing a README file, where basic design principles and conventions will be described, and don&#8217;t forget to update it as the architecture changes.</p>
<p>Another interesting topic was <a href="http://tomdoc.org/" target="_blank">TomDoc</a> &#8211; code level documentation &#8211; a better alternative than RDoc/Yard, designed for hackers/humans, not for machines to read.</p>
<p>Modularisation was yet another subject &#8211; Tom explained how at GitHub they try to split the code into independent modules to reduce complexity of the system.<br />
Grit is a good example of that &#8211; a module for Ruby-Git interaction was written even before the rails code for GitHub.</p>
<p>Other examples of modles created in GitHub (and open-sourced) are: resque, jekyll, proxymachine and chimney, albino, gollum, bart, camo, failbot, giraffe, nodeload (in node.js), ernie (in erlang), stratocaster (for event feed), ghromosome (which is apparently not used anymore, but worth mentioning just because of the fun name).</p>
<p>And naturally for versioning of the components Tom proposes to use <a href="http://semver.org/" target="_blank">Semantic versioning</a>.</p>
<p>A few notes from the after-talk discussion with Tom and others:<br />
- Github uses git powered deploys &#8211; instead of copying the new release from git and then changing symlink to current release, they use single directory and do direct git updates &#8211; rollbacks are also easy to do using git fucntionality<br />
- it&#8217;s possible to deploy Github from Campfire by giving deploy command to a robot<br />
- to avoid downtime &#8211; build_cache is executed on a local machine before deploy and pushed to the servers during deploy<br />
- GitHub is still running on Rails 2.3, Tom&#8217;s estimate for migration to Rails 3 is ~2 weeks of &#8220;stop commits and migrate&#8221; (the estimate seems to be pretty consistent &#8211; I&#8217;ve been talking to several people about it)<br />
- experience from a fairly large web-app developers: MySQL to Postgres migration took 3 weeks</p>
<p><strong>&#8220;API Design Matters&#8221; was by Anthony Eden (@aeden) from DNSimple</strong></p>
<p>Central points from Anthony&#8217;s presentation:<br />
- APIs outlive their implementation (&#8220;Think about the children&#8221; when designing APIs <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
- Design APIs so that they are easy to extend<br />
- 5 Cs: consistent, clear, convenient, concise and complete<br />
- The best API is no API<br />
- If you&#8217;re a software developer &#8211; you are and API designer<br />
- And use semantic versioning that Tom was talking about</p>
<p>Reading recommendations:<br />
- Jasmine Blanchette &#8220;<a href="http://chaos.troll.no/~shausman/api-design/api-design.pdf" target="_blank">The little manual of API design</a>&#8221;<br />
- Joshua Bloch &#8220;<a href="http://www.youtube.com/watch?v=aAb7hSCtvGw, " target="_blank">How to design a good API and why it matters</a>&#8221;</p>
<p><strong>&#8220;Bridging the gap &#8211; Using JavaScript in Rails to write DRY rich client applications&#8221; by Thorben Schröder (@walski), KOPFMaschine</strong></p>
<p>An interesting talk about using Java Script from Ruby code and the other way around.<br />
Implementing validations on the client side reduces amount of round-trips and speeds up user interaction, but since smart people can hack JavaScript and bypass client-side validations, also server side validations are necessary. To avoid writing validations twice use The Ruby Racer,  CommonJS and CommonJS models to DRY your code and write validations only once and use them from both Ruby and JS code. Pretty smart, huh?</p>
<p><strong>&#8220;Limited Red Society&#8221; by Joseph Wilk (@josephwilk)</strong></p>
<p>Slides: <a href="http://www.slideshare.net/josephwilk/the-limited-red-society-8367200" target="_blank">http://www.slideshare.net/josephwilk/the-limited-red-society-8367200</a></p>
<p>Kanban is limiting number of tasks the team has in progress at any given moment. Joseph described in his talk how to apply this methodology to testing.</p>
<p>It&#8217;s important to have metrics for your testing and it&#8217;s important to visualize them. How much time do you spend in &#8220;red&#8221; when your tests are failing, which modules in your code are changed most often, are they the same that usually fail tests, are there any oscillating test cases that pass then fail then pass again?</p>
<p>One thing to be noted &#8211; some metrics have limited lifespan &#8211; measure what you&#8217;re interested in and then throw them away.</p>
<p>Reading recommendations:<br />
&#8220;<a href="http://www.amazon.co.uk/Refactoring-Ruby-William-C-Wake/dp/0321545044" target="_blank">Refactoring in Ruby</a>&#8221;<br />
&#8220;<a href="http://www.amazon.co.uk/Refactoring-Ruby-Addison-Wesley-Professional/dp/0321603508" target="_blank">Refactoring. Ruby Edition</a>&#8221; Kent Beck</p>
<p><strong>&#8220;</strong><strong>Must It Always Be About Sex?</strong><strong>&#8221; by Joshua Wehner (@jaw6)</strong></p>
<p>Links from the talk: <a href="http://pinboard.in/u:jaw6/t:nr2011/" target="_blank">http://pinboard.in/u:jaw6/t:nr2011/</a></p>
<p>Minorities and women are under-represented in our community. Black man is more likely to be hit by lightning than become a computer science professor.<br />
75% of women engineers leave profession because they are not socially accepted in the working culture. In the beginning of computer era programming was mostly a job for women.<br />
Do you think that your application is mobile friendly if you have iPhone optimised version? Think again &#8211; the most popular phone with a web browser is Nokia 1100 &#8211; more than 250 million phones sold to date,<br />
and that kind of devices are the only way how most people in Africa or India access the Internet.</p>
<p>What do we need to do to change current situation?</p>
<p>Just today I came across an article on the same subject: <a href="http://www.blackweb20.com/2011/06/10/two-11-year-old-entrepreneurs-learned-the-hard-way-what-it%E2%80%99s-like-to-be-a-minority-in-tech-during-startup-weekend/" target="_blank">Two 11-year-old entrepreneurs learned the hard way what it’s like to be a minority in tech during Startup Weekend</a></p>
<p><strong>&#8220;Infinite data &#8211; finite solutions&#8221; by Randall Thomas (@daksis) from Engine Yard</strong></p>
<p>Quick dive into Bayesian statistics. That is the technology that helps  to filter out spam from your inbox: &#8220;Keeps spam at Bayes&#8221; <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Bayes + DAG (Directed Acyclic Graph) = BBN (Bayesian Belief Network)</p>
<p>Probably the most scientific talk of the conference and two great demos: reconstruction of Bach&#8217;s first invention using BBN (amazing stuff) and analysing whiskey properties</p>
<p>Book to read: &#8220;<a href="http://fisher.stat.wmich.edu/joe/Stat666/book/book.pdf" target="_blank">Robust Nonparametric Statistical Methods</a>&#8221;<br />
Site to check: <a href="http://yudkowsky.net/rational/bayes" target="_blank">Eliezer Yudkowsky</a><br />
Tool to check: <a href="http://www.cs.waikato.ac.nz/ml/weka/" target="_blank">Weka</a> &#8211; analysis tool &#8211; live example how to analyze properites of whiskey.</p>
<p>A great collection of links on Bayesian Networks:  <a href="https://gist.github.com/1031597">https://gist.github.com/1031597</a></p>
<p><strong>&#8220;Taking Back Education&#8221; by Joe O&#8217;Brien (@objo)<br />
</strong></p>
<p>Education. We are in the top 5 to 2% of the developers by just being here &#8211; attending the conference.<br />
Why education system sucks? There&#8217;s a clear need for apprenticeship institute.</p>
<p>Harward Business Review research indicated that team IQ depends on diversity, not on IQ of individual members.<br />
Adding a women to the team cnsistently improves team performance (good reference for Diversity problems talk by Joshua)</p>
<p><strong>In the end of the first day there was a series of &#8220;lightning talks&#8221;.</strong></p>
<p>* Anthony Eden (@aeden) proposed to use DNS protocol for resolving dependencies. Definitely idea worth <a href="https://gist.github.com/1031494" target="_blank">studying</a>.<br />
* Twitter will be native on all iOS devices &#8211; think about it, and what do you want to do with it.<br />
* Stephen Sykes &#8211; obfuscated code for fun and ruby quiz &#8211; really, really fun &#8211; see the slides here: <a href="http://www.stephensykes.com/obfu_lightening.pdf" target="_blank">http://www.stephensykes.com/obfu_lightening.pdf</a><br />
* Emily Bach (backconsulting.com) shared her experiences in teaching TDD<br />
* Theo from Burt talked about his experiences and lessons learned from scaling:<br />
- build two of everything from the start &#8211; will help with horizontal scaling later<br />
- fail fast (Göthenburg ship made it to China and back to Sweden and sank a hundred meters from the home harbour, Vaasa is a lot better example &#8211; it sank right after it was deployed <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
- queues<br />
* Tom from GitHub talked about Hubot &#8211; a Campfire robot they wrote in node.js and keep developing just for fun &#8211; absolutely amazing stuff, every team should do that<br />
* David from Streamio (one of the sponsors of Nordic Ruby) did a &#8220;shameless self-promotion&#8221; of his company<br />
* Alex who has been doing a great job filming the conference talked about making a movie &#8211; what it takes<br />
* Antony Sastre &#8211; talked about photography &#8211; really inspiring, Antony was a web developer, then left the field and was doing photography for living for two years, now came back to web development<br />
* Nikolai (@nikolayb) Is this a bad idea? Deploying always to production on a site with millions of page views per day, one branch always &#8211; test code on a live service? Somehow it works&#8230;<br />
* Paul Wilson (@paulanthonywils) talked about Agile Delivery Network &#8211; doing better government IT, and here&#8217;s a bunch of links from his talk: https://gist.github.com/1035392<br />
* Paul Campbell (@paulk) talked about whenever.js and made it public on GitHub in the end of his talk http://whatever-js.heroku.com/#1, https://github.com/paulca/whenever.js</p>
<p>Day one ended with a BBQ dinner at the River Cafe.</p>
<h2>Day 2</h2>
<p>Paul Campbell who ended Day 1 with his lightning talk also started Day 2 with a autobiographical talk &#8220;In search of me fein&#8221; (myself in Irish).</p>
<p>7 days in my life, zombie movies and finding inspiration<br />
Technologist, developers, live in a bubble &#8211; we have no problems finding jobs, we can travel, we can choose where we live and work. It&#8217;s not like that outsie of our industry.</p>
<p><strong>&#8220;Actors on stage&#8221; by Elise Huard (@elise_huard)</strong></p>
<p>Slides: <a href="http://www.slideshare.net/ehuard/ruby-hollywood-nordic" target="_blank">http://www.slideshare.net/ehuard/ruby-hollywood-nordic</a></p>
<p>We have multiple cores in our processors now &#8211; how do we benefit from it?<br />
MRI is the only Ruby where parallel threads are executed time-scliced in one real thread.</p>
<p><a href="http://www.unlimitednovelty.com/2011/05/introducing-celluloid-concurrent-object.html" target="_blank">Cellucloid</a> &#8211; a concurrent object framework for Ruby.</p>
<p>Languages that implement actors: Erlang, Scala (Actors are in standard library), Closure (Actors called Agents)</p>
<p>Mats hates threads <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Should there still be a better cuncurrency primitives in MRI? shall we create a branch of Ruby to implement it?</p>
<p><strong>&#8220;Beyond Ruby&#8221; by Jakob Mattson from Burt (@jakobmattsson)<br />
</strong></p>
<p>Slides: <a href="http://jakobmattsson.tumblr.com/post/6664704401/beyond-ruby" target="_blank">http://jakobmattsson.tumblr.com/post/6664704401/beyond-ruby</a></p>
<p>Bold statement: Ruby is not a dynamic language. Not everyting in Ruby is an object, despite what many books claim.<br />
E.g. dot (.) or &#8220;or&#8221; (||) operators cannot be redefined. Or operator doesn&#8217;t evaluate second argument if the first one is true.<br />
Ruby is not as moldable as it could be.<br />
It would be cool to implement calling by name &#8211; passing expression along with the context to the callee and letting it decide whether to evaluate it or not.<br />
<a href="http://www.iolanguage.com/" target="_blank"> Io language</a> is probably 80% there. A new language needs to be invented. And coding it would not be that difficult &#8211; because if it is<br />
truly dynamic, then most of it can be implemented in itself.</p>
<p><strong>&#8220;Fewer constraints&#8221; by Ryan Smith (@ryandotsmith) from Heroku</strong></p>
<p>Slides: <a href="http://dl.dropbox.com/u/1579953/concurrency_deck_with_notes.pdf" target="_blank">http://dl.dropbox.com/u/1579953/concurrency_deck_with_notes.pdf</a></p>
<p>Continuing the theme that Elise started this morning. How to improve performance of your application by parallelizing.<br />
Amdahl&#8217;s law &#8211; adding processors gives only marginal speed-up. &#8220;Even though we have 10 workers<br />
available to us, we are only seeing a speedup factor of 5.2, with 20 workers it get only to 6.9&#8243;.</p>
<p>Real life example &#8211; improving queue performance. Using Fuzzy FIFO instead of traditional queues FIFO implementation.<br />
Example with using spinlock in PostgreSQL to implement it. See queue_classic on github.</p>
<p><strong>&#8220;Mountain Dew and My Trail of Tears&#8221; by Aaron Patterson (@tenderlove) from AT&amp;T Interactive</strong></p>
<p>Aaron discussed in depth how to work with legacy code.</p>
<p>- use &#8220;ruby -w&#8221; to see the warnings in your code, warnings can be used by developers to inform about upcoming deprecations<br />
- Liskov substitution principle (LSP)<br />
- Single responsibility principple<br />
- Method extraction<br />
- Object#extend<br />
- Code seams<br />
- sleep sort: <a href="http://dis.4chan.org/read/prog/1295544154" target="_blank">http://dis.4chan.org/read/prog/1295544154</a> <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Recommended reading: <a href="http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052" target="_blank">Working effectibely with legacy code</a></p>
<p><strong>&#8220;Legacy&#8221; by Chad Fowler (@chadfowler)</strong></p>
<p>Chad started with playing a recording of Beethoven &#8211; this is legacy. Miro is legacy. Gaudi is legacy too, and the only reason to visit Barcelona.</p>
<p>Legacy is good.</p>
<p>Nobody will remember your work when you die. There are still systems in use written 25 years ago &#8211; why don&#8217;t we write that kind of code anymore?<br />
Average lifespan of a business software is 5 years (figure is probably made up)</p>
<p>Recommended reading:</p>
<p>Michael Feathers &#8220;<a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2007/03/your_code_its_a.html" target="_blank">Your Code.. it&#8217;s Alive..</a>&#8221;<br />
Richard P. Gabriel &#8220;<a href="http://www.dreamsongs.com/Files/DesignBeyondHumanAbilitiesSimp.pdf" target="_blank">Design Beyond Human Abilities</a>&#8221;</p>
<p>What kind of software lasts &#8211; either small (cell-size) or systems consisting of cell-sized software (like UNIX).</p>
<p>Force heterogenity &#8211; languages, OSes, frameworks &#8211; will change over time. If it&#8217;s hard to force heterogenity &#8211; do it all the time.</p>
<p><strong>&#8220;Must.Try.Harder&#8221; by Keavy McMinn (@keavy)</strong></p>
<p>An absolutely fascinating and inspirational talk from a woman who decided to train for an IronMan from pretty much zero.<br />
She did it. A rare inspirational example of how to go outside your comfort zone and achieve a goal that looked impossible.</p>
<p>&nbsp;</p>
<p>Other conference notes:</p>
<p>Fredrik Rubensson: <a href="http://www.highlevelbits.com/2011/06/nordic-ruby.html" target="_blank">http://www.highlevelbits.com/2011/06/nordic-ruby.html</a><br />
Andreas Ronge / Jayway:  <a href="http://blog.jayway.com/2011/06/19/notes-and-thoughts-from-a-great-conference/" target="_blank">http://blog.jayway.com/2011/06/19/notes-and-thoughts-from-a-great-conference/</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2011%2F06%2Fnotes-from-gothenburg-nordic-ruby-2011-conference.html&amp;title=Notes%20from%20Gothenburg%20%26%238211%3B%20Nordic%20Ruby%202011%20conference" id="wpa2a_6"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2011/06/notes-from-gothenburg-nordic-ruby-2011-conference.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vim is the best editor, also for RoR development</title>
		<link>http://www.ivankuznetsov.com/2011/06/vim-is-the-best-editor-also-for-ror-development.html</link>
		<comments>http://www.ivankuznetsov.com/2011/06/vim-is-the-best-editor-also-for-ror-development.html#comments</comments>
		<pubDate>Wed, 15 Jun 2011 15:35:15 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=329</guid>
		<description><![CDATA[vim is a natural choice when you&#8217;re starting a new programming project (if you&#8217;re emacs or textmate adept &#8211; you can stop reading now If you&#8217;re starting a Ruby on Rails project there are a couple of scripts/configurations you might want to install to make development with vim an even more pleasant experience. 1. Rails.vim [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vim.org/"><a href="http://www.ivankuznetsov.com/wp-content/uploads/Screenshot.png"><img class="alignleft size-full wp-image-330" title="Rails and vim " src="http://www.ivankuznetsov.com/wp-content/uploads/Screenshot.png" alt="" width="300" height="176" /></a>vim</a> is a natural choice when you&#8217;re starting a new programming project (if you&#8217;re emacs or textmate adept &#8211; you can stop reading now <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  If you&#8217;re starting a Ruby on Rails project there are a couple of scripts/configurations you might want to install to make development with vim an even more pleasant experience.</p>
<p>1. <a href="https://github.com/tpope/vim-rails" target="_blank">Rails.vim</a> by <a href="http://tpo.pe/" target="_blank">Tim Pope</a></p>
<p>To install just copy autoload/rails.vim, plugin/rails.vim, and doc/rails.txt to corresponding directories in ~/.vim</p>
<p><a href="http://www.vim.org/scripts/script.php?script_id=1567" target="_blank">Vim scripts section</a> has a full description of the functionality. Some highlights:</p>
<ul>
<li>Easy navigation between models, controllers and views with :Rmodel, :Rview, :Rcontroller commands</li>
<li>Syntax highlighting</li>
<li>CTRL-X CTRL-U for autocompletion</li>
<li>:Rtree for project tree (see item 2)</li>
</ul>
<p>2. <a href="http://www.vim.org/scripts/script.php?script_id=1658" target="_blank">NERD Tree</a> by <a href="http://got-ravings.blogspot.com/" target="_blank">Marty Grenfell</a></p>
<p>Another must-have. Provides you with an easy way to navigate your project tree. Rails.vim nicely integrates with this one.</p>
<p>3. Colour schemas</p>
<p>If you want to save your eyes &#8211; use dark background when developing. Personally I prefer one of the standard vim themes &#8211; Desert , but <a href="http://www.vim.org/scripts/script.php?script_id=368" target="_blank">Ocean Deep</a> is also very good.</p>
<p>Copy theme file to ~/.vim/colors and then use</p>
<pre>:colorscheme oceandeep
</pre>
<p>command to apply it.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2011%2F06%2Fvim-is-the-best-editor-also-for-ror-development.html&amp;title=vim%20is%20the%20best%20editor%2C%20also%20for%20RoR%20development" id="wpa2a_8"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2011/06/vim-is-the-best-editor-also-for-ror-development.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Increasing Ruby interpreter performance by adjusting garbage collector settings</title>
		<link>http://www.ivankuznetsov.com/2010/10/increasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html</link>
		<comments>http://www.ivankuznetsov.com/2010/10/increasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html#comments</comments>
		<pubDate>Sun, 10 Oct 2010 23:10:12 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[garbage collector]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=305</guid>
		<description><![CDATA[According to Evan Weaver from Twitter it is possible for a typical production Rails app on Ruby 1.8 to recover 20% to 40% of user CPU by simply adjusting Ruby garbage collector settings. In August I set out on a quest to verify that statement on HeiaHeia servers. Results have really exceeded my expectations. Time to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/garbage.jpg"><img class="alignleft size-thumbnail wp-image-309" title="garbage" src="http://www.ivankuznetsov.com/wp-content/uploads/garbage-150x150.jpg" alt="" width="150" height="150" /></a>According to <a href="http://blog.evanweaver.com/articles/2009/04/09/ruby-gc-tuning/" target="_blank">Evan Weaver from Twitter</a> it is possible for a typical production Rails app on Ruby 1.8 to recover 20% to 40% of user CPU by simply adjusting Ruby garbage collector settings. In August I set out on a quest to verify that statement on <a href="http://www.heiaheia.com" target="_blank">HeiaHeia</a> servers. Results have really exceeded my expectations. Time to execute application tests locally decreased by 46%. On production servers CPU utilisation decreased by almost 40%.</p>
<div><span id="more-305"></span></div>
<p>But let&#8217;s start from the beginning. I should say right away that we at HeiaHeia are using <a href="http://www.rubyenterpriseedition.com/" target="_blank">Ruby Enterprise Edition</a>, so I didn&#8217;t have to apply patches to Ruby source code that Evan is talking about in his post. Before starting to analyse GC current usage it will be useful to read a brilliant <a href="http://timetobleed.com/garbage-collection-and-the-ruby-heap-from-railsconf/">overview of Ruby garbage collection</a> by Joe Damato. It&#8217;ll help to understand what&#8217;s going to happen next. It is also useful to read <a href="http://www.rubyenterpriseedition.com/documentation.html#_garbage_collector_performance_tuning" target="_blank">REE documentation on garbage collector performance tuning</a>.</p>
<p>And as before any optimisation it is good to get the reference metrics, so that you know you actually improved something by changing settings, and didn&#8217;t make it worse. In this case I measured:</p>
<div>
<ul>
<li>number of garbage collector calls when loading HeiaHeia-feed</li>
<li>local tests execution time (unit + functional)</li>
<li>application server CPU load and average response time</li>
</ul>
</div>
<p>To measure number of garbage collector calls per one page I used <a href="http://www.coffeepowered.net/2009/06/13/fine-tuning-your-garbage-collector/" target="_blank">Scrap &#8211; a nice tool by Chris Heald</a>. Chris also describes the tuning process in great detail, so I&#8217;m not going to repeat it &#8211; just go and read his blog.</p>
<p>To measure local test execution time I just ran <span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;">rake test </span>5 times and took the average of all runs.</p>
<p>To measure application server CPU load and average response time I used <a href="http://www.newrelic.com/" target="_blank">NewRelic</a> tool (free version should be enough to do the measurement).</p>
<p>When I first loaded feed page with Scrap enabled I saw 36 GC cycles, and Ruby spend 1.12s in GC cycles (these figures are from the development server, so response time is big). After playing a bit with the settings and monitoring GC cycles number and unused heap after each allocation with Scrap, I ended up with the same settings as Twitter uses in production:</p>
<pre><code>export RUBY_HEAP_MIN_SLOTS=500000
export RUBY_HEAP_SLOTS_INCREMENT=250000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=50000000</code></pre>
<p>These settings reduced GC cycles number down to 7 (from 36), and Ruby spent now only 0.62s in GC instead of 1.12s when loading feed page (again, load times are bigger on our development server).</p>
<p>After introducing same settings on my local machine project tests took only 148s &#8211; down from 274 seconds before optimisation &#8211; a whopping 46% improvement.</p>
<p>We have multiple identical application servers, so I introduced the new settings only on one of the application servers, to compare the results on a live system (during low traffic hours). Here&#8217;s the picture from NewRelic:</p>
<pre><span style="font-family: monospace;">Server        Instances        Apdex          Resp.time    Throughput    CPU          Memory
</span><span style="font-family: monospace;">hh-app1     3 Instances         0.86      	407 ms       30 rpm      14 %	      349 MB
</span><span style="font-family: monospace;">hh-app2     3 Instances         0.91   	        311 ms	     30 rpm       8 %	      413 MB</span></pre>
<p>hh-app2 had optimised garbage collector. With the same throughput CPU load  was only 8% vs 14% with non-optimised GC. However that improvement came at a cost of increased memory consumption (413M vs 349M). However response time and lower CPU load proved to be a lot more important than memory consumption, so I rolled out the new settings on all production servers.</p>
<p>Making <a href="http://nginx.org/" target="_blank">nginx</a> utilise GC settings when spawning <a href="http://www.modrails.com/" target="_blank">Passenger</a> instances is easy, and is well <a href="http://www.coffeepowered.net/2009/06/13/fine-tuning-your-garbage-collector/" target="_blank">described by Chris</a>. Here are instructions that work nice with server and Nginx setup on Ubuntu as I described in <a href="http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html" target="_blank">earlier posts</a>.</p>
<p>Create /usr/local/bin/ruby-with-env file (as a root) that will set GC settings in the environment and then launch Ruby:</p>
<pre>#!/bin/bash
export RUBY_HEAP_MIN_SLOTS=1500000
export RUBY_HEAP_SLOTS_INCREMENT=500000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=50000000
exec "/usr/local/bin/ruby" "$@"</pre>
<div>Make this file executable by all:</div>
<pre>sudo chmod a+x /usr/local/bin/ruby-with-env</pre>
<div>Now tell Passenger to use that file instead of launching Ruby directly &#8211; edit /opt/nginx/conf/nginx.conf and replace</div>
<pre>passenger_ruby /usr/local/bin/ruby;</pre>
<div>with</div>
<pre>passenger_ruby /usr/local/bin/ruby-with-env;</pre>
<div>Now restart Nginx &#8211; and you&#8217;ve got yourself a faster Ruby!</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F10%2Fincreasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html&amp;title=Increasing%20Ruby%20interpreter%20performance%20by%20adjusting%20garbage%20collector%20settings" id="wpa2a_10"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/10/increasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Running Rails applications using Nginx with Passenger on Ubuntu Server</title>
		<link>http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html</link>
		<comments>http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html#comments</comments>
		<pubDate>Fri, 14 May 2010 10:40:50 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[mod_rails]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=279</guid>
		<description><![CDATA[If you&#8217;re planning to run Rails applications on Nginx using Phusion Passenger, and do it on Ubuntu Linux, here&#8217;s what needs to be done. Even though there&#8217;s Ubuntu nginx package available (which works perfectly when you&#8217;re running PHP apps using FCGI), if you want to take into use Phusion Passenger, you&#8217;ll need to recompile Nginx [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/enterprise_logo.png"><img class="alignleft size-full wp-image-281" title="enterprise_logo" src="http://www.ivankuznetsov.com/wp-content/uploads/enterprise_logo.png" alt="" width="261" height="68" /></a>If you&#8217;re planning to run <a href="http://rubyonrails.org/" target="_blank">Rails</a> applications on <a href="http://www.nginx.org" target="_blank">Nginx</a> using <a href="http://www.modrails.com/" target="_blank">Phusion Passenger</a>, and do it on <a href="http://www.ubuntu.com" target="_blank">Ubuntu</a> Linux, here&#8217;s what needs to be done.</p>
<p>Even though there&#8217;s Ubuntu nginx package available (which works perfectly when you&#8217;re running <a href="http://www.ivankuznetsov.com/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html">PHP apps using FCGI</a>), if you want to take into use Phusion Passenger, you&#8217;ll need to recompile Nginx from sources.</p>
<p>Instructions below were verified on Ubuntu 10.04 (Lucid Lynx) Server Edition.</p>
<p><span id="more-279"></span></p>
<p>If you already have Nginx ubuntu package installed, uninstall it (NOTE! purge will delete all configuration files &#8211; so if you changed them &#8211; make a backup for future reference):</p>
<pre>sudo aptitude purge nginx</pre>
<p>Assuming you already have Rails stack installed, install Passenger gem:</p>
<pre>sudo gem install passenger</pre>
<p>At the time of this writing the latest version of Passenger is 2.2.11</p>
<p>Let&#8217;s check dependencies that Ubuntu nginx package has and install them before compilation:</p>
<pre>aptitude show nginx | grep Depends</pre>
<div>You&#8217;ll see something like:</div>
<pre>Depends: libc6 (&gt;= 2.4), libpcre3 (&gt;= 7.7), libssl0.9.8 (&gt;= 0.9.8k-1), zlib1g</pre>
<div>Install build dependencies and start nginx module installation (it will offer you to recompile nginx)</div>
<pre>sudo apt-get install libc6 libpcre3 libssl0.9.8 zlib1g
sudo /usr/local/bin/passenger-install-nginx-module</pre>
<div>Choose option 1 (Yes: download, compile and install Nginx for me) unless you need special configuration parameters or need features not enabled by default (like SSL).</div>
<div>Further instructions assume that you also chose default installation directory /opt/nginx.</div>
<div>If you&#8217;ve purchased Passenger Enterprise Edition, don&#8217;t forget to register it:</div>
<pre>sudo /usr/local/bin/passenger-make-enterprisey</pre>
<div>Now add nginx init script (I just copied this from Ubuntu default nginx package):</div>
<pre>sudo vim /etc/init.d/nginx</pre>
<div>with the following content:</div>
<pre>#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/nginx/sbin
DAEMON=/opt/nginx/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
        . /etc/default/nginx
fi

set -e

. /lib/lsb/init-functions

test_nginx_config() {
  if nginx -t $DAEMON_OPTS
  then
    return 0
  else
    return $?
  fi
}

case "$1" in
  start)
        echo -n "Starting $DESC: "
        test_nginx_config
        start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
                --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
                --exec $DAEMON || true
        echo "$NAME."
        ;;
  restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON || true
        sleep 1
        test_nginx_config
        start-stop-daemon --start --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
        ;;
  reload)
        echo -n "Reloading $DESC configuration: "
        test_nginx_config
        start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid \
            --exec $DAEMON || true
        echo "$NAME."
        ;;
  configtest)
        echo -n "Testing $DESC configuration: "
        if test_nginx_config
        then
          echo "$NAME."
        else
          exit $?
        fi
        ;;
  status)
        status_of_proc -p /var/run/$NAME.pid "$DAEMON" nginx &amp;&amp; exit 0 || exit $?
        ;;
  *)
        echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest}" &gt;&amp;2
        exit 1
        ;;
esac

exit 0</pre>
<div>Now make this script executable add it to default run levels:</div>
<pre>sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults</pre>
<div>Edit  nginx.conf to look like this:</div>
<pre>user www-data;
worker_processes  4;

error_log  /opt/nginx/logs/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  8192;
    use epoll;
}

http {
    passenger_root /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.11;
    passenger_ruby /usr/local/bin/ruby;

    include       /opt/nginx/conf/mime.types;

    # set a default type for the rare situation that
    # nothing matches from the mimie-type include
    default_type application/octet-stream;

    # This log format is compatible with any tool like awstats
    # that can parse standard apache logs.
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"' ;

    access_log  /opt/nginx/logs/access.log;

    sendfile        on;
    tcp_nopush     on;

    keepalive_timeout  0;
    tcp_nodelay        on;

    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    include /opt/nginx/conf/sites-enabled/*;
}</pre>
<div>Now create virtual hosts structure (so that it looks like the structure created by Ubuntu original nginx package):</div>
<div>
<pre>sudo mkdir /opt/nginx/conf/sites-available
sudo mkdir /opt/nginx/conf/sites-enabled</pre>
</div>
<div>Now it is time to configure your first rails site. Create virtual host configuration in sites-available.</div>
<pre>sudo vim /opt/nginx/conf/sites-available/mysite.com</pre>
<div>Content can be something like:</div>
<pre>server {
        listen   80;
        server_name  www.mysite.com;

        access_log  /home/user/logs/www.mysite.com/access.log;
        root   /home/user/www.mysite.com/public;

        # serve static content directly
        location ~* \.(ico|jpg|gif|png|css|js|swf|html)$ {
          if (-f $request_filename) {
            expires max;
            break;
          }
        }

        passenger_enabled on;

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
          deny  all;
        }
}</pre>
<div>Make a symlink in sites-enabled directory and restart nginx.</div>
<pre>sudo ln -s /opt/nginx/conf/sites-available/mysite.com /opt/nginx/conf/sites-enabled/mysite.com
sudo /etc/init.d/nginx restart</pre>
<div>Now open the browser and check that your site is working.</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F05%2Frunning-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html&amp;title=Running%20Rails%20applications%20using%20Nginx%20with%20Passenger%20on%20Ubuntu%20Server" id="wpa2a_12"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Informal notes from #frozenrails 2010</title>
		<link>http://www.ivankuznetsov.com/2010/05/informal-notes-from-frozenrails-2010.html</link>
		<comments>http://www.ivankuznetsov.com/2010/05/informal-notes-from-frozenrails-2010.html#comments</comments>
		<pubDate>Tue, 11 May 2010 07:17:53 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[frozenrails]]></category>
		<category><![CDATA[ror]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=248</guid>
		<description><![CDATA[Thanks to organisers from Kisko Labs and the HHLinuxClub on Friday, May 7th, 2010 Finland got its first  Rails conference. Conference has drawn very interesting speakers and  international crowd &#8211; from Finland (naturally), Sweden, Poland, Germany, Russia and other countries. I made a few notes from selected talks on the conference. Chris Wanstrath / GitHub (@defunkt) Slides: [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/frozen_rails_logo.png"><img class="alignleft " title="frozen_rails_logo" src="http://www.ivankuznetsov.com/wp-content/uploads/frozen_rails_logo.png" alt="" width="99" height="95" /></a>Thanks to organisers from <a href="http://www.kiskolabs.com/">Kisko Labs</a> and the <a href="http://www.hhlinuxclub.org/">HHLinuxClub</a> on Friday, May 7th, 2010 Finland got its first  Rails conference.</p>
<p>Conference has drawn very interesting speakers and  international crowd &#8211; from Finland (naturally), Sweden, Poland, Germany, Russia and other countries. I made a few notes from selected talks on the conference.</p>
<h3>Chris Wanstrath / GitHub (<a href="http://twitter.com/defunkt" target="_blank">@defunkt</a>)</h3>
<ul>
<li>Slides: <a href="http://www.slideshare.net/err/inside-github" target="_blank">http://www.slideshare.net/err/inside-github</a></li>
<li><a href="http://www.youtube.com/watch?v=4XpnKHJAok8" target="_blank">Linus Trovalds Google tech talk about git</a> &#8211; where Linus tell you that you&#8217;re stpid if you&#8217;re not using git</li>
<li><a href="http://github.com/talison/rack-mobile-detect" target="_blank">rack-mobile-detect</a> – is used by GitHub, super useful if you&#8217;re planning to create mobile optimized version</li>
<li>GitHub uses Unicorn as an application server – personally I&#8217;m not sure if that&#8217;s better than Apache + Passenger. Chris tells that Unicorn is cool, because does fair load balancing on Linux kernel level, also Rails are loaded only once &#8211; and then required number of processes are forked &#8211; and this is very fast, a lot faster than loading rails separately for each Mongrel. And when one of the processes dies &#8211; there&#8217;s no need to re-load Rails, but just fork another process.</li>
<li>GitHub users <a href="http://github.com/blog/531-introducing-bert-and-bert-rpc" target="_blank">BERT</a> to forward requests to one of their six servers – BERT to Erlang is the same as JSON to JavaScript</li>
<li>GitHub doesn&#8217;t use <a href="http://github.com/collectiveidea/delayed_job" target="_blank">delayed_job</a> anymore since they needed several queues with different priorities &#8211; so far they use <a href="http://github.com/blog/542-introducing-resque" target="_blank">resque</a>, but are considering developing a real queue management system</li>
</ul>
<p><span id="more-248"></span></p>
<h3>Jose Valim / Plataforma (<a href="http://twitter.com/josevalim" target="_blank">@josevalim</a>)</h3>
<ul>
<li>Brazilian Rails consultants and developers: <a href="http://plataformatec.com.br/" target="_blank">http://plataformatec.com.br/</a></li>
<li>Developed several interesting components to make their life easier &#8211; extracted common components from several customer projects and open-sourced them</li>
<li>User authorisation and roles: Devise – <a href="http://blog.plataformatec.com.br/2010/04/authentication-is-with-devise/" target="_blank">http://blog.plataformatec.com.br/2010/04/authentication-is-with-devise/</a></li>
<li><a href="http://blog.plataformatec.com.br/2010/04/authentication-is-with-devise/" target="_blank"></a>Nice forms with labels, error handling, etc. : Simple Form – <a href="http://github.com/plataformatec/simple_form" target="_blank">http://github.com/plataformatec/simple_form</a></li>
</ul>
<h3>Mike Dirolf / MongoDB (<a href="http://twitter.com/mdirolf" target="_blank">@mdirolf</a>) &amp; Jonathan Weiss / CouchDB (<a href="http://twitter.com/jweiss" target="_blank">@jweiss</a>)</h3>
<ul>
<li>Two very interesting NoSQL presentations: <a href="http://www.slideshare.net/mdirolf/mongodb-at-frozenrails" target="_blank">http://www.slideshare.net/mdirolf/mongodb-at-frozenrails</a>, <a href="http://www.slideshare.net/jweiss/couchdb-on-rails-frozenrails-2010" target="_blank">http://www.slideshare.net/jweiss/couchdb-on-rails-frozenrails-2010</a></li>
<li>Answering a question from the audience Mike said that fault tolerance is something that is not quite there yet in MongoDB &#8211; there is a possibility to do recovery, but there&#8217;s a chance data might be lost</li>
<li>There is no such issue in CouchDB, it also is written in Erland and provides REST API</li>
<li>Links to project homepages: <a href="http://couchdb.apache.org/" target="_blank">http://couchdb.apache.org/</a> &amp;<a href=" http://www.mongodb.org/" target="_blank"> http://www.mongodb.org/</a> &#8211; worth taking a look at both</li>
</ul>
<h3>Yehuda Katz / EngineYard (<a href="http://twitter.com/wycats" target="_blank">@wycats</a>)</h3>
<ul>
<li>Very interesting presentation about developing web application for mobile devices (in Rails 3)</li>
<li>One of the central messages &#8211; HTML5 is coming &#8211; learn how to use it now, if you want to stay in business</li>
<li>I really hope Yehuda will publish his slides &#8211; it was a presentation worth spreading around</li>
<li>interesting thoughts:
<ul>
<li>same optimization methods as we traditionally use for Rails apps on desktop are not suitable for mobile browsers due to constraints &#8211; connection availability, memory, cpu, battery, etc.</li>
<li>don&#8217;t count on browser cach on mobile devices – separate data and presentation, cache presentation using localStorage feature of HTML5, load only data from the web after that</li>
<li>mobile browsers are updated a lot faster than desktop borwser &#8211; there are new browsers in the new phones, and nobody uses 2 year old phone</li>
<li>HTML5 will become mainstream on mobile devices a lot faster than on desktop (IE6 will not happen on mobile)</li>
<li>when developing apps for mobile take into account that in some places people still pay per kilobyte of traffic</li>
<li>incremental rendering on the mobile is evil &#8211; it consumes battery and can be very slow, unpleasant and unusable for the user</li>
</ul>
</li>
<li>battery &#8211; unoptimized sites can easily drain the battery, and even though users are most likely to blame the phone manufacturer it is good to think about it</li>
<li>http://Railsdispatch.com – recommended reading about Rails 3</li>
</ul>
<h3>Carl Lerche / Engine Yard (<a href="http://twitter.com/carllerche" target="_blank">@carllerche</a>)</h3>
<ul>
<li>Carl told about Rails 3 and migration to version 3 from earlier ones <a href="http://www.slideshare.net/carllerche/frozen-rails-slides" target="_blank">http://www.slideshare.net/carllerche/frozen-rails-slides</a></li>
<li>Migration itself is not that difficult (provided that you know what you&#8217;re doing) – it can even be done in 15 minutes, but thus far stability and performance of Rails 3 / Ruby 1.9.1 are not quite there yet</li>
<li>Rails 3 is not finished &#8211; the plan is to make RC for RailsConf, and the it will be released “when it’s ready”</li>
<li>When asked if they have done performance tests on Rails 3, Carl answered that, yes, they did, and its sad.  Performance optimization is the next big step after stabilization.</li>
<li>When asked which Ruby release is better to use with Rails 3, Carl answered &#8211; 1.8.7, since Ruby 1.9.1 still segfaults and is not ready for production sites.</li>
</ul>
<h3>JetBrains (<a href="http://twitter.com/rubymine" target="_blank">@rubymine</a>):</h3>
<ul>
<li>new release of RubyMine is available with Rails3 support</li>
<li>guys from JetBrains tell that  TextMate development/maintenance is lagging behind, and they observe migration of TextMate and even vim users to RubyMine (there&#8217;s now vim interface emultion)</li>
</ul>
<h3>overall impression:</h3>
<ul>
<li>Apple is the king – virtually everybody was walking around with either MacBook, iPhone, iPad or all of the above</li>
<li>first Rails conference in Finland was a huge success &#8211; I really hope there will be FrozenRails 2011</li>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F05%2Finformal-notes-from-frozenrails-2010.html&amp;title=Informal%20notes%20from%20%23frozenrails%202010" id="wpa2a_14"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/05/informal-notes-from-frozenrails-2010.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Setting up Ruby, Rails, Git and Redmine on Dreamhost</title>
		<link>http://www.ivankuznetsov.com/2009/07/setting-up-ruby-rails-git-and-redmine-on-dreamhost.html</link>
		<comments>http://www.ivankuznetsov.com/2009/07/setting-up-ruby-rails-git-and-redmine-on-dreamhost.html#comments</comments>
		<pubDate>Thu, 30 Jul 2009 14:58:27 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Dreamhost]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[redmine]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=195</guid>
		<description><![CDATA[The task is to have: - Redmine installation on redmine.mydomain.com - Several Git repositories on git.mydomain.com with different access rights to each one This proved to be a non-trivial task. There is a number of tutorials on the net, but none of them described the full solution. So after getting it all to work, I [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-196" title="Git, RedMine, Ruby, Rails on Dreamhost" src="http://www.ivankuznetsov.com/wp-content/uploads/git.png" alt="Git, RedMine, Ruby, Rails on Dreamhost" width="200" height="150" />The task is to have:<br />
- Redmine installation on redmine.mydomain.com<br />
- Several Git repositories on git.mydomain.com with different access rights to each one</p>
<p>This proved to be a non-trivial task. There is a number of tutorials on the net, but none of them described the full solution. So after getting it all to work, I decided to share all the tips and tricks. Feel free to comment, if you will find problems with the following set of instructions.<br />
<span id="more-195"></span>SSH to redmine.mydomain.com as a user that will be running Redmine (in the following examples it will be &#8216;redmine_user&#8217;).<br />
First, you need to compile openssl &#8211; it will be required for curl, git and redmine.</p>
<pre>mkdir ~/tmp
cd ~/tmp
wget http://www.openssl.org/source/openssl-0.9.8k.tar.gz
tar xzvf openssl-0.9.8k.tar.gz
cd openssl-0.9.8k
./config shared zlib --prefix=$HOME/.packages
make
make install</pre>
<p>Let&#8217;s tell the world that we keep binaries and libraries also in the local directory. Edit ~/.bashrc (it is used by all non-login shells):</p>
<pre>export TZ='Europe/Helsinki'
export PATH="$HOME/.packages/bin:$PATH"
export LD_LIBRARY_PATH="$HOME/.packages/lib"
export GEM_HOME="$HOME/.gems"
export GEM_PATH="$GEM_HOME:/usr/lib/ruby/gems/1.8"
export PATH="$HOME/.packages/bin:$HOME/.gems/bin:$PATH"
export RUBYLIB="$HOME/.packages/lib:$RUBYLIB"
export LD_LIBRARY_PATH="$HOME/.packages/lib"

# this ensures our gem install processes don't get killed by the DreamHost police
alias gem="nice -n19 ~/.packages/bin/gem"</pre>
<p>(You can skip TZ &#8211; it is just usefule to have correct time set for your environment. Use tzselect to find out correct TZ string for your region)</p>
<p>And edit ~/.bash_profile (it is used by login shells):</p>
<pre>umask 002
PS1='[\h:$PWD]$ '
alias ll="ls -l"
EDITOR="/usr/bin/vim"
. .bashrc</pre>
<p>Now let&#8217;s apply the changes in active shell:</p>
<pre>cd ~ : . .bash_profile</pre>
<p>Then you need to compile curl, to be able to compile git with curl and execute clone commands on your server.</p>
<pre>cd ~/tmp
wget http://curl.haxx.se/download/curl-7.19.5.tar.gz
tar xzvf curl-7.19.5.tar.gz
cd curl-7.19.5
./configure --prefix=$HOME/.packages --with-ssl=$HOME/.packages
make
make install</pre>
<p>Now get and compile Git. If you are not using Dreamhost PS, you might want to compile it with NO_MMPAP=1, to reduce<br />
probability of git process getting killed by Dreamhost police robots due to extensive memory</p>
<pre>cd ~/tmp
wget http://www.kernel.org/pub/software/scm/git/git-1.6.4.tar.gz
tar xzvf git-1.6.4.tar.gz
cd git-1.6.4
./configure --prefix=$HOME/.packages --with-curl=$HOME/.packages
make
make install</pre>
<p>Let&#8217;s start with ruby and rails related stuff. First readline library is needed, for script/console to work.</p>
<pre>cd ~/tmp
wget http://ftp.gnu.org/gnu/readline/readline-5.2.tar.gz
tar xzvf readline-5.2.tar.gz
cd readline-5.2
./configure --prefix=$HOME/.packages
make
make install</pre>
<p>Install ruby:</p>
<pre>cd ~/tmp
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz
tar zxvf ruby-1.8.7-p72.tar.gz
cd ruby-1.8.7-p72
./configure --prefix=$HOME/.packages --with-openssl-dir=$HOME/.packages --with-readline-dir=$HOME/.packages
make
make install</pre>
<p>Install rubygems:</p>
<pre>cd ~/tmp
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
tar zxvf rubygems-1.3.5.tgz
cd rubygems-1.3.5
ruby setup.rb config --prefix=$HOME/.packages
ruby setup.rb setup
ruby setup.rb install</pre>
<p>Now you can install all required gems and freeze them if necessary.</p>
<p><strong>Installing RedMine</strong></p>
<p>Refer to <a href="http://wiki.dreamhost.com/Redmine" target="_blank">http://wiki.dreamhost.com/Redmine</a> for details.</p>
<p>But there&#8217;s one trick &#8211; if you want RedMine to use just compiled version of Git &#8211; edit in lib/redmine/scm/adapters/git_adapter.rb:</p>
<pre># Git executable name
GIT_BIN = "/home/username/.packages/bin/git"</pre>
<p>If this is not done, default Dreamhost git will be used (which is too old at the moment 1.4.4.4) and Git repository browsing will not work in RedMine<br />
(see <a href="http://groups.google.com/group/phusion-passenger/browse_thread/thread/5080d7c7cfbcf20e" target="_blank">http://groups.google.com/group/phusion-passenger/browse_thread/thread/5080d7c7cfbcf20e</a>).</p>
<p><strong>Setting up Git repository</strong></p>
<p>Refer to <a href="http://wiki.dreamhost.com/Git" target="_blank">http://wiki.dreamhost.com/Git</a> for details.</p>
<p>Couple of tricks here. There are bugs in WebDAV functionality in Ubuntu &#8211; so if you&#8217;re using it &#8211; launch Nautilus, use &#8220;File-&gt;Connect to server&#8230;&#8221; menu from there (not from the system menu), don&#8217;t enter user name in the dialog &#8211; leave it empty and enter it when you&#8217;re requested username and password in the next dialog.</p>
<p>When setting up WebDAV access rights, give access to user &#8220;redmine&#8221;.</p>
<p><strong>Setting Git repository copy for Redmine</strong></p>
<p>Create ~/.netrc for your redmine user on Dreamhost</p>
<p>Insert the following line in that file</p>
<pre>machine git.mydomain.com login redmine password [redmine_password]</pre>
<p>where redmine_password is the password you gave to user redmine in the previous step.<br />
.netrc will ensure that password is not asked when git is accessing the repository.<br />
You don&#8217;t need to bother about creating .netrc if you have a public repository (or at least available for cloning without password).</p>
<p><strong>Create a local copy of the repository</strong></p>
<p>For RedMine to be able to display Git repository, it needs to have a local clone of the repository.</p>
<pre>mkdir ~/git_project_clones
cd git_project_clones
git clone http://git.mydomain.com/repository_name</pre>
<p>Now you should have a local copy that can be used from RedMine.<br />
All you have left to do is to set up regular pulls from the master repository to this local copy. Use command</p>
<pre>crontab -e</pre>
<p>Add the following line to pull latest change into local copy every 5 minutes:</p>
<pre>*/5 * * * * cd /home/redmine_user/git_project_clones/repository_name &amp;&amp; /home/redmine_user/.packages/bin/git pull</pre>
<p>Make sure that you specify full path to git &#8211; otherwise it will execute Dreamhost default git 1.4.4.4 and command will fail with &#8220;refusing to create funny ref &#8216;remotes/origin/*&#8217; locally&#8221; error.</p>
<p>Save and exit cron editor.</p>
<p>(You might also want to check Redmine own wiki: <a href="http://www.redmine.org/wiki/redmine/HowTo_keep_in_sync_your_git_repository_for_redmine" target="_blank">http://www.redmine.org/wiki/redmine/HowTo_keep_in_sync_your_git_repository_for_redmine</a>)</p>
<p>Set repository in the settings of your project in RedMine: /home/redmine_user/git_project_clones/repository_name/.git</p>
<p>Now you need to manually update Git repository changesets in RedMine:</p>
<pre>cd ~/mydomain.com
script/runner "Repository.fetch_changesets" -e production</pre>
<p>And set a hook to your repository to do this every time repository is updated &#8211; edit ~/git_project_clones/repository_name/.git/hooks/post-update file and add the following command ther:</p>
<pre>cd /home/redmine_user/mydomain.com &amp;&amp; script/runner "Repository.fetch_changesets" -e production</pre>
<p>When writing this blogpost I found a lot of useful information on Dreamhost own wiki as well on these blog posts:<br />
<a href="http://www.wavethenavel.com/2008/09/08/bootstrapping-a-dreamhost-account-for-rails-and-git/" target="_blank"> http://www.wavethenavel.com/2008/09/08/bootstrapping-a-dreamhost-account-for-rails-and-git/</a><br />
<a href="http://juliobiason.net/2008/05/19/git-repositories-on-dreamhost-via-ssh/" target="_blank"> http://juliobiason.net/2008/05/19/git-repositories-on-dreamhost-via-ssh/</a><br />
<a href="http://www.simonecarletti.com/blog/2009/07/configuring-git-repository-with-redmine/" target="_blank"> http://www.simonecarletti.com/blog/2009/07/configuring-git-repository-with-redmine/</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2009%2F07%2Fsetting-up-ruby-rails-git-and-redmine-on-dreamhost.html&amp;title=Setting%20up%20Ruby%2C%20Rails%2C%20Git%20and%20Redmine%20on%20Dreamhost" id="wpa2a_16"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2009/07/setting-up-ruby-rails-git-and-redmine-on-dreamhost.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Radiant CMS</title>
		<link>http://www.ivankuznetsov.com/2008/03/radiant-cms.html</link>
		<comments>http://www.ivankuznetsov.com/2008/03/radiant-cms.html#comments</comments>
		<pubDate>Sun, 23 Mar 2008 16:58:13 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[Weblogs]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/2008/03/radiant-cms.html</guid>
		<description><![CDATA[Easter weekend didn&#8217;t start well &#8211; I decided to upgrade Joomla on one of my sites to version 1.5.1 from 1.0 and upgrade just totally ruined the entire site &#8211; content was lost, template wasn&#8217;t compatible with version 1.5.1. At first I thought that the reason is Dreamhost&#8216;s automatic one-click upgrade that I used, but [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.ivankuznetsov.com/wp-content/uploads/2008/03/screenshot.png" class="alignleft" alt="Radiant CMS" />Easter weekend didn&#8217;t start well &#8211; I decided to upgrade <a href="http://www.joomla.org/">Joomla</a> on <a href="http://www.kvartira.fi">one of my sites</a> to version 1.5.1 from 1.0 and upgrade just totally ruined the entire site &#8211; content was lost, template wasn&#8217;t compatible with version 1.5.1. At first I thought that the reason is <a href="http://www.dreamhost.com">Dreamhost</a>&#8216;s automatic one-click upgrade that I used, but even after manual reinstall Joomla kept giving weird &#8220;Fatal error: Call to a member function name() on a non-object in helper.php on line 219&#8243; error in Control Panel, and legacy mode for old template didn&#8217;t work.</p>
<p><em>(To be fare I should say that <a href="http://www.dreamhost.com">Dreamhost</a> provides excellent value for money. If you are looking for a good hosting &#8211; use IVANKUZNETSOV promocode and get a $50 discount when setting up an account on Dreamhost) </em></p>
<p>A thought of reinstalling all modules and reconfiguring Joomla from scratch was simply too depressive, so I decided to try another CMS. As a <a href="http://www.rubyonrails.org/">Ruby on Rails</a> convert and a strong believer in open-source ideology I decided to go for <a href="http://www.radiantcms.org">Radiant</a> &#8211; open-source CMS written in RoR. It is still in beta (latest release is 0.6.4), but it is surprisingly stable and powerful. Take a look at the footer of <a href="http://www.ruby-lang.org">www.ruby-lang.org</a> &#8211; official Ruby programming language web site &#8211; it is powered by Radiant <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Installation of Radiant was rather easy &#8211; thanks to <a href="http://wiki.radiantcms.org/How_To_Deploy_on_Dreamhost">this</a> guide and my prior experience with RoR applications deployment on Dreamhost. It took me a couple of hours to figure out how to actually create sites with Radiant &#8211; there are not that many tutorials available yet, so it is pretty much  &#8220;make by example&#8221;. Split into pages, snippets and layouts makes a lot of sense onse you get your head around it.</p>
<p>From my experience Joomla is an overkill for most of the small sites, and despite being WYSIWYG, it still requires a professional or at least a tech savvy to configure it. After Radiant is set up and configured it is no more difficult to add content there than to edit a wiki page because of its <a href="http://www.textism.com/tools/textile/">Textile</a> support. But it is so much simpler and easier to use than Joomla.</p>
<p>I managed to restore the ruined site in a day&#8217;s time &#8211; fetched most of the lost content from Google cache, converted Joomla template into Radiant&#8217;s layouts and recreated the pages (well, it was a small site after all). First time I dealt with Joomla &#8211; I spent several days trying to figure out where are the settings that I actually need in the endless menus.</p>
<p>Radiant is clearly following &#8220;less is better&#8221; principle. If you want to try Radiant &#8211; there&#8217;s a <a href="http://radiantcms.org/demo/">live demo</a> where you can do whatever you want with the content.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2008%2F03%2Fradiant-cms.html&amp;title=Radiant%20CMS" id="wpa2a_18"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2008/03/radiant-cms.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

