<?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 Developer Blog &#187; Ruby</title>
	<atom:link href="http://blog.engineyard.com/category/ruby/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.engineyard.com</link>
	<description></description>
	<lastBuildDate>Wed, 23 Jan 2013 00:38:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=276</generator>
		<item>
		<title>Rails 4, Part 1: What&#8217;s Changed in Rails 4?</title>
		<link>https://blog.engineyard.com/2013/rails-4-changes</link>
		<comments>https://blog.engineyard.com/2013/rails-4-changes#comments</comments>
		<pubDate>Tue, 22 Jan 2013 23:59:57 +0000</pubDate>
		<dc:creator>J. Austin Hughey</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">https://blog.engineyard.com/?p=13719</guid>
		<description><![CDATA[<p>Note: This is the first in a two-part series that looks at what's changing in Rails 4, and new features in Rails 4. Look out for the second part will be published next week.</p>
<p>The fourth major release of the Ruby on Rails framework is coming up rather soon. While no official release date has been announced, many anticipate a release candidate early this year. This version of the framework has been over a year in the making and represents a major change in the way its internals are architected. The framework has evolved in a more modular format, pushing many of its features into separate gems in an effort to keep the primary codebase lean and mean and remove official support for deprecated features while providing ability to use them if indeed truly needed.</p>
<p>As of the time of this writing, Engine Yard doesn’t yet have support for Rails 4 in our Cloud product. That isn’t to say that you can’t try it - you most certainly can. Be aware that some features, especially live streaming, will probably not work on Cloud right now. Any issues you run into when trying to deploy and run a Rails 4 application should be filed as <a href="https://support.cloud.engineyard.com/forums/30086-feature-requests">feature requests</a> instead of bugs since we haven’t finished building Rails 4 support into the product yet. We will of course endeavor to have full support for Rails 4 available on our platform as soon as we can.<b><br />
</b></p>
<h1>Notable Changes in Rails 4</h1>
<p>Many things have been changed and/or refactored in Rails 4, and several new features have been added. While this article is not exhaustive, we’ll attempt to explain some of the more interesting or impactful ones here.<b><br />
</b></p>
<h3>Ruby 1.9.3 Minimum</h3>
<p>One of the most notable changes in Rails 4 that all developers should be aware of is that it requires Ruby 1.9.3 at a minimum. Support for 1.8.7 has been dropped completely, and since we have 1.9.3 these days, there’s really no reason to worry about support for 1.9.2 either. In fact, <a href="https://github.com/rails/rails/commit/4fa615a8661eb13d4bd8a7de4d839e9883ef26ec">this commit</a> by Jose Valim specifically tells the user that Rails 4 requires Ruby 1.9.3+ and aborts immediately if RUBY_VERSION is &lt; 1.9.3.</p>
<p>What does this mean for you? First of all, if you’re running in 1.8.7 or Ruby Enterprise Edition (which is basically 1.8.7 with some performance tuning capabilities), you should start upgrading now regardless. Upgrading your application from 1.8.7 to 1.9.3 may be fairly painless, or could be rather challenging - it somewhat depends on the application, its dependencies and what (if anything) you were using that may have been deprecated between those releases. Make sure you have good test coverage, switch your interpreter in development mode to 1.9.3 (using <a href="https://rvm.io/">RVM</a> makes that wicked simple), and run those tests. Note any unusual output you see and create stories in your favorite tracker system for each item that’s incompatible with 1.9.3. For more tips on moving to from 1.8 to 1.9, see <a href="https://blog.engineyard.com/2012/prepare-your-app-for-rails-4-and-ruby-1-9/">this article</a> by Engine Yard’s own Anthony Accomazzo.</p>
<p>Regardless, I strongly encourage everyone to run on the latest stable version of the interpreter with the latest patchlevel available for several reasons, performance and security being chief among them.<b><br />
</b></p>
<h3>No more vendor/plugins</h3>
<p>The vendor/plugins directory has been removed in Rails 4. Instead, you should use Bundler with a path or Git dependencies.<b><br />
</b></p>
<h3>Many deprecated items moved into separate gems</h3>
<p>Rails 4 has deprecated many things and moved them into separate gems.<b><br />
</b></p>
<h3 dir="ltr">Hash-based and dynamic finder methods</h3>
<p>You may recall that in previous versions of Rails, deprecation warnings for the “old” ActiveRecord query syntax were thrown constantly. For example:<br />
<b><br />
</b></p>
<pre escaped="true">User.find(:first, :conditions =&gt; { … })</pre>
<p><b><br />
</b>Support for this syntax is no longer available in Rails 4. To get this functionality back into your application, you’ll need to install the activerecord-deprecated_finders gem: <a href="https://github.com/rails/activerecord-deprecated_finders">https://github.com/rails/activerecord-deprecated_finders</a><br />
<b><br />
</b></p>
<h3 dir="ltr">ActiveRecord::SessionStore</h3>
<p>Storing sessions in the database is an interesting feature that has some useful applications, particularly with respect to sensitive information, but for most cases it’s not as performant as just using a plain ‘ol cookie. So ActiveRecord::SessionStore no longer exists in Rails 4. You’ll need to use the activerecord-session_store gem to bring this functionality back: <a href="https://github.com/rails/activerecord-session_store">https://github.com/rails/activerecord-session_store</a>.</p>
<p>To further elaborate, storing sensitive information in a cookie is generally a bad idea for several reasons, lack of encryption (or weak encryption) being only one of them. A better way to go about storing sensitive information is to keep said information in your database (protected by network-layer access and your application), and simply reference object IDs in your session object. So instead of setting a full object in a session, for example, or even meta-data about an object, you may save the object to the database, and simply reference its ID inside the user’s session (and put meta data about it in memcached or PostgreSQL hstore, for example).</p>
<h3 dir="ltr">ActiveResource</h3>
<p>ActiveResource is an ORM for REST-based web services. It’s been removed from Rails 4 and won’t be shipping with it. <a href="https://twitter.com/guilleiguaran">Guillermo Iguaran</a> says on the Yeti Media blog that <a href="http://yetimedia.tumblr.com/post/35233051627/activeresource-is-dead-long-live-activeresource">the motivation for this change was that it wasn’t being shown the maintenance love that it deserved by the Core team</a>, and that after being extracted, it’s now being given some more attention from its own contributors - a small team led by <a href="https://github.com/jeremy">Jeremy Kemper</a>. There have also been some new features added since the extraction, so all in all, this sounds like a positive change for fans of ActiveResource, and it’s quite useful for people who’d like this functionality without necessarily needing to use the entirety of Rails to get it. To get this functionality in your app, include the ‘activeresource’ gem: <a href="https://github.com/rails/activeresource">https://github.com/rails/activeresource</a>.<br />
<b><br />
</b></p>
<h3 dir="ltr">Rails Observers, Page and Action Caching</h3>
<p>Page and Action caching capabilities are being deprecated in Rails 4 in favor of “Russian Doll” caching strategies. DHH has a gem available on GitHub that explains how that caching will work; see <a href="https://github.com/rails/cache_digests">https://github.com/rails/cache_digests</a> for more information on that.</p>
<p>Regardless, with page and action caching now gone, the need for ActiveRecord Observers is now almost non-existent. In many cases, these observers are used to expire caches, which, thanks to Rails 4’s new caching scheme, isn’t as necessary anymore. Other than cache expiration, observers tend to be abused as a dumping ground for persistence operations in many cases, where a callback is a better option. So Rails 4 will ship without observers, page or action caching.</p>
<p>To get those back in your application, look at:<span id="more-13719"></span><b><br />
</b></p>
<ul>
<li dir="ltr"><a href="https://github.com/rails/actionpack-action_caching">https://github.com/rails/actionpack-action_caching</a></li>
<li dir="ltr"><a href="https://github.com/rails/actionpack-page_caching">https://github.com/rails/actionpack-page_caching</a></li>
<li dir="ltr"><a href="https://github.com/rails/rails-observers">https://github.com/rails/rails-observers</a></li>
</ul>
<p><b> </b></p>
<h3>Dalli instead of memcache-client</h3>
<p>Dalli is now being used for memcached instead of memcache-client. This is likely a welcome change in the eyes of many developers, since Dalli is quite a bit faster than memcache-client, and is thread safe - a topic of increasing concern in the community. To use it, you’ll need to add the “dalli” gem to your Gemfile if it isn’t in there already and set your cache store to mem_cache_store.<b><br />
</b></p>
<h3>New Default Test Locations</h3>
<p>Newcomers to Rails and TDD are often confused by the default setup and naming of test locations. “Models” corresponded to “units”, “controllers” to “functional” tests, and so on. In Rails 4, that’s going to change to be much clearer. The default test locations will now be a little closer to rspec’s naming conventions for Rails tests:</p>
<p>&nbsp;</p>
<pre escaped="true">app/models -&gt; test/models (was test/units)
app/helpers -&gt; test/helpers (was test/units/helpers)
app/controllers -&gt; test/controllers (was test/functional)
app/mailers -&gt; test/mailers (was test/functional)</pre>
<p><b><br />
</b>If you’re ever in the mood to read an interesting discussion on naming of tests and their purposes, you really should check out the discussion around the <a href="https://github.com/rails/rails/pull/7878">pull request that implements this change</a>. Originally, the commit was designed to rename “integration” tests (test/integration) to “acceptance” tests. While the rest of the pull request was well received, this particular change sparked a lot of conversation about what an acceptance test is and isn’t. Eventually the committer, <a href="https://github.com/blowmage">blowmage</a>, decided to leave integration as it was so as not to hold up acceptance of the commit, a move well received by several Rails core team members.</p>
<p>&nbsp;</p>
<h3>The PATCH Verb</h3>
<p>Rails has used the convention of the “PUT” HTTP method for modifying an existing resource for quite a while now. However, the HTTP specification semantically regards a PUT as a complete representation of a resource. In other words, a PUT, semantically-speaking, should contain a full representation of an entire object to be updated. Ergo, technically, we’ve been doing it somewhat “wrong” for a while now by only sending the bits of the object that need to be changed when performing a RESTful update via PUT.</p>
<p>That’s why Rails 4 will change this functionality to use the PATCH verb instead. As it suggests, PATCH is meant to send just new bits of data about an object on the server, not a full representation of it. This is more in-line with HTTP semantics as described in <a href="http://tools.ietf.org/html/rfc5789">RFC 5789</a>.</p>
<p>As with all RESTful forms in Rails, a hidden “_method” field will be generated specifying that the method to be used is “PATCH” instead of “PUT”. And as expected, routing will map the PATCH method to the “update” action in a controller.</p>
<p>In a move to preserve backwards compatibility, the former PUT method will also continue to route to “update” in Rails 4.0, so existing APIs, for example, should continue to work as normal after an upgrade.</p>
<p>The <a href="http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/">Rails blog goes into more detail on the PATCH method</a>. This is a great change overall, and the fact that it’s being done in a backwards-compatible way will certainly smooth the upgrade path for developers.<br />
<b><br />
</b></p>
<h3>Threadsafe by default</h3>
<p>Ruby developers have expressed a desire for true, GIL-free multithreading for a while now, and the Rails contributors understand that MRI isn’t the only way to run applications in production. Multi-threaded servers and applications allow for significant performance improvements by sharing segments of memory and allowing concurrent execution of code.<br />
However, the standard Ruby interpreter, generally known as “MRI”, isn’t truly multi-threaded. It can execute code concurrently if one thread is waiting on I/O, for example, and can allow underlying C libraries to execute code concurrently, but actual Ruby code is still executed synchronously due the presence of the global interpreter lock (GIL).</p>
<p>Rails has had the option for running code in a threadsafe manner for a while now, but it hasn’t been enabled by default. Starting with Rails 4, it will be. This isn’t as major a change as some may expect, given that you can enable this in most Rails apps right now by simply modifying the configuration option and restarting your threadsafe server, though it’s worth noting, if for no other reason, than it draws attention to the fact that the Rails community is increasingly adapting to the need to run concurrent web application code.</p>
<p>Aaron Patterson goes into more detail on config.threadsafe! here:<br />
<a href="http://tenderlovemaking.com/2012/06/18/removing-config-threadsafe.html">http://tenderlovemaking.com/2012/06/18/removing-config-threadsafe.html</a></p>
<p>That's it for part one. Check back <strong>next week</strong> for part 2, which will cover new features in Rails 4!
<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>https://blog.engineyard.com/2013/rails-4-changes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Next Weekend: Rails Girls in SF!</title>
		<link>https://blog.engineyard.com/2013/next-weekend-rails-girls-in-sf</link>
		<comments>https://blog.engineyard.com/2013/next-weekend-rails-girls-in-sf#comments</comments>
		<pubDate>Thu, 17 Jan 2013 21:18:17 +0000</pubDate>
		<dc:creator>Elaine Greenberg</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">https://blog.engineyard.com/?p=13710</guid>
		<description><![CDATA[<p><a href="http://railsgirls.com/">Rails Girls</a> is an incredible opportunity for women to not only build web applications, but ideas as well. Originally founded in Finland, Rails Girls covers sketching, prototyping and basic programming in Rails. To put it simply, the program is a web development workshop for women. And yet it goes far beyond its initial premise: it connects women and inspires a passion for technology with a built-in community. Since its creation, the organization has grown to over 15 countries, from Germany to Uganda.</p>
<p>We’re very excited to host the second ever Rails Girls event in San Francisco right here at Engine Yard’s headquarters. The two-day event will kick off on January 25th, and will feature coaches from Engine Yard, Github, Heroku and Snapguide. We’ll also be covering snacks, beverages and lots of other goodies. Want to meet <a href="https://twitter.com/jessicaspacekat">the creator of the now-famous Riker Ipsum</a>, or hang out with <a href="https://twitter.com/hone02">the Bundler guy</a>? They’ll both be there, among many other incredibly inspiring tech-lovers.</p>
<p>To learn more and to register, go <a href="http://railsgirls.com/sanfrancisco">here</a>.</p>
<p><a href="https://blog.engineyard.com/wp-content/uploads/Screen-Shot-2013-01-17-at-1.17.13-PM.png"><img class="alignnone size-medium wp-image-13712" title="Screen Shot 2013-01-17 at 1.17.13 PM" src="https://blog.engineyard.com/wp-content/uploads/Screen-Shot-2013-01-17-at-1.17.13-PM-300x246.png" alt="" width="300" height="246" /></a>
<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>https://blog.engineyard.com/2013/next-weekend-rails-girls-in-sf/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Innovations in JRuby 1.7.0</title>
		<link>https://blog.engineyard.com/2013/jruby-1-7-0-invokedynamic</link>
		<comments>https://blog.engineyard.com/2013/jruby-1-7-0-invokedynamic#comments</comments>
		<pubDate>Mon, 14 Jan 2013 18:48:51 +0000</pubDate>
		<dc:creator>Hiro Asari</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">https://blog.engineyard.com/?p=13692</guid>
		<description><![CDATA[<p>I am extremely humbled and honored to receive the inaugural Engine Yard Innovator Award.</p>
<p>Four years ago, I was lured by Ruby on Rails to pick up a new programming language (I wrote code mostly in Perl back then) and I have not looked back. Rails was (and still is) fun to write applications with, but deployment was not very pleasant (unsurprisingly, the PaaS market has blossomed since then!). This drove me to JRuby, for which warbler eased the pain enormously.</p>
<p>I was lucky to have found JRuby, whose core members are welcoming, and for which I have been able to make meaningful contributions. The JRuby team released 1.7.0 in October. This release includes support for the new 'invokedynamic' feature support, better 1.9 compatibility, and continues our tradition of performance improvements. As we speak, we are preparing for the 1.7.1 release with bug fixes as well. JRuby continues to expand its reach. The "JRuby Guy" Charles Oliver Nutter and I will be giving the first JRuby workshop in the Southern hemisphere at the inaugural RubyConf AU in February. If you are in the neighborhood, do attend and say hi.</p>
<p>Thank you, Engine Yard, for this award, and for continued support and recognition for the importance of JRuby.</p>
<p><a href="https://blog.engineyard.com/wp-content/uploads/mugshot-008.png"><img class="alignnone size-medium wp-image-13701" title="mugshot 008" src="https://blog.engineyard.com/wp-content/uploads/mugshot-008-225x300.png" alt="" width="225" height="300" /></a>
<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>https://blog.engineyard.com/2013/jruby-1-7-0-invokedynamic/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Update from Travis CI</title>
		<link>https://blog.engineyard.com/2012/travis-ci</link>
		<comments>https://blog.engineyard.com/2012/travis-ci#comments</comments>
		<pubDate>Thu, 20 Dec 2012 19:43:06 +0000</pubDate>
		<dc:creator>Piotr Sarnacki</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">https://www.engineyard.com/blog/?p=13559</guid>
		<description><![CDATA[<p>Engine Yard is well known for sponsoring Open Source projects and pushing Ruby forward. It has sponsored the development of crucial building blocks such as Rubinius, JRuby, Rails, RVM, but also smaller and less well known projects, as part of their Open Source Software Grant Program.</p>
<p>Now, since a few weeks ago Travis CI is the next happy participant of this program.</p>
<p>Travis CI is a hosted continuous integration service, which is completely free for Open Source projects and which itself is open source. We run tests for over 20 thousands projects (over 2.5 million of tests run in total to date) and thus help increase the quality of open source software in general.</p>
<p>I happen to be the very lucky guy who is sponsored by Engine Yard to work on Travis CI.</p>
<p>When I was first asked if I could imagine to work on Travis CI at a conference I couldn't believe it and the next day I was actually wondering if this was not a dream. I love working on open source projects, so this would be the best job I could get!</p>
<p>I participated in the Ruby Summer of Code 2010 (also co-sponsored by Engine Yard) in the past, working on improvements to Rails Engines in Rails 3. I also try to contribute to Open Source as much as I can in my spare time - not always easy when you have a stressful full time job, so being able to work on Open Source, with a fantastic team, on a really relevant project is even more awesome for me.</p>
<p>I started working on Travis CI before Engine Yard offered to sponsor me, so I already knew what it feels like and it feels just great.</p>
<p>Travis CI is quite challenging technically, because with so many projects on board we need to scale well and in order to do that Travis CI is going towards a distributed architecture. Travis CI also uses quite a few bits of cutting edge technology, which pushes web development forward - like Ember.js to power its main web client and up to date JRuby versions for running background services.</p>
<p>But working on Travis CI also means participating in something relevant that changes our everyday lifes for the better. Travis CI makes failure visible across the community. Thereby it uncovers a lot of bugs in crucial components of our development environment and over time improves stability in general. I think it's fair to say that Travis CI has changed the way we build software. And being able to contribute to this just makes me happy.</p>
<h3>What have I been working on so far?</h3>
<p>I have implemented a few features, like support for encrypted env vars which allows to include sensitive data to your test suites (like credentials for accessing external services) and fixed a range of issues and bugs. But the biggest part of my work so far was helping get the new web client and API done and released.</p>
<p>Our client is written in Javascript using Ember.js framework. <span id="more-13559"></span>If you don't know Ember.js, it announces itself as a framework for creating ambitious client-side web applications. When you look at the main Travis CI web client (link), you may wonder what's so ambitious about it - it displays a few repositories on the left, the current build details in the middle and a bit more information, like status of workers and queues on the right. The ambitious part is that it is "live": lots of data is being updated at all times through websockets. If you keep the site open you will see new repositories and builds coming in, build jobs being queued and worker statuses updated. And, maybe most importantly, you can watch the output of your test suite being streamed to the client live.</p>
<h3>How does it work?</h3>
<p>First thing worth noting is that our client and API are deployed under different domain names, respectively <a href="https://travis-ci.org/">travis-ci.org</a> and <a href="https://api.travis-ci.org/">api.travis-ci.org</a>. The major reason for such approach is isolation. Client and API are completely different apps, one written in javascript and the other in Ruby. It makes much more sense to develop, test and deploy them separately.</p>
<p>In order to allow cross domain ajax requests, we use Cross-origin resource sharing, usually referenced with CORS. CORS is automatically used in browsers which support it, when you make a request to the other domain. The part which needs additional work is the server. When browser sends cross domain ajax request it needs to actually do 2 requests:</p>
<ol>
<li><code>OPTION</code> request, which checks for existence of CORS headers</li>
<li>If response from the previous request returns proper CORS headers, the browser will send an actual request.</li>
</ol>
<p>You can read more about CORS in the <a href="http://www.w3.org/TR/cors/">specification</a>.</p>
<p>The obvious drawback of such flow is the fact that now we need to send 2 times more requests. Although it may seem like a problem, in practice it does not matter that much, because OPTION response is usually very fast. If you can use SPDY, the problem can be decreased even further.</p>
<p>What really matters to me as a developer is the ease of work with such setup. Most of the time I don't need to have API running locally. I can just point the client to the production API and check new features or bug fixes against it. This is extremely valuable, because usually you can't have production data on a local machine (for good reasons). That way I can catch errors more easily and check my code more thoroughly.</p>
<h3>How does Ember help us build Travis?</h3>
<p>As I mentioned earlier, although Travis may look as a simple app, we try to do a few things that make it more ambitious. Travis is a one page application, which means that you don't need to reload a page while you browse and also that you should not need to reload to have a fresh data. A few of the challenges you face when you build such applications are:</p>
<ul>
<li>updating views whenever data changes</li>
<li>keeping the data fresh</li>
<li>managing nested views</li>
<li>cleaning up unneeded stuff (so the app can be open for a longer amount of time)</li>
</ul>
<p>Ember helps us with all of those problems. I will try to briefly explain how exactly does it work.</p>
<p>The first point is pretty much no brainer in Ember. Its view layer deals with updating your DOM elements whenever it's needed.</p>
<p>Considering that you have a simple template that looks like that:</p>
<pre lang="handlebars" escaped="true">Hello {{name}}!</pre>
<p>and an object which is the context of this template is:</p>
<div>
<pre escaped="true">person = Em.Object.create({ name: 'Piotr' });</pre>
</div>
<p>the output you get is <code>Hello Piotr!</code><br />
This is kind of expected and there is nothing interesting about it. The fun starts when you update name field on the object, in Ember it can be done with a `set` function: </p>
<pre escaped="true">person.set('name', 'John');</pre>
<p>Now the output will be automatically updated to <code>Hello John!</code></p>
<p>The second thing from the list is also quite easy to achieve, thanks to Ember and <a href="http://pusher.com/">Pusher</a>. Pusher is a service that allows us to handle live updates with websockets easily. Whenever something is updated on the server, we send an event to pusher, which is then delivered to the subscribed clients. When we update objects in Javascript, the templates are automatically updated.</p>
<p>Handling this case is also much easier thanks to Ember Data. Ember Data is the library written on top of Ember.js, which helps with data management and supports defining models and relationships between them. Ember Data isolates the models defined in the client from data source (such as an API), which means that after you define how your data looks in an application, you can easily change a way you get it from the server.</p>
<p>A quick example of the way it works may be our job queue and repository list. When a new job is created, we send the <code>job:created</code> event, which is handled on the client by creating a new <code>Travis.Job</code> record. Job queue displays all the jobs, which have not been started yet. When <code>Travis.Job</code> record is created, all of the collections that observe changes will be notified and refreshed - in this case, filter function attached to an observer will check if the new record has <code>created</code> state and update UI accordingly. The similar thing happens on the repository list. We display 30 repositories with most recent builds there. When the application receives the <code>build:started</code>event, it will update the associated repository and as a result, Ember will take care of updating and ordering the repository list properly.</p>
<p>The last, but not the least, of the hard problems connected with building one page applications is managing views and events. This is really important if your application is not "flat", ie. it has nested views and if you want it to run for a long period of time without reloading it.</p>
<p>The thing that makes is hard is keeping track of what should we clean. In Travis, for example, we sometimes display jobs list in the build view. Jobs list is needed if a build contains more than one job, for example you may want to run your tests on different versions of Ruby. Without Ember, if we wanted to destroy a build view to display some other build, we would have to destroy the current build view and displabefore displaying the new view, we would have to destroy the previous one and make sure that we removed all of the attached event handlers. It could look something like</p>
<div>
<pre escaped="true">destroy: function() {
  this.jobViews.forEach(function(view) {
    view.destroy()
  });
}</pre>
</div>
<p>If we ever forget about any of the nested views, we now have a memory leak. But that's not all! We often need to use event listeners. We need to remember about cleaning them, too. So, our code would have to be even more complicated:</p>
<div>
<pre escaped="true">destroy: function() {
  this.element.removeEventListener('mousemove', this.onMouseMove);
  this.someLinkElement.removeEventListener('click', this.onSomeElementClick);

  this.jobViews.forEach(function(view) {
    view.destroy()
  });
}</pre>
</div>
<p>You may imagine that with a complicated application it may get messy pretty quickly and what's even more important, developers should not need to handle such boilerplate code.</p>
<p>Ember.js on the other hand keeps track of nested views and clears them up automatically. You also don't have to deal with event handlers - there is only one handler for each event, which is delegated to the proper view.</p>
<p>Of course there are still edgecases and things that we have to handle manually, but Ember constantly gets better at letting you to focus on your application, and not the boilerplace code.</p>
<h3>What else will I be working on?</h3>
<p>We released a new client about a month ago, but I'm continuing development in this area, looking for a ways to make it smoother and faster, adding more features and port the old mobile client.</p>
<p>My next bigger task is to allow people to easily upload files produced during a build to some sort of storage. Those files are often called artifacts and they can be really useful in various different scenarios. Some projects with acceptance test suites can do screenshots, which can be later investigated if a build fails. Other projects, like Ember.js, may build latest library version or docs and upload them for people to use. And these are just a few use cases, I'm sure that people will come up with incredible ways to use this feature.</p>
<p>Currently nothing stops developers from building their own scripts to save build artifacts, but this is just reinventing the same thing over and over again. We would like to address it and make artifacts management as simple as adding a few more lines in a configuration file and provide access to many different storage providers or services like Github, which allow to upload files for projects hosted there.</p>
<p>I will also do community support, take care of our issues on GitHub and act as a contact person.
<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>https://blog.engineyard.com/2012/travis-ci/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quickly view the threads of your blocked Ruby application with JStack</title>
		<link>https://blog.engineyard.com/2012/thread-viewing-jstack</link>
		<comments>https://blog.engineyard.com/2012/thread-viewing-jstack#comments</comments>
		<pubDate>Fri, 09 Nov 2012 18:53:36 +0000</pubDate>
		<dc:creator>Dr Nic Williams</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">https://www.engineyard.com/blog/?p=13359</guid>
		<description><![CDATA[<p>When something is amiss with a production application, it can be very productive to quickly look at the list of threads in an application and what state they are in. For your Ruby application running on JRuby, we can use <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/share/jstack.html">JStack</a>.</p>
<p>This article shows a quick example of a stuck Ruby application running on JRuby and how to find out what is stuck and how to look at the elongated (read: ugly) stack trace and figure out how it maps to our Ruby source code.</p>
<h2 id="java_and_jstack">Java and JStack</h2>
<p>First let’s look at using JStack for a basic Java app, then look at the same app written in Ruby and running on JRuby.</p>
<p>Example taken from http://www.herongyang.com/Java-Tools/jstack-JVM-Thread-Dump-Stack-Strace.html. Source available at https://github.com/drnic/long_sleep_demo/blob/master/LongSleep.java</p>
<pre lang="java" escaped="true">/**
 * LongSleep.java
 * Copyright (c) 2008 by Dr. Herong Yang, http://www.herongyang.com/
 */
class LongSleep {
   public static void main(String[] a) {
      Runtime rt = Runtime.getRuntime();
      System.out.println(" Free memory: " + rt.freeMemory());
      System.out.println("Total memory: " + rt.totalMemory());
      try {Thread.sleep(1000*60*60);} 
      catch (InterruptedException e) {}
   }
}</pre>
<p>Then run:</p>
<pre escaped="true">$ javac LongSleep.java
$ java LongSleep
 Free memory: 83588920
Total memory: 85000192
* pauses unexplainably!! *</pre>
<p>Find all running Java processes in another terminal:</p>
<pre escaped="true">$ jps
47521 Jps
30447 LongSleep</pre>
<p>Now we can view all the threads of our <code>LongSleep</code> application. We see that one of the threads is in a <code>TIMED_WAITING</code> state and it came from our application.</p>
<pre escaped="true">$ jstack -l 30447
...
"main" prio=5 tid=7fdec4000800 nid=0x110535000 waiting on condition [110534000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
  at java.lang.Thread.sleep(Native Method)
  at LongSleep.main(LongSleep.java:10)

   Locked ownable synchronizers:
  - None</pre>
<p>Ahh, its sleeping. Great, we could now go and fix that in <code>LongSleep.main(LongSleep.java:10)</code>.</p>
<p>Awesome.</p>
<h2 id="jruby_and_jstack">JRuby and JStack<span id="more-13359"></span></h2>
<p>Let’s rewrite LongSleep as a Ruby app for JRuby. Source available at https://github.com/drnic/long_sleep_demo/blob/master/long_sleep.rb</p>
<pre lang="ruby" escaped="true"># long_sleep.rb

require 'java'
class RuntimeView
  def display
    rt = java.lang.Runtime.getRuntime
    puts " Free memory: #{rt.freeMemory}"
    puts "Total memory: #{rt.totalMemory}"
    sleep 1000 * 60 * 60
  end
end

RuntimeView.new.display</pre>
<p>Run it:</p>
<pre escaped="true">$ jruby long_sleep.rb
 Free memory: 73802224
Total memory: 85000192
* pauses unexplainably!! *</pre>
<p>Find the process and look for our stuck thread:</p>
<pre escaped="true">$ jps
47521 Jps
30447 LongSleep

$ jstack -l 30447
...
"main" prio=5 tid=7fcfe3000800 nid=0x101bb4000 in Object.wait() [101bb2000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
  at java.lang.Object.wait(Native Method)
  - waiting on &lt;7df9e8d60&gt; (a org.jruby.RubyThread)
  at org.jruby.RubyThread.sleep(RubyThread.java:864)
  - locked &lt;7df9e8d60&gt; (a org.jruby.RubyThread)
  - locked &lt;7df9e8d60&gt; (a org.jruby.RubyThread)
  at org.jruby.RubyKernel.sleep(RubyKernel.java:792)
  at org.jruby.RubyKernel$INVOKER$s$0$1$sleep.call(RubyKernel$INVOKER$s$0$1$sleep.gen)
  at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:642)
  at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:204)
  at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
  at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
  at long_sleep.method__1$RUBY$display(long_sleep.rb:9)
  at long_sleep$method__1$RUBY$display.call(long_sleep$method__1$RUBY$display)
  at long_sleep$method__1$RUBY$display.call(long_sleep$method__1$RUBY$display)
  at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
  at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
  at long_sleep.__file__(long_sleep.rb:13)
  at long_sleep.load(long_sleep.rb)
  at org.jruby.Ruby.runScript(Ruby.java:770)
  at org.jruby.Ruby.runScript(Ruby.java:763)
  at org.jruby.Ruby.runNormally(Ruby.java:640)
  at org.jruby.Ruby.runFromMain(Ruby.java:489)
  at org.jruby.Main.doRunFromMain(Main.java:375)
  at org.jruby.Main.internalRun(Main.java:264)
  at org.jruby.Main.run(Main.java:230)
  at org.jruby.Main.run(Main.java:214)
  at org.jruby.Main.main(Main.java:194)

   Locked ownable synchronizers:
  - None</pre>
<p>Looking through the list of threads (not shown above) we again find this thread in a <code>TIMED_WAITING</code> state. The first thing I notice is that the JRuby stack trace is a lot longer than the pure Java one.</p>
<p>After finding the <code>TIMED_WAITING</code> state thread, it is clear that this thread is <code>locked</code> by <code>RubyKernel.sleep</code>.</p>
<p>Looking down the stack trace, it is not as clear, but you can see that my application is involved at <code>long_sleep.rb:9</code>:</p>
<pre escaped="true">long_sleep.method__1$RUBY$display(long_sleep.rb:9)</pre>
<p>Slightly hard to read, but the blocking occurs within a <code>#display</code> method (on an unspecified class?) on line 9 in <code>long_sleep.rb</code>.</p>
<p>Again, wonderful. I can now continue debugging!</p>
<p>I definitely look forward to using JStack in future as part of debugging applications in development and in production.
<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>https://blog.engineyard.com/2012/thread-viewing-jstack/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An eCommerce Refactor: Cleaning up a Common Pattern in a Rails eCommerce App</title>
		<link>https://blog.engineyard.com/2012/ecommerce-rails</link>
		<comments>https://blog.engineyard.com/2012/ecommerce-rails#comments</comments>
		<pubDate>Thu, 18 Oct 2012 21:11:31 +0000</pubDate>
		<dc:creator>Paul Campbell</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Refactoring]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=13282</guid>
		<description><![CDATA[<p>"We can't add any more features", I said to Cillian. We had reached that point when building a web app using Rails that if we added another line to that controller, I couldn't help but feel the whole thing would come crashing down, like placing the last block in a game of Jenga.</p>
<p>"We need to refactor."</p>
<p>The code in question was extremely common code: handling customer payments.</p>
<p>Like many, many eCommerce setups out there, we wanted to be able to accept payment by PayPal, or by credit card. Since we also wanted to support multiple stores, we wanted to accept multiple payment gateways.</p>
<p>The purchase controller logic looked a bit like this:</p>
<div>
<pre escaped="true">class PurchasesController
  def create
    @purchase = Purchase.new(params[:purchase])

    if @purchase.free?
      if @purchase.confirm
        redirect_to @purchase
      else
        render :new
      end
    else
      if @purchase.paypal?
        redirect_to_paypal
      elsif @purchase.credit_card?
        if purchase_attempt = @purchase.confirm &amp;&amp; purchase_attempt.success?
          redirect_to @purchase
        else
          render :new
        end
      end
    end
  end
end</pre>
</div>
<p>This is a simplification of the actual spaghetti code, but it serves to illustrate a few points that I want to highlight.</p>
<p>For me, it all starts with the unfortunate use of the word "Purchase". Purchase is a noun that's very much connected to a verb: the action of buying. In eCommerce terms, a purchase is actually quite a complex interaction: choosing what to buy, agreeing to do it, agreeing on a payment type, making that payment and then receiving the goods.</p>
<p>Take a look at the relevant methods in that <code>Purchase</code> model:</p>
<p><span id="more-13282"></span></p>
<div>
<pre escaped="true">class Purchase

  def confirm_free
    complete_order
  end

  def confirm_paypal
    if paypal_transaction.success?
      complete_order
    end
  end

  def confirm_credit_card
    if credit_card_transaction.success?
      complete_order
    end
  end

  def confirm
    case
    when free?
      confirm_free
    when paypal?
      confirm_paypal
    when credit_card?
      confirm_credit_card
    end
  end

  def complete_order
    create_receipt
    confirm_purchase
    send_order_email
    set_as_complete
  end
end</pre>
</div>
<p>I've tried to simplify the sample code, but you can see that there's already quite a lot going on. Ultimately, naming the model <code>Purchase</code> led to giving too much responsibility to that class. Here are the steps the logic has to take:</p>
<p>1) Decide if the purchase is free, PayPal or credit card<br />
2) Verify the transaction in each case<br />
3) Create a receipt for the payment<br />
4) Complete the order</p>
<p>The key realisation for me was in those steps 3 and 4. There was a bunch of behavior around the <code>Payment</code> and a bunch of behavior around the <code>Order</code>. In fact, the behavior relating to the order didn't seem to have anything to do with the payment and the payment behavior didn't really have anything to do with what the customer was purchasing, other than the price and some shipping logic.</p>
<p>Going back up to the controller, it feels like it's obvious now too: there's too much domain logic in there. The controller shouldn't care about things like "free?" and "paypal?" and "credit_card?". The controller is concerned about input and output: taking action as a result of domain logic: the logic itself should be elsewhere.</p>
<p>Here's what I decided to do:</p>
<p>1) Split <code>Purchase</code> into <code>Order</code> and <code>Payment</code>, separating the logic<br />
2) Implement a controller for each<br />
3) Separate classes for each payment type conforming to a common API</p>
<p>Here's how the controllers ended up:</p>
<div>
<pre escaped="true">class OrdersController
  def create
    @order = Order.new(params[:order])
    if @order.paid?
      if @order.payment.redirect?
        redirect_to @order.redirect_url
      else
        redirect_to [@order, @payment]
      end
    else
      if @order.complete
        redirect_to @order
      else
        render :new
      end
    end
  end
end

class PaymentsController
  def create
    @order = @order.find(params[:order_id])
    @payment = @order.payment
    if @payment.redirect?
      redirect_to @payment.redirect_url
    else
      if @payment.confirm(params[:payment])
        redirect_to @order
      else
        render :edit
      end
    end
  end
end</pre>
</div>
<p>Now the controllers don't care about PayPal, don't care about credit card. The <code>Order</code> model implements the <code>Order#paid?</code> method, and if an order is paid, it should have a payment attached to it, which either redirects or it doesn't.</p>
<p>Similarly, the payments controller asks the <code>Payment</code> object what to do.</p>
<p>What's neat about this is that the controller doesn't have to change, and the underlying models do all of the work. We can use Rails's STI implementation to create multiple classes that implement the simple API that the controller uses.</p>
<p>Here's how the underlying model structure ended up:</p>
<div>
<pre escaped="true">class Payment
  # common payment functionality here
end

class Payment::CreditCard
  validates_as_credit_card

  def confirm(attrs)
    if update_attributes(attrs)
      if authorized? || authorize
        order.complete
      end
    end
  end
end

class Payment::CreditCard::SampleProvider
  def redirect?
    false
  end

  def authorize
    return if authorized?
    transaction do
      if SampleProviderApi.authorize(price)
        update_column(:authorized, true)
      end
    end
  end
end

class Payment::PayPal
  include PayPalGateway

  def redirect?
    true
  end

  def redirect_url
    paypal_gateway.redirect_url
  end
end

class Order
  def complete
    send_order_email
    set_as_complete
  end
end</pre>
</div>
<p>This new structure does a few things.</p>
<p>First, it removes business logic from the controller. The controller is still making decisions based on the state of the objects it's interacting with, but the questions are at a higher level, and the results deal with dispatching behaviour, rather than making business decisions.</p>
<p>Second, the controller logic is consistent accross all implementations of the Payment model. It doesn't care whether the underlying payment is PayPal or a credit card API. It just calls a common API that the underlying models implement.</p>
<p>Third, the domain is split up into logical concerns. The Order model now no longer cares about anything to do with accepting payment. If the order is not free, it has an attached payment option that handles these concerns.</p>
<p>Finally, the Payment model handles common payment logic, with its sub-classes implementing the particulars for each underlying API.</p>
<p>Of course, these changes assume a solid set of tests which were in place before this refactoring. Further: the refactoring makes it easier to test each component in isolation in our unit tests.</p>
<p>The actual refactoring described here took about a month to do, between testing various formations and moving huge chunks of code about. I consider it a month well spent.</p>
<p>Technical debt accrues as you rush to ship a release, to get a new feature out or just in the every day beat of adding features on top of existing functionality.</p>
<p>This refactor paid off a bit of this debt, and gave us space. Space not only in the smaller classes that do less, but more specific work, but also headspace: peace of mind knowing that the app is tidier, simpler, easier to understand and, ultimately, easier to change.</p>
<p>"Ok, what should we do now?" I asked Cillian.</p>
<p>"Let's add that feature that everyone's been looking for."
<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>https://blog.engineyard.com/2012/ecommerce-rails/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Set Your RubyGems Version Per Environment</title>
		<link>https://blog.engineyard.com/2012/set-your-rubygems-version-per-environment</link>
		<comments>https://blog.engineyard.com/2012/set-your-rubygems-version-per-environment#comments</comments>
		<pubDate>Mon, 15 Oct 2012 22:46:03 +0000</pubDate>
		<dc:creator>Josh Hamilton</dc:creator>
				<category><![CDATA[Product]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=13267</guid>
		<description><![CDATA[<p>Earlier this summer, in an effort to help our customers keep up to date with newer gem libraries and security updates, we offered a newer version of RubyGems (1.8.17) in one of our stack upgrades. Some legacy applications began having incompatibility issues with this newer version of RubyGems. Certain crucial gems would break in this process and cause complications for running your applications. As a result, RubyGems was no longer upgraded automatically.</p>
<p>Starting today, you can specify the version of RubyGems you would like to have installed, per environment.</p>
<p>With this new feature, if you are using an older version of Ruby (1.8.6 or 1.8.7), you can specify which version of RubyGems should be set for a particular environment. This will allow the environment to be able to receive other upgrades, like updates to Nginx, but not receive an upgrade to RubyGems.</p>
<h3 dir="ltr">Use the RubyGems feature</h3>
<p>The next time you go to the environment UI, the RubyGems drop-down will appear.<img src="https://lh5.googleusercontent.com/cUqNx-m_l9irl5FDDBN_hrumrn7WzCuZsdpq-igILxjKgsIfq2kw3-KEzq1b7EHzI-pECEkgsXAGzhRqCw6l7GJ7YWzodufothETjEXVWoTbgczQRTg" alt="" width="554px;" height="157px;" /><strong></strong><strong><br />
</strong></p>
<h4 dir="ltr"><strong>To get to the environment UI</strong></h4>
<ul>
<li>
<p dir="ltr">For your existing environment, click Edit Environment under the More Options section.</p>
</li>
<li>
<p dir="ltr">Or, from your app's Environments page, click Create New Environment.</p>
</li>
</ul>
<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>https://blog.engineyard.com/2012/set-your-rubygems-version-per-environment/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Log in to Engine Yard Cloud and see bonus help!</title>
		<link>https://blog.engineyard.com/2012/login-to-and-see-bonus-help</link>
		<comments>https://blog.engineyard.com/2012/login-to-and-see-bonus-help#comments</comments>
		<pubDate>Thu, 04 Oct 2012 18:02:35 +0000</pubDate>
		<dc:creator>Dr Nic Williams</dc:creator>
				<category><![CDATA[Product]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=13167</guid>
		<description><![CDATA[<p>When you next upgrade your Engine Yard Cloud environment, or deploy a new application, your SSH sessions will display new information! Here's an example...</p>
<pre escaped="true">Last login: Tue Sep 25 14:47:03 PDT 2012 from 64.134.224.205 on pts/0
Welcome to Engine Yard Cloud!

Applications:
hurlit:
cd /data/hurlit/current # go to the application root folder
tail -f /data/hurlit/current/log/production.log # production logs
cat /data/nginx/servers/hurlit.conf # current nginx conf

SQL database:
cd /db # your attached DB volume

PostgreSQL:
sudo tail -f /db/postgresql/9.1/data/pg_log/*
pg_top -d hurlit

Inspect node data passed to chef cookbooks:
sudo gem install jazor
sudo jazor /etc/chef/dna.json
sudo jazor /etc/chef/dna.json 'applications.map {|app, data| [app, data.keys]}'

deploy@ip-1-2-3-4 ~ $</pre>
<p>Sometimes it's the little things that can make a big difference. I know this has helped me out already — finding my way around and quickly diagnosing an issue.</p>
<p>Let me know by leaving a comment below; how has this helped you? Perhaps there are some other small niceties that could be added to make your day more awesome?</p>
<p>Keep an eye out for this SSH login message, it may change over time to teach you new and interesting things.
<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>https://blog.engineyard.com/2012/login-to-and-see-bonus-help/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Application Server Showdown: Passenger vs. Unicorn</title>
		<link>https://blog.engineyard.com/2012/passenger-vs-unicorn</link>
		<comments>https://blog.engineyard.com/2012/passenger-vs-unicorn#comments</comments>
		<pubDate>Tue, 18 Sep 2012 21:29:44 +0000</pubDate>
		<dc:creator>Matt Mills</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=12999</guid>
		<description><![CDATA[<h2>tl;dr</h2>
<p>Use <a href="http://unicorn.bogomips.org/">Unicorn</a> unless you need to run multiple applications on the same host, such as testing environments or shared CMS instances.</p>
<p>Unicorn and <a href="https://github.com/FooBarWidget/passenger">Passenger</a> fundamentally differ in how they operate. There are a few similarities, however.  Both have a master process that can spawn workers; both fork off workers from the master process; and both run Rack-based applications in addition to supporting older rails versions. What follows is a summary of the way the two application servers work, their benefits and problems.</p>
<h2>Passenger</h2>
<p>Passenger is a module that can be integrated into either <a href="http://www.apache.org/">Apache</a> or <a href="http://nginx.org/">Nginx</a>; it's modeled on mod_php and mod_ruby. Here at Engine Yard we use Nginx, for various reasons; performance, simple configuration file formats, and because it uses less memory than Apache. When started as part of Nginx, Passenger creates a master process that spawns workers as requests come in. It does this relatively quickly, but there's a warm up time while the Rails code loads. The startup time is usually less than five seconds, but for some applications as long as thirty seconds.</p>
<p>There is a limit to the number of Passenger worker processes, set in the Nginx configs,  and they stay alive as long as requests keep coming in. Each application only has as many workers as it needs to serve requests, down to the minimum number of workers configured. The upshot is that you're only using memory for the number of workers needed to serve requests; so if one application only needs one worker, that's all the memory it uses, and the rest of the memory is free for your other applications.</p>
<p>While being able to run several applications under one setup is useful, Passenger has several faults. It’s difficult to monitor; If one of the workers has a problem and dies, it sits there stuck in memory until someone or something clears it out. Here at Engine Yard, that would be a Support Engineer or our passenger_monitor cron job. Some applications seem to have this problem more than others; it really depends on load and request volume.  Also, when Passenger is restarted, sometimes the old application processes do not respond to the master Passenger’s kill signal, and there's currently no automation in place on Cloud to kill them. This is especially a problem when a server is experiencing high load.</p>
<p>All of those issues aside, there are three problems that are really major for people: The warm up time, the inability (or at best extreme hackishness) to do seamless deploys, and the fact that since it’s compiled into the web server, you can’t configure proxies in the detailed and custom ways that you can with other application servers like Unicorn.</p>
<h2>Unicorn</h2>
<p>Unicorn, on the other hand, works somewhat differently. Unicorn runs independently of the other parts of your stack. It has a master process responsible for several things:<span id="more-12999"></span></p>
<p>1. Keeps a running copy of the code in memory.<br />
2. Monitors how long the workers take to fulfill requests.<br />
3. Kills workers that take too long to fulfill requests, and forks off new workers very quickly, on the order of milliseconds.<br />
4. Can gracefully restart with new code. That is, you can update your code, send it a USR2 signal, and it'll boot a new master and new workers, let the old workers finish their requests, and then stop them. This is what allows “zero downtime” deploys.</p>
<p>Unicorn has a set number of workers alive in memory. On Engine Yard Cloud, this number is set based on instance size. These all take requests via the accept(2) kernel method through a socket as they come in. This means that load balancing is managed by the kernel, which is very efficient. Since this is a relatively static setup, you can use Monit (or another process monitor like god) to monitor CPU and memory usage as well.</p>
<p>Memory consumption can be considered a disadvantage for Unicorn.  It takes up whatever memory is required for your code, plus the unicorn master overhead, times the number of workers. In a clustered environment, this isn't as bad as it sounds, but it does effectively limit the number of applications you can run to one, unless you’re willing to do a bunch of custom work.</p>
<p>Further reading:</p>
<p><a href="http://unicorn.bogomips.org/" target="_blank">http://unicorn.bogomips.org/</a><br />
<a href="http://www.modrails.com/documentation/Users%20guide%20Nginx.html" target="_blank">http://www.modrails.com/<wbr>documentation/Users%20guide%</wbr><wbr>20Nginx.html</wbr></a><br />
<a href="http://tomayko.com/writings/unicorn-is-unix/" target="_blank">http://tomayko.com/writings/<wbr>unicorn-is-unix/</wbr></a></p>
<div><strong style="color: #222222; line-height: normal; background-color: #ffffff; font-family: Times; font-size: medium; font-weight: normal;"><span style="font-size: 15px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br />
</span></strong></div>
<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>https://blog.engineyard.com/2012/passenger-vs-unicorn/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Engine Yard and WNYRuby or The Little Ruby Group that Could</title>
		<link>https://blog.engineyard.com/2012/engine-yard-and-wnyruby-or-the-little-ruby-group-that-could</link>
		<comments>https://blog.engineyard.com/2012/engine-yard-and-wnyruby-or-the-little-ruby-group-that-could#comments</comments>
		<pubDate>Thu, 30 Aug 2012 21:45:06 +0000</pubDate>
		<dc:creator>PJ Hagerty</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=13016</guid>
		<description><![CDATA[<p>Engine Yard is dedicated to helping the Ruby and Rails community flourish as much as possible.  This is never more apparent than when examining a case where a small Ruby group, suffering low attendance and attrition, came to Engine Yard for help...and Engine Yard came through.</p>
<p>The <a href="http://www.meetup.com/Western-New-York-Ruby/">Western New York Ruby Brigade</a> was founded 5 years ago by a few folks who were adamant about Ruby and Rails who needed a way to share ideas with like minded individuals in and around Buffalo, NY.  Made up of mostly independent contractors, the group would meet once a month to discuss topics and occasionally have presentations from one or two of the members. Unfortunately, the venue was always the same, on a college campus, sponsorship was nearly non-existent, and attendance ranged between 6 and 10 people every month.  While some names were well known in the community, attendees would often only come for two or three meetings, and then disappear.  Between lack of exposure and seeing the same information imparted repeatedly, things were looking grim, to the point where months would pass without a meeting.</p>
<p>In October, I moved to Engine Yard after working as a developer for a Rails shop focusing on admissions and evaluation software for Higher Education Health Sciences schools.  After attending many meetings, I thought it would be good to ask the experts at Engine Yard for help.  That last thing anyone wanted was for the group to fade away. Explaining the situation to the Engine Yard Community Events team, some serious flaws were seen and solutions were offered.  Engine Yard offered us sponsorship capital, along with a boatload of schwag.  This was a starting point, but it was the advice that really paid off. It was recommended we move off campus, to a place that had food, drinks, and wifi.  I took this information back to the group coordinators who in turn made me a group coordinator and let me run free with re-booting WNY Ruby.</p>
<p>Our first step was a meet-up that focused on what the group was about.  This offered an opportunity for people to find out a Ruby/Rails community existed in Western New York and meet the people who have a vested interest and plenty of knowledge.  In order to bring people in, we set up the meeting at a local tavern, with food and beverages provided by Engine Yard. The next step was an all-out social media blitz.  A twitter account was set up, the Facebook group was updated for the first time in months, we used meetup.com to let people know we were there.  We even added links to the event on Reddit.  Even with this step, Engine Yard stepped up, retweeting our links and information, helping getting everything in place for success.</p>
<p>Our first revamped meetup was in November.  All the “original 6” were there...along with 25 new faces attending their first meeting.  And things have just improved since then.  WNY Ruby has been able to bring outside speakers like Engine Yard’s Database guru Ines Sombra and testing evangelist <a href="https://twitter.com/steveklabnik">Steve Klabnik</a> of <a href="http://jumpstartlab.com/">JumpstartLab</a>.  Generating interest has never been easier and at the heart of it is the help we received from Engine Yard’s team of Community Managers. Engine Yard has provided more to this Ruby Group than just t-shirts and beer.  Without Engine Yard’s dedication to seeing regional Ruby and Rails groups succeed, WNY Ruby would have gone off the rails.  Now we see consistent attendance of 30 or more and it’s all thanks to our teamwork with Engine Yard.</p>
<p>Need help organizing your own local Ruby user group? Don't hesitate to contact us! We'd love to help out and make your user group the best it can be.
<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>https://blog.engineyard.com/2012/engine-yard-and-wnyruby-or-the-little-ruby-group-that-could/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
