Rack::TrafficSignal
Rack::TrafficSignal is a Rack middleware to make application in maintenance mode. You can make part of application in maintenance mode, and use different http status and response body.
Installation
Add this line to your application's Gemfile:
gem 'rack-traffic-signal'
And then execute:
$ bundle
Or install it yourself as:
$ gem install rack-traffic-signal
If you are installing this gem to Rails application, run:
$ rails g rack_traffic_signal:install
Usage
Rails
Generator places initializer template and sample maintenance page.
Modify config/initializers/rack_traffic_signal.rb
.
And add below to your application.rb
require 'rack/traffic_signal'
...
config.middleware.use(Rack::TrafficSignal::Middleware)
...
Not Rails
Insert Rack::TrafficSignal::Middleware to Middleware stack manually, and create setting script.
Setting
Rack::TrafficSignal.setup do |config|
# This config is used to internal_access? method.
# Only add path to this option, mantenance mode is not skipped.
config.internal_ips = ['192.168.1.1/25']
# This config is used to skip_path? method.
# Only add path to this option, mantenance mode is not skipped.
config.skip_paths = [/^\/users\/12345/]
# This config is used to skip_path? method.
# Only add path to this option, mantenance mode is not skipped.
# If request header has `X-RACK-TRAFFIC-SIGNAL-SECRET=<secret word>`, Rack::TrafficSignal.has_secret returns true.
config.secret_word = 'secret'
# Default setting
config.default_status = 503
config.default_content_type = 'application/json'
config.default_body = { error: 'error' }.to_json
# Maintenance group settings
# Maintenance group defined as :<resource>_<action>
# If path defined by String, maintenance mode will be applied path is match rigidly.
# '/users' does not make maintenance mode '/users/foo'.
# If multiple setting is appliable, more general setting will be priored.
# %{/} has higher priority than %{/users/\/d+/foo/bar}
config.maintenance_group = {
# <resource>: {
# <action>: [
# { methods: [:get, :post], path: <path_to_maintenance>}
# ]
# }
users: {
register: [
{ methods: [:get], path: "/users/new"},
{ methods: [:post], path: "/users" }
],
update: [
{ methods: [:put], path: %r{/users/\d+}, status: 404, body: { meta: '404' }.to_json }
]
}
}
# Block to judge whether requested page/api is under maintenance.
# Returns Array<Symbol>
# If status array include...
# :all => all of maintenance groups are enabled.
# :<resource>_all => maintenance groups under resource
# ex) :users_all => users_register and users_update are in under maintenance
# :<resource>_<action> => maintenance group matches is in under maintenance
config.maintenance_status_by do
ENV['MAINTENANCE_STATUS'] # [:users_register, :users_update]
end
# Block to judge whether maintenance mode should be skipped.
# For example, you can skip maintenance mode with specific path or internal access.
config.skip_by do |env|
Rack::TrafficSignal.skip_path?(env) || Rack::TrafficSignal.internal_access?(env)
end
# Block to judge whether maintenance mode should be skipped with warning.
# For example, you can skip maintenance mode with specific path or internal access.
# Warn by add 'X-RACK-TRAFFIC-SIGNAL-MAINTENANCE' to response header.
config.skip_with_warning_by do |env|
Rack::TrafficSignal.skip_path?(env) || Rack::TrafficSignal.internal_access?(env)
end
end
Contributing
- Fork it
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create new Pull Request
License
The gem is available as open source under the terms of the MIT License.