<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title>Production Hacks</title>
  <id>http://www.production-hacks.com</id>
  <updated>2010-04-14T00:00:00Z</updated>
  <author>
    <name>Jose Fernandez</name>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/productionhacks" /><feedburner:info uri="productionhacks" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Active Users with Redis</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/7lrdRC3lXZs/" rel="alternate" />
    <id>http://www.production-hacks.com/2011/03/22/active-users-with-redis/</id>
    <published>2011-03-22T00:00:00Z</published>
    <updated>2011-03-22T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;Want to log and display the active users in your web application? Enjoy using &lt;a href="http://redis.io"&gt;Redis&lt;/a&gt;? Read on&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Want to log and display the active users in your web application? Enjoy using &lt;a href="http://redis.io"&gt;Redis&lt;/a&gt;? Read on.&lt;/p&gt;

&lt;h2&gt;Scenario&lt;/h2&gt;

&lt;p&gt;A user with ID &lt;span style="color:green"&gt;123&lt;/span&gt; hits our web application.  The unix timestamp (seconds since epoch) for the current date and time is: &lt;span style="color:blue"&gt;1300803419&lt;/span&gt;.&lt;/p&gt;

&lt;h2&gt;Logging&lt;/h2&gt;

&lt;p&gt;We insert the user’s ID as a member of the &lt;span style="color:#FF6600"&gt;&amp;lsquo;active-users&amp;rsquo;&lt;/span&gt; Sorted Set, using the timestamp as the score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ZADD&lt;/strong&gt; &lt;span style="color:#FF6600"&gt;&amp;lsquo;active-users&amp;rsquo;&lt;/span&gt; &lt;span style="color:blue"&gt;1300803419&lt;/span&gt; &lt;span style="color:green"&gt;123&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;If &lt;span style="color:green"&gt;123&lt;/span&gt; was already a member of the Sorted Set, Redis would &lt;strong&gt;only update&lt;/strong&gt; the score to the new timestamp, effectively setting the user&amp;rsquo;s last action timestamp.&lt;/p&gt;

&lt;h2&gt;Display&lt;/h2&gt;

&lt;p&gt;If you want to display the active users in the last 15 minutes, you will first need to generate 2 timestamps.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;timestamp1&lt;/code&gt; = 15 minutes ago&lt;/p&gt;

&lt;p&gt;&lt;code&gt;timestamp2&lt;/code&gt; = current date and time&lt;/p&gt;

&lt;p&gt;Then return a range of members in the &lt;span style="color:#FF6600"&gt;&amp;lsquo;active-users&amp;rsquo;&lt;/span&gt; Sorted Set using these timestamps as the min and max scores.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;user_ids&lt;/code&gt; = &lt;strong&gt;ZRANGEBYSCORE&lt;/strong&gt; &lt;span style="color:#FF6600"&gt;&amp;lsquo;active-users&amp;rsquo;&lt;/span&gt; &lt;code&gt;timestamp1&lt;/code&gt; &lt;code&gt;timestamp2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The returned array will contain the user ID’s of all users active in the last 15 minutes.&lt;/p&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;What I like about this approach is that it’s simple and lightweight; only 1 entry in the Sorted Set per user.  You can also query “active users in the last X minutes/days/months” up to the date when you began logging the requests.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/7lrdRC3lXZs" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2011/03/22/active-users-with-redis/</feedburner:origLink></entry>
  <entry>
    <title>ActionMailer MissingTemplate error in Rails 2.3</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/VezPoul5P1Y/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/07/20/actionmailer-missingtemplate-error-in-rails-23/</id>
    <published>2010-07-20T00:00:00Z</published>
    <updated>2010-07-20T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;In Rails 2.3, if you&amp;rsquo;re using implicit multipart emails for your ActionMailer views (the content type is part of the file name), ActionMailer will have problems locating the correct template during tests and background jobs. I ran into this problem when setting up background emailing with &lt;a href="http://github.com/zapnap/resque_mailer" title="resque mailer"&gt;resque_mailer&lt;/a&gt;&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;In Rails 2.3, if you&amp;rsquo;re using implicit multipart emails for your ActionMailer views (the content type is part of the file name), ActionMailer will have problems locating the correct template during tests and background jobs. I ran into this problem when setting up background emailing with &lt;a href="http://github.com/zapnap/resque_mailer" title="resque mailer"&gt;resque_mailer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ActionView::MissingTemplate: Missing template my_mailer/mailer_action.erb in view path app/views&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a known and &lt;a href="https://rails.lighthouseapp.com/projects/8994/tickets/2263-rails-232-breaks-implicit-multipart-actionmailer-tests" title="lighhouse ticket"&gt;documented bug&lt;/a&gt;, but the &lt;a href="http://github.com/rails/rails/commit/97e07a88feaf334d7eaa44f66bcd57c08cd587a6" title="patch"&gt;patch&lt;/a&gt; went in after the 2.3.5 release.  Adding the following code to a Rails initializer should fix the problem:&lt;/p&gt;

&lt;script src="http://gist.github.com/482599.js"&gt; &lt;/script&gt;

&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/VezPoul5P1Y" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/07/20/actionmailer-missingtemplate-error-in-rails-23/</feedburner:origLink></entry>
  <entry>
    <title>Redis API access logger</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/aDeYN0KD4co/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/07/10/redis-api-access-logger/</id>
    <published>2010-07-10T00:00:00Z</published>
    <updated>2010-07-10T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;We just launched a REST API for our production Rails app and we wanted to keep track of the API usage by user.  Inserting a row into MySQL or incrementing an existing counter on every request had inevitable scaling issues. We needed something lightweight and fast, Redis was a perfect candidate for the job&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;We just launched a REST API for our production Rails app and we wanted to keep track of the API usage by user.  Inserting a row into MySQL or incrementing an existing counter on every request had inevitable scaling issues. We needed something lightweight and fast, Redis was a perfect candidate for the job.&lt;/p&gt;

&lt;p&gt;Redis has to keep all stored objects in memory, so just putting all data in there and forgetting about it was out of the question.  We decided to only keep a few days of data in Redis and archive the results to MySQL.  Daily API usage stats would be served directly by Redis, archived results on date ranges would be fetched from MySQL.&lt;/p&gt;

&lt;p&gt;Assuming a User with ID 1337 hits the UsersController #update API call on July 10, 2010 &amp;ndash; the process would go like this:&lt;/p&gt;

&lt;p&gt;Increment a Sorted Set of daily &amp;ldquo;Controller#Action&amp;rdquo; values by 1 (the hit count):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ZINCRBY 'api:requests:2010-07-10' 1 'users#update'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Increment a Sorted Set of daily &amp;ldquo;Controller#Action&amp;rdquo; values by User ID:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ZINCRBY 'api:requests:2010-06-30:users#update' 1 1337&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the current date to a Set of dates for which we&amp;rsquo;re currently tracking data:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SADD api:requests:dates '2010-07-10'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We are now able to pull a list of Controller#Action values by date, sorted by the hit count (ZSCORE).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;controller_actions = ZREVRANGE 'api:requests:2010-07-10' 0, -1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hit_count = ZSCORE 'api:requests:2010-07-10' 'users#update'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then using the Controller#Action value, generate a key to pull a list of User IDs that have accessed that action, also sorted by their hit count (ZSCORE).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;user_ids = ZREVRANGE 'api:requests:2010-07-10:users#update' 0, -1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hit_count = ZSCORE 'api:requests:2010-07-10:users#update' 1337&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Finally we archive our daily results to a MySQL table with the following schema:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;date | user_id | controller | action | hit_count&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On a daily cron, we iterate through the Set of archived dates (skipping the current date) and generate the keys needed to pull the API usage stats from Redis.  Once we&amp;rsquo;ve inserted the daily results into MySQL, we can safely delete the daily Sorted Sets and remove the date from the Set:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dates = SMEMBERS 'api:requests:dates'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&amp;hellip; repeat the steps above to pull the usage stats by date, controller#action and user ID &amp;hellip;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DEL 'api:requests:2010-07-10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DEL 'api:requests:2010-07-10:users#update'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SREM 'api:requests:dates' '2010-07-10'&lt;/code&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/aDeYN0KD4co" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/07/10/redis-api-access-logger/</feedburner:origLink></entry>
  <entry>
    <title>Passenger 2.2.14 with bundler08 support</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/XUy3b4OxPjo/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/06/11/passenger-2214-with-bundler08-support/</id>
    <published>2010-06-11T00:00:00Z</published>
    <updated>2010-06-11T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;Passenger 2.2.14 now comes with built in Bundler support for Rails 3, but some Rails 2 apps might have explicitly added Bundler support in the &amp;ldquo;config/preinitializer.rb&amp;rdquo; file.&lt;/p&gt;

&lt;p&gt;To stop Passenger from setting up Bundler (and crashing in the process), just create the &amp;ldquo;config/setup_load_paths.rb&amp;rdquo; file and copy your &amp;ldquo;config/preinitializer.rb&amp;rdquo; content in there.  Passenger will now detect the file and require it instead of running its Bundler setup&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Passenger 2.2.14 now comes with built in Bundler support for Rails 3, but some Rails 2 apps might have explicitly added Bundler support in the &amp;ldquo;config/preinitializer.rb&amp;rdquo; file.&lt;/p&gt;

&lt;p&gt;To stop Passenger from setting up Bundler (and crashing in the process), just create the &amp;ldquo;config/setup_load_paths.rb&amp;rdquo; file and copy your &amp;ldquo;config/preinitializer.rb&amp;rdquo; content in there.  Passenger will now detect the file and require it instead of running its Bundler setup.&lt;/p&gt;

&lt;p&gt;Make sure to keep both files around too make the app backwards compatible with earlier versions of Passenger (for EY-Cloud support).&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/XUy3b4OxPjo" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/06/11/passenger-2214-with-bundler08-support/</feedburner:origLink></entry>
  <entry>
    <title>Domain redirect using rack-rewrite</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/9hbGbtPfOXM/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/06/05/domain-redirect-using-rack-rewrite/</id>
    <published>2010-06-05T00:00:00Z</published>
    <updated>2010-06-05T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;Stick this snippet in at the top of the &amp;ldquo;config.ru&amp;rdquo; file of your Rack app (Rails, Sinatra) to always redirect visitors to the &amp;lsquo;www&amp;rsquo; version of your domain name (&lt;a href="http://github.com/jtrupiano/rack-rewrite"&gt;rack-rewrite&lt;/a&gt; gem required):&lt;/p&gt;

&lt;script src="http://gist.github.com/426802.js?file=config.ru"&gt;&lt;/script&gt;

</summary>
    <content type="html">&lt;p&gt;Stick this snippet in at the top of the &amp;ldquo;config.ru&amp;rdquo; file of your Rack app (Rails, Sinatra) to always redirect visitors to the &amp;lsquo;www&amp;rsquo; version of your domain name (&lt;a href="http://github.com/jtrupiano/rack-rewrite"&gt;rack-rewrite&lt;/a&gt; gem required):&lt;/p&gt;

&lt;script src="http://gist.github.com/426802.js?file=config.ru"&gt;&lt;/script&gt;

&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/9hbGbtPfOXM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/06/05/domain-redirect-using-rack-rewrite/</feedburner:origLink></entry>
  <entry>
    <title>Engine Yard Cloud, New Relic and Hoptoad deploy notifications</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/FQ5TqKTPO6c/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/05/12/engine-yard-cloud-new-relic-and-hoptoad-deploy-notifications/</id>
    <published>2010-05-12T00:00:00Z</published>
    <updated>2010-05-12T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;&lt;a href="http://www.engineyard.com/products/cloud"&gt;Engine Yard&amp;rsquo;s Cloud&lt;/a&gt; platform uses the &lt;a href="http://github.com/ezmobius/chef-deploy"&gt;chef-deploy&lt;/a&gt; gem instead of the more commonly used Capistrano to deploy your Rails app.  Both New Relic and Hoptoad have a built in Capistrano task to notify the services on deploy.  Using a deploy hook we can achieve the same result with EY-Cloud&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;&lt;a href="http://www.engineyard.com/products/cloud"&gt;Engine Yard&amp;rsquo;s Cloud&lt;/a&gt; platform uses the &lt;a href="http://github.com/ezmobius/chef-deploy"&gt;chef-deploy&lt;/a&gt; gem instead of the more commonly used Capistrano to deploy your Rails app.  Both New Relic and Hoptoad have a built in Capistrano task to notify the services on deploy.  Using a deploy hook we can achieve the same result with EY-Cloud.&lt;/p&gt;

&lt;p&gt;Create the following file in &amp;ldquo;RAILS_ROOT/deploy/after_restart.rb&amp;rdquo;&lt;/p&gt;

&lt;script src="http://gist.github.com/398600.js?file=after_restart.rb"&gt;&lt;/script&gt;


&lt;p&gt;The above deploy hook will only fire off when you&amp;rsquo;re deploying to a production environment.  If you&amp;rsquo;re using &lt;a href="http://github.com/carlhuda/bundler/tree/v0.8"&gt;bundler08&lt;/a&gt; instead of Engine Yard&amp;rsquo;s gem manager, then replace the &amp;ldquo;newrelic_cmd&amp;rdquo; with &amp;ldquo;bin/newrelic_cmd&amp;rdquo;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/FQ5TqKTPO6c" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/05/12/engine-yard-cloud-new-relic-and-hoptoad-deploy-notifications/</feedburner:origLink></entry>
  <entry>
    <title>toto and New Relic RPM</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/Il1cHMYc9X0/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/04/20/toto-and-new-relic-rpm/</id>
    <published>2010-04-20T00:00:00Z</published>
    <updated>2010-04-20T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;This blog is powered by &lt;a href="http://cloudhead.io/toto"&gt;toto&lt;/a&gt;, a minimalistic Ruby blogging engine.  It&amp;rsquo;s currently hosted on the &lt;a href="http://www.heroku.com"&gt;Heroku&lt;/a&gt; free plan, which is more than enough for now, but I wanted to know when would be a good time crank up the &lt;a href="http://heroku.com/how/dynos"&gt;dynos&lt;/a&gt;.  Heroku allows you to setup the free version New Relic RPM as an addon, but you will have to follow a couple of extra steps to get toto&amp;rsquo;s requests to show up in New Relic&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;This blog is powered by &lt;a href="http://cloudhead.io/toto"&gt;toto&lt;/a&gt;, a minimalistic Ruby blogging engine.  It&amp;rsquo;s currently hosted on the &lt;a href="http://www.heroku.com"&gt;Heroku&lt;/a&gt; free plan, which is more than enough for now, but I wanted to know when would be a good time crank up the &lt;a href="http://heroku.com/how/dynos"&gt;dynos&lt;/a&gt;.  Heroku allows you to setup the free version New Relic RPM as an addon, but you will have to follow a couple of extra steps to get toto&amp;rsquo;s requests to show up in New Relic.&lt;/p&gt;

&lt;p&gt;First make sure you have added the New Relic RPM addon for Heroku.  If you&amp;rsquo;re not using Heroku or you want you use your own New Relic account, add your newrelic.yml config to the APP_ROOT/config folder.&lt;/p&gt;

&lt;p&gt;Checkout the &lt;a href="http://newrelic.rubyforge.org/svn/newrelic_rpm/"&gt;newrelic_rpm&lt;/a&gt; gem in the vendor/plugins folder.&lt;/p&gt;

&lt;p&gt;Finally, add the following code to your &lt;strong&gt;config.ru&lt;/strong&gt; file (before the toto config block):&lt;/p&gt;

&lt;script src="http://gist.github.com/373436.js?file=config.ru"&gt;&lt;/script&gt;


&lt;p&gt;The last part of the snippet monkey-patches toto&amp;rsquo;s Site#call method to report back to New Relic on each request.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/Il1cHMYc9X0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/04/20/toto-and-new-relic-rpm/</feedburner:origLink></entry>
  <entry>
    <title>MySQL NOT Comparisons and NULL values</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/80p5qjhBGAg/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/04/17/mysql-not-comparisons-and-null-values/</id>
    <published>2010-04-17T00:00:00Z</published>
    <updated>2010-04-17T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;If you&amp;rsquo;re using any of the MySQL NOT logical operators (NOT IN (?), &amp;lt;&gt;, !=) on a column, you should be aware that all records that have a NULL column value will always be &lt;strong&gt;excluded&lt;/strong&gt; by MySQL.&lt;/p&gt;

&lt;p&gt;What if you do want to include the NULL value records? You could try something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT * FROM books WHERE author_id IS NULL OR author_id != 123&lt;/code&gt;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;If you&amp;rsquo;re using any of the MySQL NOT logical operators (NOT IN (?), &amp;lt;&gt;, !=) on a column, you should be aware that all records that have a NULL column value will always be &lt;strong&gt;excluded&lt;/strong&gt; by MySQL.&lt;/p&gt;

&lt;p&gt;What if you do want to include the NULL value records? You could try something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT * FROM books WHERE author_id IS NULL OR author_id != 123&lt;/code&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/80p5qjhBGAg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/04/17/mysql-not-comparisons-and-null-values/</feedburner:origLink></entry>
  <entry>
    <title>Memcached and Passenger connection sharing</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/reWQymHfA3c/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/04/15/memcached-and-passenger-connection-sharing/</id>
    <published>2010-04-15T00:00:00Z</published>
    <updated>2010-04-15T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;One of the few gotchas for Passenger&amp;rsquo;s smart/smart-lv2 spawning methods is the unintentional sharing of file descriptors between workers.  This is actually documented at the very bottom of the &lt;a href="http://www.modrails.com/documentation/Users%20guide.html#_example_1_memcached_connection_sharing_harmful"&gt;Passenger docs&lt;/a&gt;, but you don&amp;rsquo;t really understand the impact of it until it starts wreaking havoc on a highly cached production application&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;One of the few gotchas for Passenger&amp;rsquo;s smart/smart-lv2 spawning methods is the unintentional sharing of file descriptors between workers.  This is actually documented at the very bottom of the &lt;a href="http://www.modrails.com/documentation/Users%20guide.html#_example_1_memcached_connection_sharing_harmful"&gt;Passenger docs&lt;/a&gt;, but you don&amp;rsquo;t really understand the impact of it until it starts wreaking havoc on a highly cached production application.&lt;/p&gt;

&lt;p&gt;We started by getting random Memcache IO timeout errors, which we initially thought were caused by the strain on the server and Memcached running out of memory.  Then the Rails session manager would receive random cached ActiveRecord objects instead of the session hash (we store our sessions in Memcached).&lt;/p&gt;

&lt;p&gt;This last error lead me into the right direction and I found similar issues posted on the web.  The problems were caused by having all Passenger workers share the same memcache-client connection.  They had to be reset when spawned to avoid clashing of cached objects as they get fetched.  Putting the following code in your environment.rb file should take care of this:&lt;/p&gt;

&lt;script src="http://gist.github.com/366768.js?file=environment.rb"&gt;&lt;/script&gt;

&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/reWQymHfA3c" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/04/15/memcached-and-passenger-connection-sharing/</feedburner:origLink></entry>
  <entry>
    <title>Rails 2.3, cache_fu and memcached session_store</title>
    <link href="http://feedproxy.google.com/~r/productionhacks/~3/1k8Jdw-jDjU/" rel="alternate" />
    <id>http://www.production-hacks.com/2010/04/14/rails-23-cachefu-and-memcached-sessionstore/</id>
    <published>2010-04-14T00:00:00Z</published>
    <updated>2010-04-14T00:00:00Z</updated>
    <author>
      <name>Jose Fernandez</name>
    </author>
    <summary type="html">&lt;p&gt;Many Rails developers mistakenly assume that by installing defunkt&amp;rsquo;s &lt;a href="http://github.com/defunkt/cache_fu" title="cache_fu repository at Github"&gt;cache_fu&lt;/a&gt;, Rails will be configured to use the settings found in the memcached.yml config YAML installed by the plugin. This was somehow true in earlier versions of Rails 2.*, but a couple of extra steps are required for 2.3&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Many Rails developers mistakenly assume that by installing defunkt&amp;rsquo;s &lt;a href="http://github.com/defunkt/cache_fu" title="cache_fu repository at Github"&gt;cache_fu&lt;/a&gt;, Rails will be configured to use the settings found in the memcached.yml config YAML installed by the plugin. This was somehow true in earlier versions of Rails 2.*, but a couple of extra steps are required for 2.3.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/timocratic"&gt;Tim Connor&amp;rsquo;s&lt;/a&gt; branch has a &lt;a href="http://github.com/timocratic/cache_fu/commit/bbfee8ecbb4f5676f047f5b34c58a12ded13e8d2"&gt;commit&lt;/a&gt; that correctly sets the session_store config in Rails 2.3.  I applied Tim&amp;rsquo;s patch to the most recent version of cache_fu:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/jfernandez/cache_fu"&gt;http://github.com/jfernandez/cache_fu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;re also using Rails abstract cache_store (Rails.cache) and you want it to use the same settings as cache_fu, you will have to use the &lt;a href="http://github.com/colinsurprenant/memcached-config/"&gt;MemcachedConfig&lt;/a&gt; class. Just drop the class file in your RAILS_ROOT/lib folder and add the following code to your environment.rb file (or production.rb)&lt;/p&gt;

&lt;script src="http://gist.github.com/366557.js?file=environment.rb"&gt;&lt;/script&gt;


&lt;p&gt;Now you have Rails 2.3 running with all Memcached stores configured under the same settings and namespace.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/productionhacks/~4/1k8Jdw-jDjU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.production-hacks.com/2010/04/14/rails-23-cachefu-and-memcached-sessionstore/</feedburner:origLink></entry>
</feed>

