Helios - open source framework for mobile

Heroku has a strong tradition with open source projects. Engineers have dedicated countless hours to the projects that developers count on every day. Open Source Software is in our DNA.

Speaking personally, I’m passionate about building tools like AFNetworking and cupertino, in order to help developers build insanely great experiences for mobile devices. It’s with great pleasure that I introduce something new I’ve been working on:

Helios is an open-source framework that provides essential backend services for iOS apps. This includes data synchronization, push notifications, in-app purchases, and passbook integration. It allows developers to get a client-server app up-and-running while seamlessly incorporating functionality as necessary.

Helios is designed for "mobile first" development. Build out great features on the device, and implement the server-side components as necessary. Pour all of your energy into crafting a great user experience, rather than getting mired down with the backend.

Built on the Rack webserver interface, Helios can be easily added into any existing Rails or Sinatra application. Or, if you're starting with a Helios application, you can build a new Rails or Sinatra application on top of it. This means that you can develop your application using the tools and frameworks you love, and maintain flexibility with your architecture as your needs evolve.

Give it a try and let me know what you think!

Adding Concurrency to Rails Apps with Unicorn

With support for Node.js, Java, Scala and other multi-threaded languages, Heroku allows you to take full advantage of concurrent request processing and get more performance out of each dyno. Ruby should be no exception.

If you are running Ruby on Rails with Thin, or another single-threaded server, you may be seeing bottlenecks in your application. These servers only process one request at a time and can cause unnecessary queuing. Instead, you can improve performance by choosing a concurrent server such as Unicorn which will make your app faster and make better use of your system resources. In this article we will explore how Unicorn works, how it gives you more processing power, and how to run it on Heroku.

Concurrency and Forking

At the core of Heroku is the Unix Philosophy, and we see this philosphy at work in Unicorn. Unicorn uses the Unix concept of forking to give you more concurrency.

Process forking is a critical component of Unix's design. When a process forks it creates a copy of itself. Unicorn forks multiple OS processes within each dyno to allow a Rails app to support multiple concurrent requests without requiring them to be thread-safe. This means that even if your app is only designed to handle one request at a time, with Unicorn you can handle concurrent connections.

Unicorn leverages the operating system to do most of the heavy lifting when creating and maintaining these forks. Unix-based systems are extremely efficient at forking, and even take advantage of Copy on Write optimizations that are similar to those in the recently released Ruby 2.0.

Unicorn on Rails

By running Unicorn in production, you can significantly increase throughput per dyno and avoid or reduce queuing when your app is under load. Unicorn can be difficult to setup and configure, so we’ve provided configuration documentation to make it easier to get started.

Let's set up a Rails app to use Unicorn.

Setting up Unicorn

First, add Unicorn to your application Gemfile:

gem 'unicorn'

Run $ bundle install, now you are ready to configure your app to use Unicorn.

Create a configuration file for Unicorn at config/unicorn.rb:

$ touch config/unicorn.rb

Now we're going to add Unicorn-specific configuration options, that we explain in detail in Heroku's Unicorn documentation:

# config/unicorn.rb
worker_processes 3
timeout 30
preload_app true

before_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

This default configuration assumes a standard Rails app with Active Record, see Heroku's Unicorn documentation for more information. You should also get acquainted with the different options in the official Unicorn documentation.

Now that we've got your app setup to use Unicorn, you’ll need to tell Heroku how to run it in production.

Unicorn in your Procfile

Change the web command in your Procfile to:

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

Now try running your server locally with $ foreman start. Once you're happy with your changes, commit to git, deploy to staging, and when you're ready deploy to production.

A World of Concurrency

With the recent release of the Rails 4 beta, which is threadsafe by default, it's becoming increasingly clear that Rubyists care about concurrency.

Unicorn gives us the ability to take multiple requests at a time, but it is by no means the only option when it comes to concurrent Rack servers. Another popular alternative is Puma which uses threads instead of forking processes. Puma does however require that your code is threadsafe.

If you've never run a concurrent server in production, we encourage you to spend some time exploring the ecosystem. After all no one knows your app's requirements better than you.

Whatever you do don't settle for one request at a time. Demand performance, demand concurrency, and try Unicorn today.

Rails Security Vulnerability

A serious security vulnerability has been found in the Ruby on Rails framework. This exploit affects nearly all applications running Rails and a patch has been made available.

Rails developers can get a full list of all your affected Heroku applications by following instructions here. Please address this security vulnerability by immediately upgrading your affected apps to any of the safe versions of Rails listed below. The following Rails versions have been patched and deemed safe from this exploit:

  • 3.2.11
  • 3.1.10
  • 3.0.19
  • 2.3.15

If you do not upgrade, an attacker can trivially gain access to your application, its data, and run arbitrary code or commands. Heroku recommends upgrading to a patched version immediately.

How to Upgrade:

Open the Gemfile in the affected application and change the Rails version to one listed above:

rails '3.2.11'

Then run:

$ bundle update rails

Then commit the results to git, and push to Heroku:

$ git commit -am "Bundle update rails"
$ git push heroku master

Repeat for any susceptible applications. If you cannot upgrade at this time, please consider enabling maintenance mode or scaling your app down to zero dynos.

$ heroku maintenance:on -a APPNAME
$ heroku scale web=0 -a APPNAME

Any applications running an insecure version are at risk.

Rails 2.3.6+ Dependency Issues

This past Sunday, Rails 2.3.6 was released, and quickly followed by 2.3.7 and 2.3.8. One of the major changes in these new versions is to require a newer version of Rack, specifically 1.1.0, that is incompatible with Rails 2.3.5 and older. Due to the fairly complex ways in which Rubygems resolves dependencies, this can prevent your app from starting – in your local environment as well as when deployed on Heroku. If you’ve been affected by this issue, you would see this error message:

    Missing the Rails gem. Please `gem install -v= x.x.x`,
    update your RAILS_GEM_VERSION setting in config/environment.rb 
    for the Rails version you dohave installed, or 
    comment out RAILS_GEM_VERSION to use the latest 
    version installed.

We have written up a new docs page page with information detailing the issue, how to reproduce on your local machine, and how to resolve it.

Rails 2.3

The Rails 2.3.2 gem is now installed and available for use on Heroku. To learn more about what’s new and improved, check the official Rails blog post.

Enjoy!

Browse the blog archives or subscribe to the full-text feed.