read-only-mode 0.1.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/README.md +42 -0
- data/lib/middleware.rb +28 -0
- data/lib/railtie.rb +9 -0
- data/lib/read-only-mode.html +14 -0
- data/lib/read-only-mode.rb +31 -0
- data/read-only-mode.gemspec +17 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 789458ccf4c3a3659e0f5ff50b69f5ce25dec31eedf1d6828b58b57bbb14c3eb
|
4
|
+
data.tar.gz: 33b10e31a9daf2d6a5d02ff77672781adb199571149d44b0ad3c7f3327bca895
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05e8f74a2c93cbf9e4c907e80b24c4c2f81644adf166642d419f77d27fb765595c2fc22a8009b32e3eaf841adba5e0eefef0ce0e6ae0e3942f699862c64f57ae
|
7
|
+
data.tar.gz: c8dcc9577f73b9652f77f7dd9efe348926dca038b71eaad7a56fc988b8af23fe0342157f73f166148f79b92299c47e766856f177388992461217e0e1aa14f9e6
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Read Only Mode
|
2
|
+
|
3
|
+
A simple ruby gem for adding read only maintenance mode to your Rails / Rack applications.
|
4
|
+
|
5
|
+
When read only mode is enabled, all non GET / HEAD requests will be rejected with a 503 Service Unavailable response. Additionally the 503 response will be given in case a GET request would raise a `PG::ReadOnlySqlTransaction` error.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add the line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem "read_only_mode"
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
Read only mode is enabled via environment variables. There are two options, either:
|
18
|
+
|
19
|
+
Set `READ_ONLY_MODE=true`
|
20
|
+
|
21
|
+
Or...
|
22
|
+
|
23
|
+
Set `PGOPTIONS="-c default_transaction_read_only=on"` (or any other string containing `default_transaction_read_only=on`).
|
24
|
+
|
25
|
+
The `PGOPTIONS` approach is recommended for applications using Postgres as this will prevent any write queries from being executed.
|
26
|
+
|
27
|
+
### Rack integration
|
28
|
+
|
29
|
+
Rails applications will automatically use the middleware via a Railtie. For other Rack applications, you can add the middleware manually:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
use ReadOnlyMode::Middleware if ReadOnlyMode.enabled?
|
33
|
+
```
|
34
|
+
|
35
|
+
## Configuration
|
36
|
+
|
37
|
+
You can customize the HTML / JSON responses returned when read only mode is enabled via some simple setters:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
ReadOnlyMode.html_response = File.read("path/to/your/read_only.html")
|
41
|
+
ReadOnlyMode.json_response = { error: "Maintenance in progress" }.to_json
|
42
|
+
```
|
data/lib/middleware.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module ReadOnlyMode
|
2
|
+
class Middleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
if env["REQUEST_METHOD"] == "GET" || env["REQUEST_METHOD"] == "HEAD"
|
9
|
+
@app.call(env)
|
10
|
+
else
|
11
|
+
render_503(env)
|
12
|
+
end
|
13
|
+
rescue PG::ReadOnlySqlTransaction
|
14
|
+
render_503(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# 503 Service Unavailable with HTML or JSON depending on accept header
|
20
|
+
def render_503(env)
|
21
|
+
if env["HTTP_ACCEPT"] == "application/json"
|
22
|
+
[503, { "content-type" => "application/json; charset=utf-8" }, [ReadOnlyMode.json_response]]
|
23
|
+
else
|
24
|
+
[503, { "content-type" => "text/html; charset=utf-8" }, [ReadOnlyMode.html_response]]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/railtie.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Read-only maintenance in progress</title>
|
5
|
+
</head>
|
6
|
+
<body style="height: 100vh; background: linear-gradient(198deg, rgba(242,242,242,1) 0%, rgba(239,251,255,1) 100%); font-family: sans-serif; text-align: center;">
|
7
|
+
<div style="display: flex; height: 100vh">
|
8
|
+
<div style="margin: auto; height: 250px;">
|
9
|
+
<h1 style="font-weight: 200; color: #2c3647">Maintenance in progress</h1>
|
10
|
+
<p style="line-height: 1.8rem; color: #555a64">This app is undergoing maintenance right now.<br>Some actions are unavailable.<br>Please check back later 🙏</p>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module ReadOnlyMode
|
6
|
+
DEFALT_HTML_RESPONSE = File.read(File.expand_path("read-only-mode.html", __dir__))
|
7
|
+
DEFAULT_JSON_RESPONSE = { error: "Application is in read-only maintenance mode. Please try again later." }.to_json
|
8
|
+
|
9
|
+
def self.enabled?
|
10
|
+
ENV["READ_ONLY_MODE"] == "true" || ENV["PGOPTIONS"]&.include?("default_transaction_read_only=on")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.html_response=(html_response)
|
14
|
+
@html_response = html_response
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.html_response
|
18
|
+
@html_response ||= DEFALT_HTML_RESPONSE
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.json_response=(json_response)
|
22
|
+
@json_response = json_response
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.json_response
|
26
|
+
@json_response ||= DEFAULT_JSON_RESPONSE
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require_relative "middleware"
|
31
|
+
require_relative "railtie" if defined? Rails::Railtie
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "read-only-mode"
|
3
|
+
spec.version = "0.1.0"
|
4
|
+
spec.authors = ["David Backeus"]
|
5
|
+
spec.email = ["david.backeus@mynewsdesk.com"]
|
6
|
+
spec.summary = "Simple read-only maintenance mode for Rails and Rack based web applications"
|
7
|
+
spec.homepage = "https://github.com/reclaim-the-stack/read-only-mode"
|
8
|
+
spec.license = "MIT"
|
9
|
+
spec.metadata = {
|
10
|
+
"homepage_uri" => spec.homepage,
|
11
|
+
"source_code_uri" => spec.homepage,
|
12
|
+
"changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md"
|
13
|
+
}
|
14
|
+
spec.files = %w[README.md CHANGELOG.md read-only-mode.gemspec] + Dir["lib/**/*"]
|
15
|
+
|
16
|
+
spec.required_ruby_version = ">= 2.7.0"
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: read-only-mode
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Backeus
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-02-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- david.backeus@mynewsdesk.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- CHANGELOG.md
|
21
|
+
- README.md
|
22
|
+
- lib/middleware.rb
|
23
|
+
- lib/railtie.rb
|
24
|
+
- lib/read-only-mode.html
|
25
|
+
- lib/read-only-mode.rb
|
26
|
+
- read-only-mode.gemspec
|
27
|
+
homepage: https://github.com/reclaim-the-stack/read-only-mode
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata:
|
31
|
+
homepage_uri: https://github.com/reclaim-the-stack/read-only-mode
|
32
|
+
source_code_uri: https://github.com/reclaim-the-stack/read-only-mode
|
33
|
+
changelog_uri: https://github.com/reclaim-the-stack/read-only-mode/blob/master/CHANGELOG.md
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 2.7.0
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubygems_version: 3.5.0.dev
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: Simple read-only maintenance mode for Rails and Rack based web applications
|
53
|
+
test_files: []
|