Rack::Downtime

Planned downtime management for Rack applications

Build Status Code Climate

Overview

Rack::Dowtime does not add a maintenance page -there are plenty of ways to do this already. Instead, it provides one with a variety of simple ways to trigger and takedown planned maintenance notifications while a site is still up.

Examples

require "rack/downtime"

use Rack::Downtime

In your layout:

<% if ENV.include?("rack.downtime") %>
  <div>
    <p>
      We will be down for maintenance on
      <%= ENV["rack.downtime"][0].strftime("%b %e") %> from
      <%= ENV["rack.downtime"][0].strftime("%l:%M %p") %> to
      <%= ENV["rack.downtime"][1].strftime("%l:%M %p") %> EST.
    </p>
  </div>
<% end %>

Now set the downtime using the :file strategy:

# 1 to 4 AM
> echo '2014-11-15T01:00/2014-11-15T04:00' > downtime.txt

If you prefer, Rack::Downtime can insert the message for you:

# Inserts a downtime message
use Rack::Downtime, :insert => "my_template.erb"

# Specify where to insert message
use Rack::Downtime, :insert => "my_template.erb", :insert_at => "body #container"

The downtime can be set various ways:

# From the HTTP header X-Downtime
use Rack::Downtime, :strategy => :header
use Rack::Downtime, :strategy => { :header => "X-MyHeader" }

# Or from the query string
use Rack::Downtime, :strategy => :query
use Rack::Downtime, :strategy => { :query => "dwn__" }

Alternate configuration:

Rack::Downtime.strategy = :file
Rack::Downtime::Strategy::File.path = Rails.root.join("downtime.txt")

Control its behavior via environment variables:

SetEnv RACK_DOWNTIME 2014-11-15T01:00:00-05/2014-11-15T04:00:00-05

# Disable
SetEnv RACK_DOWNTIME_DISABLE 1

# Or, just turn of insertion
SetEnv RACK_DOWNTIME_INSERT  0

Usage

Downtime can be retrieved from various locations via a downtime strategy. When downtime is detected, it's turned into 2 instances of DateTime and added to the Rack environment at rack.downtime. The 0th element is the start time and the 1st element is the end time.

The dates must be given as an ISO 8601 time interval in start/end format. If no dates are found rack.downtime will not be set.

Downtime messages can also be added to the response's body. See Inserting a Downtime Message.

Downtime Strategies

Strategies are given via the :strategy option. If none is provided then Rack::Downtime.strategy is used, which defaults to :file.

:file

Looks in the current directory for a file named downtime.txt.

use Rack::Downtime :strategy => :file

To use a file named my_file.txt:

use Rack::Downtime :strategy => { :file => "my_file.txt" }

:query

Looks for a query string parameter named __dt__.

use Rack::Downtime :strategy => :query

To use a query string named q:

use Rack::Downtime :strategy => { :query => "q" }

Looks for an HTTP header named X-Downtime.

use Rack::Downtime :strategy => :header

To look for a header named X-DT-4SHO:

use Rack::Downtime :strategy => { :header => "X-DT-4SHO" }

Internally the header will be converted to match what rack generates, e.g., HTTP_*.

:env

Looks for an environment variable named RACK_DOWNTIME.

Looks for cookie named __dt__.

use Rack::Downtime :strategy => :cookie

To use a cookie named oreo:

use Rack::Downtime :strategy => { :cookie => "oreo" }

Custom

Just pass in something that responds to :call, accepts a rack environment, and returns a downtime array.

use Rack::Downtime :strategy => ->(env) { YourDownTimeConfig.find_dowmtime }

Inserting a Downtime Message

A message can be inserted by Rack::Downtime into your response's body whenever downtime is scheduled. Just provide a path to an ERB template to the :insert option. The downtime will be passed to the template as start_time and end_time.

By default the template will be inserted after the body tag. This can be changed by providing the desired location to the :insert_at option. The location can be given as a CSS selector or an XPath location.

Messages are only inserted into HTML responses with a 200 status code.

Note that when Rack::Downtime inserts a message it will turn a streaming response into a buffered one. If this is a problem you can always check for and insert the downtime yourself in your application.

TODO

Don't invalidate XHTML responses when inserting a downtime message.

Author

Skye Shaw [sshaw AT gmail.com]