rack-maintenance_mode 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +0 -2
- data/README.md +160 -0
- data/lib/rack/maintenance_mode.rb +5 -0
- data/lib/rack/maintenance_mode/default_mode_check.rb +14 -0
- data/lib/rack/maintenance_mode/middleware.rb +14 -4
- data/lib/rack/maintenance_mode/railtie.rb +11 -0
- data/lib/rack/maintenance_mode/version.rb +1 -1
- metadata +6 -5
data/Gemfile
CHANGED
data/README.md
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
# Rack::MaintenanceMode
|
2
|
+
|
3
|
+
Rack::MaintenanceMode is a Rack middleware which manages sending clients
|
4
|
+
maintenance (HTTP 503) responses, when appropriate. It is intended to be robust
|
5
|
+
and extensible, allowing you to meet your particular business needs.
|
6
|
+
|
7
|
+
## Maintenance mode is easy. What's the deal?
|
8
|
+
|
9
|
+
Glad you asked. So, yes, in a lot of applications, maintenance mode is simple:
|
10
|
+
all requests result in a 503 response. But, as applications grow and business
|
11
|
+
rules change, and … life happens … well, that's not always sufficient.
|
12
|
+
|
13
|
+
Maybe you'd like to 503 on all public requests, but still allow requests from
|
14
|
+
your IP to pass through it. Maybe you want to 503 only requests to a particular
|
15
|
+
subset of your URLs ("/api", for instance). Maybe you want to be in maintenance
|
16
|
+
mode based on some complex set of business rules (a particular column in the
|
17
|
+
database has a set value, and it's a full moon tonight, and Kim Kardashian is
|
18
|
+
married). Whatever.
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
If you're using Bundler, then add the gem to your Gemfile:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'rack-maintenance_mode'
|
26
|
+
```
|
27
|
+
|
28
|
+
Otherwise:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ gem install rack-maintenance_mode
|
32
|
+
```
|
33
|
+
|
34
|
+
## How does it work?
|
35
|
+
|
36
|
+
So, it's a Rack middleware. That's pretty simple. And, by default, it'll
|
37
|
+
"just work," by watching for a `ENV["MAINTENANCE"]` variable to be set. If
|
38
|
+
it's set, it'll automatically respond with a default 503 response, containing
|
39
|
+
a simple HTML page and message:
|
40
|
+
|
41
|
+
> We are undergoing maintenance right now, please try again soon.
|
42
|
+
|
43
|
+
## Customization
|
44
|
+
|
45
|
+
The default, while useful, probably isn't exactly what you're looking for, is
|
46
|
+
it? So, how do we customize it?
|
47
|
+
|
48
|
+
Well, if you're using Rails, then it will integrate with your application
|
49
|
+
automatically using a Railtie. This gives us a few things: first, the
|
50
|
+
middleware will be automatically loaded for you. And second, this gives you a
|
51
|
+
simple way to override the default behaviour.
|
52
|
+
|
53
|
+
### Customized maintenance mode logic
|
54
|
+
|
55
|
+
You can create your own, custom, maintenance mode determination logic in a few
|
56
|
+
ways. Well, really… a ton of ways, but at the end of the day, you just need
|
57
|
+
to encapsulate it in something that responds to `call`. So, that could be a
|
58
|
+
simple Proc, a module, a class, and instance, a mock, a stub, … I don't really
|
59
|
+
care. That's up to you.
|
60
|
+
|
61
|
+
Here's a very simple example of a customization using the Railtie integration
|
62
|
+
when using this gem with Rails (in `config/application.rb`):
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
require File.expand_path('../boot', __FILE__)
|
66
|
+
require 'rails/all'
|
67
|
+
Bundler.require(:default, Rails.env) if defined?(Bundler)
|
68
|
+
|
69
|
+
module MySuperApp
|
70
|
+
class Application < Rails::Application
|
71
|
+
…
|
72
|
+
config.maintenance_mode.if = Proc.new { |env| true }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
Hey look! Every request is now in maintenance mode! Ok, probably not so
|
78
|
+
useful. So, then:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
config.maintenance_mode.if = Proc.new { |env|
|
82
|
+
ENV["MAINTENANCE"] == 'enabled' && !(env['PATH_INFO'] =~ /safe/)
|
83
|
+
}
|
84
|
+
```
|
85
|
+
|
86
|
+
Now, it'll only 503 if the ENV's maintenance flag is set and the request is to
|
87
|
+
something other than a "safe" URL (i.e. "http://awesome.com/safe/foo").
|
88
|
+
|
89
|
+
Maybe we don't like Procs all over the place. Can't we make a class?
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
# lib/maintenance.rb
|
93
|
+
class Maintenance
|
94
|
+
def call(env)
|
95
|
+
ENV["MAINTENANCE"] == 'enabled' && !(env['PATH_INFO'] =~ /safe/)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# config/application.rb
|
100
|
+
module MySuperApp
|
101
|
+
class Application < Rails::Application
|
102
|
+
…
|
103
|
+
config.maintenance_mode.if = Maintenance.new
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
Sure can.
|
109
|
+
|
110
|
+
"But wait," I hear you saying. I still get the crappy default maintenance mode
|
111
|
+
response. I'd like to have super-pretty, customized page with CSS-based,
|
112
|
+
shifting perspectives and whatnot. Yes, we can.
|
113
|
+
|
114
|
+
### Customized responses
|
115
|
+
|
116
|
+
Customizing the response is pretty straightforward, as well. Just as with
|
117
|
+
customizing the maintenance logic, you can also customize the response. The
|
118
|
+
only real requirement, again, is that you use something that responds to `call`,
|
119
|
+
which can accept a environment hash, and you return a Rack-compatible array.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
config.maintenance_mode.response = Proc.new { |env| [503, {'Content-Type' => 'text/plain'}, ['Go away']] }
|
123
|
+
```
|
124
|
+
|
125
|
+
This allows you to do some super-useful stuff. Like, maybe by inspecting the
|
126
|
+
`env`, you realize that it's an XML request, not HTML. Well, you could send
|
127
|
+
and XML response. Or, maybe you'd like to load that pretty HTML page you've
|
128
|
+
spent days crafting:
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
config.maintenance_mode.response = Proc.new { |env| [503, {'Content-Type' => 'text/html'}, [Rails.root.join("public/503.html").read]] }
|
132
|
+
```
|
133
|
+
|
134
|
+
Or, maybe you like classes:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
# lib/maintenance_response.rb
|
138
|
+
class MaintenanceResponse
|
139
|
+
def call(env)
|
140
|
+
content_type, body = case Pathname.new(env['PATH_INFO'])
|
141
|
+
when '.xml'
|
142
|
+
['application/xml', '<error>Maintenance</error>']
|
143
|
+
when '.json'
|
144
|
+
['application/json', 'Maintenance']
|
145
|
+
else
|
146
|
+
['text/html', '<html><body>Maintenance</body></html>']
|
147
|
+
end
|
148
|
+
|
149
|
+
[503, {'Content-Type' => content_type}, [body]]
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# config/application.rb
|
154
|
+
module MySuperApp
|
155
|
+
class Application < Rails::Application
|
156
|
+
…
|
157
|
+
config.maintenance_mode.response = MaintenanceResponse.new
|
158
|
+
end
|
159
|
+
end
|
160
|
+
```
|
@@ -4,6 +4,11 @@ require 'rack/maintenance_mode/middleware'
|
|
4
4
|
require 'rack/maintenance_mode/railtie' if defined?(Rails)
|
5
5
|
|
6
6
|
module Rack
|
7
|
+
##
|
8
|
+
# Rack::MaintenanceMode is a Rack middleware which manages sending clients
|
9
|
+
# maintenance (HTTP 503) responses, when appropriate. It is intended to be
|
10
|
+
# robust and extensible, allowing you to meet your particular business needs.
|
11
|
+
#
|
7
12
|
module MaintenanceMode
|
8
13
|
end
|
9
14
|
end
|
@@ -1,6 +1,20 @@
|
|
1
1
|
module Rack
|
2
2
|
module MaintenanceMode
|
3
|
+
##
|
4
|
+
# This is the default behaviour for the gem, with respect to determining
|
5
|
+
# whether or not a particular request should be responded to with a
|
6
|
+
# maintenance response.
|
7
|
+
#
|
3
8
|
module DefaultModeCheck
|
9
|
+
##
|
10
|
+
# With this implementation, maintenance mode will be enabled if there is
|
11
|
+
# an `ENV["MAINTENANCE"]` variable set and it has an acceptable value.
|
12
|
+
#
|
13
|
+
# Acceptable values for MAINTENANCE: on, yes, y, true, t, enable, enabled
|
14
|
+
#
|
15
|
+
# If the MAINTENANCE variable is unset or does not match one of the above
|
16
|
+
# values, maintenance mode is disabled.
|
17
|
+
#
|
4
18
|
def self.call(env)
|
5
19
|
ENV["MAINTENANCE"].to_s =~ /^(?:on|yes|y|true|t|enabled?)$/i
|
6
20
|
end
|
@@ -3,11 +3,21 @@ require 'rack/maintenance_mode/default_mode_check'
|
|
3
3
|
module Rack
|
4
4
|
module MaintenanceMode
|
5
5
|
##
|
6
|
-
# A Rack middleware to automatically put the Rack application into
|
7
|
-
# mode (HTTP 503).
|
6
|
+
# A Rack middleware to automatically put the Rack application into
|
7
|
+
# maintenance mode (HTTP 503).
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# The default behaviour may be overridden by passing specific options at
|
10
|
+
# the time of initialization.
|
11
|
+
#
|
12
|
+
# Available options:
|
13
|
+
#
|
14
|
+
# `:if` - Any object which responds to `call(hash)` and returns a
|
15
|
+
# true/false-like result. Used for determining whether or not we're in
|
16
|
+
# maintenance mode.
|
17
|
+
#
|
18
|
+
# `:response` - Any object which responds to `call(hash)` and returns a
|
19
|
+
# Rack-compatible response array. Used for generating the client response
|
20
|
+
# when in maintenance mode.
|
11
21
|
#
|
12
22
|
class Middleware
|
13
23
|
DEFAULT_RESPONSE = Proc.new { |env| [503, {"Content-Type" => "text/html"}, ["<html><body><h2>We are undergoing maintenance right now, please try again soon.</body></html>"]] }
|
@@ -1,5 +1,16 @@
|
|
1
1
|
module Rack
|
2
2
|
module MaintenanceMode
|
3
|
+
##
|
4
|
+
# This is the primary integration point when using this gem within a Rails
|
5
|
+
# application. This railtie allows for the following customizations:
|
6
|
+
#
|
7
|
+
# `config.maintenance_mode.if` - used for overriding the logic to determine
|
8
|
+
# whether or not the application is in maintenance mode.
|
9
|
+
#
|
10
|
+
# `config.maintenance_mode.response` - used for generating the maintenance
|
11
|
+
# response for the client when in maintenance mode.
|
12
|
+
#
|
13
|
+
#
|
3
14
|
class Railtie < Rails::Railtie
|
4
15
|
config.maintenance_mode = ActiveSupport::OrderedOptions.new
|
5
16
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-maintenance_mode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-01-05 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &2156868180 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '2.0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2156868180
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rack
|
27
|
-
requirement: &
|
27
|
+
requirement: &2156867680 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 1.0.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2156867680
|
36
36
|
description: Allows you to create a customized maintenance mode for your application
|
37
37
|
that is run early in the Rack stack.
|
38
38
|
email:
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- .rspec
|
46
46
|
- .rvmrc
|
47
47
|
- Gemfile
|
48
|
+
- README.md
|
48
49
|
- Rakefile
|
49
50
|
- lib/rack-maintenance_mode.rb
|
50
51
|
- lib/rack/maintenance_mode.rb
|