Zero Downtime Deploys with Migrations »

Created at: 13.12.2011 22:30, source: Engine Yard Blog, tagged: ruby Technology

I gave a talk at RubyConf that went over how we automate our development and deploy process here at Engine Yard. The part of the talk that got the most questions and spawned the most discussion was about the way we do deploy with zero downtime, even with migrations. Here is a bit more detail on the process.

A Caveat

At Engine Yard, we almost exclusively use DataMapper for our ORM. This means that we specify all of the properties for our models in the model class, there is no database introspection to generate accessors for the properties. I have not tried this technique with ActiveRecord but the concepts will be the same.

Example: Adding a column

This is the simplest example, but also the most common migration that we do.

First, before merging any part of the feature to master that needs a new column, create a migration on master that adds the column.

migration 1, :"add published_at to posts" do
  up do
    modify_table :posts do
      add_column :published_at, Time
    end
  end
end

Then we simply test the migration, and ship it all the way to production. Now the column is created in the database—ready for us to use when we merge the code that requires the column.

This also allows us to always run migrations last in the deploy, after we have restarted the app servers. This means that new code is running on the app servers earlier in the deploy process.

Renaming a Column

Adding a column is pretty straightforward but there are some migrations that are much trickier to do with zero downtime.

Lets say you have a Post model, and you want to rename the body field to content.

We have a solution for this as well.

Step 1: Add the new column

Same as above, write and deploy the migration to add the new column to the database.

migration 1, :"add content to posts" do
  up do
    modify_table :posts do
      add_column :content, Text
    end
  end
end

Step 2: Make the code aware of both columns

We usually do this by writing the code as if we were solely using the new column, then having a few accessors and hooks on the model to sync the data over.

class Post
  def content
    update_content
    attribute_get(:content)
  end 

  def content=(new_content)
    self.body = new_content
    attribute_set(:content, new_content)
  end 

  before :save, :update_content
  def update_content
    self.content = body
  end
end

Step 3: Migrate the data

Now that your code is handling the migration of data as it runs, we need to migrate all columns to the new schema.

We can either use a migration for this or just write and run a rake task to copy all data from the body column to the content column.

Once this step is complete, the content column should be canonical and remain that way due to the way the code is written.

Step 4: Remove the temporary syncing code

We can now remove all references to the body column, including the code that syncs the data between the two columns.

At this point, we are almost done. The code is all updated not to use the old column; it only remains in the database.

Step 5: Drop the column

Finally, all we need to do is write a migration to drop the column from the database and deploy it to production. The code does not reference the column, so we can deploy it at our leisure.

YMMV

This technique has worked very well for us at Engine Yard. It can be more complex, but overall it leads to less friction in the deploy process. When you know that there is no downtime needed for any step of your work, you can simply write code and ship it to production when you're ready, rather than being blocked on waiting for a maintenance window.

Adding a column to the database is by far the most common kind of migration that we do. And using this technique still makes that very simple. Over all it has not added a significant amount of overhead to getting things done, and the lack of friction is a huge win.

Doesn't always work

All this said, there are a small number of cases when you really cannot perform this technique. These are cases where the migration will take a long time and lock tables or cause heavy load on the database server. In the past year, these kinds of migrations have been the only ones that we have had to take downtime for. The most common manifestation was adding an index on a very large table. But if your database is heavily loaded, many ALTER TABLE statements may take an unacceptably long time.


more »

What Are Events, Why Might You Care, and How Can EventMachine Help? »

Created at: 08.12.2011 22:13, source: Engine Yard Blog, tagged: ruby Technology

You have likely heard of event based/driven programming, which you may also see referred to as "evented" programming. It has been around and in use for a long time, but it is seeing a growing swell of interest in recent years. Perl has had POE for years. Likewise, Python has had Twisted for quite a few years. Graphics toolkits such as GTK use event loops to respond to user interface events. Javascript has been getting a lot of attention lately because of the Node.js event driven framework. Ruby has had the EventMachine library since 2006, with other event driven programming libraries such as Rev and Coolio being released since then.

Despite this relative wealth of libraries, and growing interest in the event driven programming paradigm, this realm of software design is still shrouded in mystery and unknowns for many developers. People who are new to it tend to misunderstand it, often assuming magic that does not exist, or simply misunderstanding what "event driven" really means. Even developers with experience writing event based software using one of the previously mentioned libraries are often fuzzy on the details. They may assume that their library of choice represents the "real" world of event based programming. Or simply because their use cases only take them to a few familiar neighborhoods of evented programming, they may retain some of that newbie fog for other parts.

This series of articles is going to attempt to rectify some of those situations. The precise course of the articles will be determined as they progress, but for today, let's start at the beginning. Event Based/Driven Programming. It'a hot. All the cool kids are doing it. It's got EVENTS! Raise your hand if you truly know what that means, or why you should actually care.

Event
–noun
  1. something that happens or is regarded as happening; an occurrence, especially one of some importance.
  2. the outcome, issue, or result of anything: The venture had no successful event.
  3. something that occurs in a certain place during a particular interval of time.

That quote was courtesy of http://dictionary.reference.com/browse/event

Applying that definition to the world of software is a pretty direct thing, as it turns out. Event based programming is nothing more than letting the flow of the program be determined by some set of events. Hardware interrupts are an example of a ubiquitous source of events. On Unix systems, signals and the signal handlers that deal with them are a type of event based programming, as well. A typical pattern for windowing systems is to operate with an event based model; the software can't know when one is going to click on a menu item, or a dialog button, so the software instead runs in a loop, waiting for some event to happen. When an event occurs, the software calls into another piece of code to handle that event.

At its simplest, that general pattern of the system being divided into a dyad consisting of one part that detects or selects events, with a second part that handles them, is what event based programming is actually about. If you have been programming for any length of time, the odds are pretty good that at least in some small ways, you have engaged in event driven programming even if you didn't realize it.

If you go back and look at any of those libraries that I mentioned at the top of the articles, you will notice a trend. Each of those libraries is an event driven programming library, but there is a fair amount of variation across them. This is because event driven is a vague label, encompassing numerous patterns and feature sets. One of the most common of these patterns is the Reactor pattern.

The Reactor pattern describes a system that handles asynchronous events, but that does so with synchronous event callbacks. There are several ruby implementations of this pattern, including the most common library for event based programming in Ruby today, EventMachine. A reactor is good at handling many concurrent streams of incoming our outgoing IO, but because the callbacks are invoked synchronously, callback handling can severely impact the concurrency, or apparent concurrency, of a reactor implementation. Nonetheless, reactors are easy to implement, and with a little care, can be used to drive high performance IO on a single threaded, single process application.

As I mentioned, EventMachine is a Reactor implementation. And it is perfectly possible to install EventMachine, look at a few documents and a few examples, and start writing your own event based software that uses it without really having a good idea of how the machine is running under the hood. But there is value in understanding what a Reactor actually is, so that you better understand what a library like EventMachine is doing for you. Ruby gives us a lot of tools that make it reasonably easy to write a very simple pure ruby reactor implementation, so let's do that. It should make this topic much clearer when you see how simple it actually is. All of the code shown below can also be found on GitHub at https://github.com/engineyard/khaines_blog_code_examples/tree/master/what_are_events. All of these pure ruby examples should work on every Ruby implementation. I have tried it on MRI 1.8.7_p352 and 1.9.3_p0, as well as JRuby 1.6.5 and Rubinius 2.0.0dev, though I did not extensively test on anything other than MRI 1.9.3, so quirks may exist.

For our pure ruby reactor, we want only a few features.

  • Unlike EventMachine, which also includes substantial support for managing creations of network connections, servers, and other more sophisticated activities, our reactor is going to limit itself to only being a tool for handling events. Therefor, all that it needs is a way to attach and detach IO objects to/from the reactor. We'll use the built in ruby mechanisms for everything else.
  • Ruby has the select() call available to it on all platforms, so our reactor will be designed to use it. The select() call returns readable handles, writeable handles, and errors from a set of filehandles to operate on, so those three events (:read, :write, :error) will likewise be all that our reactor handles.
  • Timers are very useful, and are pretty easy to implement in a reactor, so it would be nice to have a timer implementation.

Even though it is not strictly necessary for a reactor implementation, I will start our implementation with the timer functionality. Timers are events which are time based. Their callback is triggered at some point after a given time threshold is reached. The difficulty with timers is in choosing a mechanism for storing them such that the ones which need to be triggered can be easily and efficiently detected. Time, however, is a sortable attribute, and there are some data structures that are great for storing sortable data where that sorted data order is important. There are tree based data structures which are very efficient at maintaining this sort of data. Ruby doesn't have one of those as a native data type, so for this example, I will just fake it. If I were writing a serious implementation, I would have to do more work to provide an efficient data structure for timer data. The following data structure is built on top of a hash, makes no claims to be efficient, and provides the bare minimum API for our reactor to have the tool that it needs to implement timers.

class SimpleReactor

  class TimerMap < Hash
    def []=(k,v)
      super
      @sorted_keys = keys.sort
      v
    end

    def delete k
      r = super
      @sorted_keys = keys.sort
      r
    end

    def next_time
      @sorted_keys.first
    end

    def shift
      if @sorted_keys.empty?
        nil
      else
        first_key = @sorted_keys.shift
        val = self.delete first_key
        [first_key, val]
      end
    end

    def add_timer time, *args, &block
      time = case time
      when Time
        Time.to_i
      else
        Time.now + time.to_i
      end

      self[time] = [block, args] if block
    end

    def call_next_timer
      _, v = self.shift
      block, args = v
      block.call(*args)
    end
  end
end

Ok. Now let's start writing a reactor! Since we started with timers, we'll just write enough to make timers work. So, first, an #initialize method, and a method to add timers.

class SimpleReactor

  def initialize
    @running = false

    @timers = TimerMap.new
    @block_buffer = []
  end

  def add_timer time, *args, &block
    time = time.to_i if Time === time
    @timers.add_timer time, *args, &block
  end

There's nothing interesting with the initialization. It just sets the @running instance variable false. This will be used in an upcoming bit of code. The method to add a timer also does nothing special; it just passes everything into a method of the same name in the TimerMap. The next part that is needed is the skeleton of our reactor. Here is what it looks like:

  def next_tick &block
    @block_buffer << block
  end

  def tick
    handle_pending_blocks
    handle_events
    handle_timers
  end

  def run
    @running = true

    yield self if block_given?

    tick while @running
  end

  def stop
    @running = false
  end

  def handle_pending_blocks
    @block_buffer.length.times { @block_buffer.shift.call }
  end

  def handle_events
  end

  def handle_timers
    now = Time.now
    while !@timers.empty? && @timers.next_time < now
      @timers.call_next_timer
    end
  end

  def empty?
    @timers.empty? && @block_buffer.empty?
  end
end

There you have it. A reactor skeleton, albeit one that only supports timers and next_tick right now. Here's an example that uses it:

require 'simplereactor'

puts <<ETXT
This demo will add a sequence of numbers to a sum, via a timer, once a second,
for four seconds, with the fifth number immediately following the fourth.
1+2+3+4+5 == 15. Let's see if that's the answer that we get."
ETXT

n = 0
reactor = SimpleReactor.new

reactor.add_timer(1) do
  puts "one"
  n += 1
end

reactor.add_timer(2) do
  puts "two"

  reactor.add_timer(1, n + 2) do |sum|
    puts "three"

    reactor.add_timer(1, sum + 3) do |sum|
      puts "four"
      n = sum + 4

      reactor.next_tick do
        puts "five"
        n += 5
        puts "n is #{n}\nThe reactor should stop after this."
      end
    end
  end
end

reactor.tick until reactor.empty?

There's no real magic here. The code shows that one can create timers, and can create new timers within the callback code of existing timers, leveraging Ruby's block syntax. If you run this, you will get output like this:

This demo will add a sequence of numbers to a sum, via a timer, once a second, for four seconds, with the fifth number immediately following the fourth. 1+2+3+4+5 == 15. Let's see if that's the answer that we get.
one
two
three
four
five
n is 15
The reactor should stop after this.

Take note of the last line in the example code -- reactor.tick until reactor.empty?. The reactor will not do anything until that line runs. That line sits in a loop, ticking our reactor repeatedly until there's nothing left for it to do. At that point, #empty? returns true, the loop terminates, and the program terminates.

The next step in this adventure is to add enough code to our reactor to do something useful with IO objects, as well. We need to be able to attach them to the reactor, detach them from the reactor, and put enough intelligence into the reactor to find events to respond to, and trigger the callbacks for those events.

First add a constant and some accessors, and change the #initialize method:

  Events = [:read, :write, :error].freeze
  attr_reader :ios

  def self.run &block
    reactor = self.new

    reactor.run &block
  end

  def initialize
    @running = false
    @ios = Hash.new do |h,k|
      h[k] = {
        :events => [],
        :callbacks => {},
        :args => [] }
    end

    @timers = TimerMap.new
    @block_buffer = []
  end

This adds a hash for holding our IO objects. It has an initializer to hold an array of events that that the IO object will respond to, a hash of callbacks (potentially one per event type), and some set of args which can be passed to an invoked callback. A hash is also created to hold unhandled events, should they occur.

Next, let's add some methods to attach an IO object to the reactor, setup callbacks, and detach an IO object to the reactor.

  def attach io, *args, &block
    events = Events & args
    args -= events

    @ios[io][:events] |= events

    setup_callback io, events, *args, &block

    self
  end

  def setup_callback io, events, *args, &block
    i = @ios[io]
    events.each {|event| i[:callbacks][event] = block }
    i[:args] = args
    i
  end

  def detach io
    @ios.delete io
  end

The code takes an IO object, a set of args to pass into the callback, and a block. It adds it to the @ios hash, and sets up the callback for the given events.

Next, we need to add a few small methods to enable triggering on IO events.

  def handle_events
    unless @ios.empty?
      pending_events.each do |io, events|
        events.each do |event|
          if @ios.has_key? io
            if handler = @ios[io][:callbacks][event]
              handler.call io, *@ios[io][:args]
            end
          end
        end
      end
    end
  end

The #handle_events method is straightforward. If there are any attached IO objects, iterate through the events, calling the callbacks for each. In the existing code, we should never have unhandled events, but by adding that now, one could take this library and expand it more easily into a larger pure ruby reactor that handles types of events other that just what select() uses.

  def pending_events
    # Trim our IO set to only include those which are not closed.
    @ios.reject! {|io, v| io.closed? }

    h = find_handles_with_events @ios.keys

    if h
      handles = Events.zip(h).inject({}) {|handles, ev| handles[ev.first] = ev.last; handles}

      events = Hash.new {|h,k| h[k] = []}

      Events.each do |event|
        handles[event].each { |io| events[io] << event }
      end

      events
    else
      {} # No handles
    end
  end

  def find_handles_with_events keys
    select find_ios(:read), find_ios(:write), keys, 0.01
  end

  def find_ios(event)
    @ios.select { |io, h| h[:events].include? event}.collect { |io, data| io } }
  end

  def empty?
    @ios.empty? && @timers.empty? && @block_buffer.empty?
  end

This last bit of code just adds the nitty gritty methods that figures out if there are any events that need to be handled. It removes from @ios any handles that are closed, uses select() to find IO events, and then returns a hash of IO objects and the events that have been triggered on them. String all of this code together, and it is all that you need to have a basic working Reactor pattern for event based programming, with timer support. Here's a trivial example that uses pipes, to illustrate how it works.

require 'simplereactor'

chunk = "01234567890" * 30

reactor = SimpleReactor.new

reader, writer = IO.pipe

reactor.attach writer, :write do |write_io|
  bytes_written = write_io.write chunk
  puts "Sent #{bytes_written} bytes: #{chunk[0..(bytes_written - 1)]}"

  chunk.slice!(0,bytes_written)
  if chunk.empty?
    reactor.detach write_io
    write_io.close
  end
end

reactor.attach reader, :read do |read_io|
  if read_io.eof?
    puts "finished; detaching and closing."
    reactor.detach read_io
    read_io.close
  else
    puts "received: #{read_io.read 200}"
  end
end

reactor.add_timer(2) do
  puts "Timer called; the code should exit after this."
end

reactor.tick until reactor.empty?

All that code does is to open a pair of pipes. The reactor attaches to one end as a writer, and the other end as a reader. The callbacks are used to send data from one end of the pipe to the other, where it is received. The Reactor will run for two seconds, then after the timer runs, the reactor will be empty, and it will exit. It looks like this:

Sent 330 bytes: 012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
received: 01234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001
received: 2345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
finished; detaching and closing.
Timer called; the code should exit after this.

Here's another example. This one takes user input through the reactor via STDIN, and at the same time runs the stupidest, simplest web server possible. That web server will return a response that includes whatever the user input. The example code is also written to leverage the #run method defined in the library instead of cranking it ourselves.

require './simplereactor'
require 'socket'

server = TCPServer.new("0.0.0.0", 9949)
buffer = ''

puts <<ETXT
Type some text and press  after each line. The reactor is attached to
STDIN and also port 9949, where it listens for any connection and responds with
a basic HTTP response containing whatever has been typed to that point. These
two dramatically different IO streams are being handled simultaneously. Type
 to exit, or wait one minute, and a timer will fire which causes the
reactor to stop and the program to exit.
ETXT

SimpleReactor.run do |reactor|
  reactor.attach(server, :read) do |server|
    conn = server.accept
    conn.gets # Pull all of the incoming data, even though it is not used in this example
    conn.write "HTTP/1.1 200 OK\r\nContent-Length:#{buffer.length}\r\nContent-Type:text/plain\r\nConnection:close\r\n\r\n#{buffer}"
    conn.close
  end

  characters_received = 0
  reactor.attach(STDIN, :read) do |stdin|
    characters_received += 1
    data = stdin.getc # Pull a character at a time, just for illustration purposes
    unless data
      reactor.stop
    else
      buffer << data
    end
  end

  reactor.add_timer(60) do
    reactor.stop
  end
end

When this is executed, it attaches to STDIN, allowing one to provide input which is buffered internally. Any connection to port 9949 returns a simple HTTP response that contains the buffer that was created through STDIN. The process will run for 60 seconds, then the reactor will stop. Bearing in mind that this is a ridiculously trivial example, it does perform pretty well, too. Below is an excerpt from a test run, done using Ruby 1.9.3_preview1, on one of my older Linux machines.

Concurrency Level:      25
Time taken for tests:   1.60504 seconds
Complete requests:      15000
Failed requests:        0
Write errors:           0
Total transferred:      1275000 bytes
HTML transferred:       75000 bytes
Requests per second:    14144.22 [#/sec] (mean)
Time per request:       1.768 [ms] (mean)
Time per request:       0.071 [ms] (mean, across all concurrent requests)
Transfer rate:          1173.97 [Kbytes/sec] received

Of course, this is an absurdly trivial example. There may be bugs, and it doesn't really do a lot for you, but it is an event reactor, written in pure ruby, and if you went through the code and examples as you read, you should have a better feel for what a reactor truly is.

If you want to write more sophisticated event based software, you could continue using a simple hand-rolled pure ruby reactor like this one, or you might choose to use one of the other common libraries for Ruby today. There are several of them, each with their own strengths and weaknesses, though the most common is EventMachine. Just like our simple reactor, EventMachine offers timers and asynchronous handling of events, though EventMachine's versions will scale better. This article's version uses the select() call, which limits code using it to 1024 open file descriptors. On the other hand, EventMachine, if used on a platform that support epoll (Linux) or kqueue (various *BSD platforms), can readily support at least 10s of thousands. EventMachine also offers a more rich set of features for implementing event based code than this article's example reactor. As a parting example, here is the HTTP server example from above, written to use EventMachine.

require 'rubygems'
require 'eventmachine'

module ServerHandler
  def initialize(buffer)
    @buffer = buffer
    super
  end

  def receive_data data
    send_data "HTTP/1.1 200 OK\r\nContent-Length:#{@buffer.length}\r\nContent-Type:text/plain\r\nConnection:close\r\n\r\n#{@buffer}"
    close_connection_after_writing
  end

end

module KeyHandler
  def initialize buffer
    @counter = 0
    @buffer = buffer
    super
  end

  def receive_data data
    @counter += 1
    if data.chomp.empty?
      EM.stop
    else
      @buffer << data
    end
  end
end

puts <<ETXT
Type some text and press  after each line. The reactor is attached to
STDIN and also port 9949, where it listens for any connection and responds with
a basic HTTP response containing whatever has been typed to that point. These
two dramatically different IO streams are being handled simultaneously. Type
a blank line to exit, or wait one minute, and a timer will fire which causes the
reactor to stop and the program to exit.
ETXT

buffer = ''

EventMachine.run do
  EM.start_server('0.0.0.0',9949,ServerHandler,buffer)

  EM.attach(STDIN, KeyHandler, buffer)

  EM.add_timer(60) do
    EM.stop
  end
end

And since I demonstrated the performance of the pure Ruby version, here's the performance of the EventMachine version (using EventMachine 0.12.10), running on the same system, using the same Ruby 1.9.3_preview1 installation.

Concurrency Level:      25
Time taken for tests:   0.696320 seconds
Complete requests:      15000
Failed requests:        0
Write errors:           0
Total transferred:      1275425 bytes
HTML transferred:       75025 bytes
Requests per second:    21541.82 [#/sec] (mean)
Time per request:       1.161 [ms] (mean)
Time per request:       0.046 [ms] (mean, across all concurrent requests)
Transfer rate:          1787.97 [Kbytes/sec] received

The code is structured differently, but as you can see, it works similarly. In our simple reactor example, if you changed data = stdin.getc to data = stdin.gets, the STDIN handling would behave similarly to the EM examples STDIN handling. However, given the experience of writing a pure ruby reactor, even if you have never used EventMachine before, I think you can now look at that piece of EventMachine code and generally understand how it works, both at the level of the ruby code itself, and with a good idea of what EventMachine is handling for you. This basic understanding of how event driven software actually works is key to writing software that uses the event paradigm effectively.

I have focused on EventMachine in this article because it is the most commonly used event reactor implementation in the Ruby world today. As I mentioned at the beginning of the article, however, there are other choices, such as Coolio. In future articles I will continue to focus on EventMachine, but I will try to include some examples from other frameworks, and also some examples focused on JRuby and Rubinius. Please let us know if there are particular topics that you would like to see discussed.


more »

MySQL 5.5 is in Beta »

Created at: 06.12.2011 19:55, source: Engine Yard Blog, tagged: Product ruby

A few months ago we launched an alpha release of MySQL 5.5. Today we are releasing a more robust version as a public Beta, which includes fixes and enhancements based on customer feedback. You can select MySQL 5.5 from your environment and install the Percona Server v5.5.13. The Percona build is an enhanced drop-in replacement for MySQL that allows you to run queries with greater speed and consistency.

Benefits of Upgrading

MySQL 5.5 delivers significant enhancements that enable you to improve the performance and scalability of your web applications. Some reasons to upgrade are:

  • InnoDB as default storage engine: Starting in MySQL 5.5, InnoDB is the default storage engine. MySQL 5.5’s InnoDB 1.1 storage engine is re-architected and has many performance and scalability features.
  • Improved multi-core performance: The database and its InnoDB storage engine have been enhanced to provide optimum performance and scalability when running on the latest multi-CPU and multi-core hardware and operating systems.
  • Improved recovery performance: One of InnoDB's great strengths is its ability to reliably recover data after any type of crash that affects the database. But, this cleanup and checking makes the next restart longer. InnoDB 1.1 has improved the algorithms for recovery to provide faster uptime after a crash.

See the MySQL Documentation for additional information.

Important! MySQL 5.5 on Engine Yard Cloud is a Beta feature. Always test in a development or staging environment before using this feature in production.

Available Upgrade Options

Be sure to review your upgrade options. The database and storage engines are substantially different, and a binary upgrade on the master database is not recommended. As a result, some downtime is unavoidable.

Dump and Restore
Best for: Small to medium data sets

This entails creating a new environment that is running the MySQL 5.5 database version and restoring a dump from the original environment to it. It requires your application to be down (or at least not servicing database requests) for the duration of the dump from the original environment and the restore to the new one. The size of your database matters; the more data you have, the longer it takes to dump and import it on the new database. Instructions on dump and restoring backup files can be found under Scenario 2 in our Database Documentation site.

In-Place Upgrade by Professional Services
Best for: Large data sets

If you know or suspect that the dump/restore upgrade will take too long (from prior testing or from the size of your database), then contact our Professional Services team to inquire about an assisted in-place upgrade of your existing environment(s).

This option will be available starting January 1st, 2012. Our database support team will analyze your database and provide you with an optimal upgrade path based on your application needs. As a baseline, the team will perform an in-place binary upgrade on a database slave (at least one is required) and then promote the newly upgraded slave to master. The team will also alert you if you should be aware of any possible upgrade blockers based on your environment. The in-place upgrade path can potentially minimize application downtime to mere minutes!
We hope you are as excited as we are with this Beta release and stay tuned for more news from the EY Data team. (Hint - you won’t have to wait long!)


more »

I heard you liked files »

Created at: 02.12.2011 07:35, source: has_many :through, tagged: ruby

I was going to try and be clever and do a funny riff on this whole subject, but I just can't manage it. Here's the thing. Makefile was a dumb name for a file when Stuart Feldman wrote the make utility in 1977, but you have to forgive him because file systems were quite limited back then and filenames could only be a few characters long. The pattern was <filename.ext> - 8 chars for the name, 3 for the extension. I guess config.make wouldn't fit, config.mak looked weird, so Makefile it was.

Now we have no excuse. At all.

I respect and adore Jim Weirich, but I hope he feels at least a little shame for inflicting "Rakefile" on us all. That name choice seems to have set the stage for a proliferation of copycats. Now we have an ever-growing assortment of files that helpfully tell us they are files right there in the file name. Because something siting in a directory in the file system might be something else, like maybe a turnip or a bad hair day. Capfile, Gemfile, Procfile, Assetfile, Vagrantfile, Guardfile...

You may ask: What's the problem? Why should anyone care about a cute little naming convention that continues a tradition going back over 30 years?

It may not be a huge deal, but there are a couple issues with this. All of these file formats are actually a variation on a well-accepted language: Ruby. But with a name that omits the standard .rb extension, language-aware tools have no chance to help us out. Syntax highlighting? Nope. Will awk search those files for you? No way. Will RubyMine figure out the structure of the code in those files? Forget it. OK, you can add those files to all your tools' configurations, then you're good to go. Until someone creates a new Crapfile and you have to go through and update all those configurations again.

Just because your configuration file's contents are written in a DSL does not mean you should pretend it's not Ruby anymore.

I urge every maintainer of a project that uses a name like Crapfile for the configuration file to move toward using a name that is compatible with language-aware tools. If you can't think of a name yourself, allow me to suggest this:

filename.sub(/file$/, '_config.rb').downcase

UPDATE: It has been pointed out to me that RubyMine actually does a pretty good job of dealing with these file names. Not perfect, but pretty good. Anyway, I don't want to come off as bashing RubyMine (I'm spending more time with it now and it's starting to grow on me), so substitute vim or emacs or TextMate or your most-hated editor instead.


more »

Engine Yard Winter Updates! »

Created at: 29.11.2011 00:03, source: Engine Yard Blog, tagged: Product ruby

Update: Multiple availability zone deployments now available in Alpha. Check out our additional documentation. To sign up for access, go here

Greetings! As the weather begins to cool, the team here is keeping warm by continuing to knock out more amazing features for all of you. I wanted to let you all know about some of the great things we have cooking over here at Engine Yard that will make life more awesome than it already is.

Highly Available, Highly Addictive

In talking to many of our customers, partners, and developers, one of the issues that frequently comes up is the ability to stay running when data centers inevitably experience an outage. Last April, one such outage impacted a variety of customers on Amazon Web Services. While we are always striving to improve our service, with our multi-region support, we were able to effectively move many of our impacted customers to Amazon’s US West region while minimizing downtime.

We plan to continue adding new features to further mitigate the effects of outages and disruptions. Currently, our development team is in the process of rolling out multiple availability zone deployments. When you create an application, Engine Yard Cloud will automatically deploy your instances across different availability zones in an Amazon Web Services region.  We balance the instances efficiently and ensure that master and slave instances are in separate zones. To further improve reliability, each tier (app server, database, and utility) will be balanced independently. The team is doing some final tests and should have it rolled out in a week or so. We’ll release more information on this soon and will announce availability via our @engineyard twitter account.

For customers with specific high availability requirements, Engine Yard Professional Services can customize an environment to meet your needs. For example, Engine Yard Professional Services recently deployed a high availability solution across two data centers for one our customers and completed a regional failover test with success. Be on the lookout soon for a case study on this initiative.  If you would like to learn more, please get in touch with our Professional Services team.

Need More Data!

A couple months ago, our data engineering team laid out a plan to strengthen Engine Yard’s data offerings. In an effort to make more database options available to our customers, the data engineering team released PostgreSQL 9.0 into alpha. After collecting some feedback, the team will be releasing PostreSQL 9.1 as a public beta over the next couple of weeks for all of you to use. PostgreSQL has earned a solid reputation for reliability, data integrity, and performance. As we noted earlier, those using Rails 3.1 can take advantage of significant performance gains using PostgreSQL.

The team also recently released MySQL 5.1 and 5.5 into alpha and will be releasing them as public beta shortly, as well. Please check back soon for news regarding MongoDB, Redis, and more!


more »