<?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>Engine Yard Blog &#187; Sam Merritt</title>
	<atom:link href="http://www.engineyard.com/blog/author/sammerritt/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.engineyard.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 07 Feb 2012 19:36:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Using the Rubygems Bundler for Your App</title>
		<link>http://www.engineyard.com/blog/2009/using-the-rubygems-bundler-for-your-app/</link>
		<comments>http://www.engineyard.com/blog/2009/using-the-rubygems-bundler-for-your-app/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 18:00:54 +0000</pubDate>
		<dc:creator>Sam Merritt</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Bundler]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=2701</guid>
		<description><![CDATA[<p>The new<a href="http://github.com/wycats/bundler"> Rubygems bundler</a> makes managing your application's gem dependencies easy. And for applications with many components, it makes separating components' dependencies easy too.</p>
<p>Let's start off with a simple, two-part application. Part 1 is a Sinatra app that puts JSON-serialized messages into an AMQP queue. Part 2 is a daemon that consumes those messages.</p>
<p>Here's what a Gemfile for this application might look like:</p>
<pre>gem 'json'
gem 'sinatra'
source 'http://gems.github.com'
gem 'famoseagle-carrot', :require_as =&gt; 'carrot'

gem 'eventmachine'
gem 'amqp'</pre>
<p>The Sinatra app starts off with these lines:</p>
<pre># This makes sure the bundled gems are in our $LOAD_PATH
require File.expand_path(File.join(File.dirname(__FILE__), 'vendor', 'gems', 'environment'))

# This actually requires the bundled gems
Bundler.require_env

class MyApp &lt; Sinatra::Base
  # stuff</pre>
<p>The daemon starts like this:</p>
<pre># This makes sure the bundled gems are in our $LOAD_PATH
require File.expand_path(File.join(File.dirname(__FILE__), 'vendor', 'gems', 'environment'))

# This actually requires the bundled gems
Bundler.require_env

AMQP.start do
  # stuff</pre>
<p>However, this loads too many gems. The Sinatra app synchronously publishes its messages using carrot, so it doesn't need the EventMachine gem or the AMQP gem. Likewise, the daemon doesn't serve HTTP requests, so it doesn't need Sinatra, and it's processing messages asynchronously using EventMachine, so it doesn't need Carrot.</p>
<p>This isn't the end of the world for this set of gems; it just makes all the Ruby processes use a little more memory than they otherwise might. However, if the Sinatra app uses one gem that defines <code>Array#foo</code> one way, and the daemon uses another gem that defines <code>Array#foo</code> an entirely <em>different</em> way, then each component must require only its own dependencies.</p>
<p>Fortunately, the bundler makes this really easy: just change the Gemfile to look like this:</p>
<pre>gem 'json'

only :app do
  gem 'sinatra'
  source 'http://gems.github.com'
  gem 'famoseagle-carrot', :require_as =&gt; 'carrot'
end

only :daemon do
  gem 'eventmachine'
  gem 'amqp'
end</pre>
<p>In the Sinatra app, change <code>Bundler.require_env</code> to <code>Bundler.require_env(:app)</code>. This loads JSON, Sinatra, and Carrot, but not EventMachine or AMQP.</p>
<p>Similarly, in the daemon, <code>Bundler.require_env</code> becomes <code>Bundler.require_env(:daemon)</code>.</p>
<p>But wait, it gets better!</p>
<p>Bundler.require_env can be called more than once with a different environment name each time. Consider tests (which, of course, you wrote first, right?): you want to run them. Now your Gemfile might look like this:</p>
<pre>gem 'json'

only :app do
  gem 'sinatra'
  source 'http://gems.github.com'
  gem 'famoseagle-carrot', :require_as =&gt; 'carrot'
end

only :daemon do
  gem 'eventmachine'
  gem 'amqp'
end

only :test do
  gem 'rspec'
  gem 'webrat'
end</pre>
<p>Then, in your spec, you start like this:</p>
<pre>require 'my_app'       # load the Sinatra app so we can test it
Bundler.require_env(:test)    # get rspec and webrat in here

describe "the main page" do
  # stuff</pre>
<p>Now each part of your app has its dependencies neatly contained. Each part only gets what it needs, and the different dependencies can't step on each others' toes.</p>
<p>Sweet.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/using-the-rubygems-bundler-for-your-app/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Distlockrun: Lockrun for Your Cloud</title>
		<link>http://www.engineyard.com/blog/2009/distlockrun-lockrun-for-your-cloud/</link>
		<comments>http://www.engineyard.com/blog/2009/distlockrun-lockrun-for-your-cloud/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 18:40:13 +0000</pubDate>
		<dc:creator>Sam Merritt</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Lockrun]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=2636</guid>
		<description><![CDATA[<p><a href="http://unixwiz.net/tools/lockrun.html">Lockrun is a handy little utility</a> for ensuring you don't run two of the same cron job (or other task) at the same time on one machine. It's especially handy when the cron job in question has a widely varying duration. Lockrun was written by Steve Friedl and <a href="http://blog.unixwiz.net/2006/06/new_tool_lockru.html">initially released in 2006</a>.</p>
<p>However, when you have jobs that use resources from multiple machines, lockrun isn't adequate. Consider a cron job that builds a local index of a bunch of NFS-mounted files. You don't want more than one consumer of that NFS volume to index it at a time, otherwise performance will be degraded.</p>
<p>Enter <a href="http://github.com/smerritt/distlockrun">distlockrun</a>: it works similarly to lockrun except that it talks to a central server for mutual exclusion instead of locking a file.</p>
<p>First of all, you need the lock server running. It's really lightweight, so you can run it on any machine you've already got. For example, on Engine Yard Cloud, it should be run on the database master in a screen session.</p>
<p>Start the server like so: <code>distlockrun-server</code></p>
<p>By default, it starts on port 7890, but that can be changed with the <code>--port</code> option.</p>
<p>Then, on the client, run your job as follows: <code>distlockrun --server {server's hostname} big-expensive-indexer.rb</code></p>
<p>If there's already a big-expensive-indexer.rb running, then distlockrun will just exit. Otherwise, it runs the job and then tells the lock server that it's finished.</p>
<p>That's all it takes to get cluster-wide mutual exclusion; short but sweet!
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/distlockrun-lockrun-for-your-cloud/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

