fly-ruby 0.3.0 → 0.4.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 +4 -4
- data/.gitignore +1 -0
- data/README.md +3 -3
- data/lib/fly-ruby/configuration.rb +21 -3
- data/lib/fly-ruby/headers.rb +16 -0
- data/lib/fly-ruby/railtie.rb +6 -13
- data/lib/fly-ruby/regional_database.rb +6 -3
- data/lib/fly-ruby/version.rb +3 -1
- data/lib/fly-ruby.rb +4 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea1ca64bcd11ed8a60774f0d8ec255ffb49bc6b8e21a8bd32e7410068bec35c0
|
4
|
+
data.tar.gz: fb55ad6c98cb631bf202aea206c53a9b2e9a7c738cd9835095dd647011cfc7f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c3df04f8bb9f97bfb87903b0fffc14ef2b320802e1183752c07f8b769b629f6c66af21ae0e4bb5a23a2608cfdfdda2f3b1c387e3edcd1f64b5d2474a79f7a6f
|
7
|
+
data.tar.gz: ff4ca7c18d4b18ec237c8e1c59bce88dce849198934ed1d42c28ab2a081b577f8fa2cc38930d0478ec94a5bee580e2f12649b38d3ad46d176a774edaba60446c
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
[](https://github.com/superfly/fly-ruby/actions/workflows/test.yml)
|
2
2
|
|
3
|
-
This gem contains helper code and Rack middleware for deploying Ruby web apps on [Fly.io](https://fly.io).
|
3
|
+
This gem contains helper code and Rack middleware for deploying Ruby web apps on [Fly.io](https://fly.io). It's designed to speed up apps by using region-local Postgresql replicas for database reads. See the blog post for more details:
|
4
4
|
|
5
|
-
|
5
|
+
https://fly.io/blog/run-ordinary-rails-apps-globally
|
6
6
|
|
7
7
|
## Speed up apps using region-local database replicas
|
8
8
|
|
@@ -49,7 +49,7 @@ Fly.configure do |c|
|
|
49
49
|
end
|
50
50
|
```
|
51
51
|
|
52
|
-
See [the source code](https://github.com/
|
52
|
+
See [the source code](https://github.com/superfly/fly-ruby/blob/main/lib/fly-ruby/configuration.rb) for defaults and available configuration options.
|
53
53
|
## Known issues
|
54
54
|
|
55
55
|
This middleware send all requests to the primary if you do something like update a user's database session on every GET request.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fly
|
2
4
|
class Configuration
|
3
5
|
# Set the region where this instance of the application is deployed
|
@@ -28,6 +30,9 @@ module Fly
|
|
28
30
|
attr_accessor :database_url
|
29
31
|
attr_accessor :redis_url
|
30
32
|
|
33
|
+
# An array of string representations of exceptions that should trigger a replay
|
34
|
+
attr_accessor :replayable_exceptions
|
35
|
+
|
31
36
|
def initialize
|
32
37
|
self.primary_region = ENV["PRIMARY_REGION"]
|
33
38
|
self.current_region = ENV["FLY_REGION"]
|
@@ -40,6 +45,19 @@ module Fly
|
|
40
45
|
self.replay_threshold_in_seconds = 5
|
41
46
|
self.database_url = ENV[database_url_env_var]
|
42
47
|
self.redis_url = ENV[redis_url_env_var]
|
48
|
+
self.replayable_exceptions = ["SQLite3::CantOpenException", "PG::ReadOnlySqlTransaction"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def replayable_exception_classes
|
52
|
+
@replayable_exception_classes ||= replayable_exceptions.collect {|ex| module_exists?(ex) }.compact
|
53
|
+
@replayable_exception_classes
|
54
|
+
end
|
55
|
+
|
56
|
+
def module_exists?(module_name)
|
57
|
+
mod = Module.const_get(module_name)
|
58
|
+
return mod
|
59
|
+
rescue NameError
|
60
|
+
nil
|
43
61
|
end
|
44
62
|
|
45
63
|
def database_uri
|
@@ -60,9 +78,9 @@ module Fly
|
|
60
78
|
# Rails-compatible database configuration
|
61
79
|
def regional_database_config
|
62
80
|
{
|
63
|
-
|
64
|
-
|
65
|
-
|
81
|
+
:host => regional_database_host,
|
82
|
+
:port => 5433,
|
83
|
+
:adapter => "postgresql"
|
66
84
|
}
|
67
85
|
end
|
68
86
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fly
|
4
|
+
class Headers
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
status, headers, body = @app.call(env)
|
11
|
+
response = Rack::Response.new(body, status, headers)
|
12
|
+
response.set_header('Fly-Region', ENV['FLY_REGION'])
|
13
|
+
response.finish
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/fly-ruby/railtie.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Fly::Railtie < Rails::Railtie
|
2
4
|
def hijack_database_connection
|
3
5
|
ActiveSupport::Reloader.to_prepare do
|
@@ -6,26 +8,17 @@ class Fly::Railtie < Rails::Railtie
|
|
6
8
|
# hooks for forking servers to work correctly.
|
7
9
|
if defined?(ActiveRecord)
|
8
10
|
config = ActiveRecord::Base.connection_db_config.configuration_hash
|
9
|
-
ActiveRecord::Base.establish_connection(config.merge(Fly.configuration.regional_database_config))
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Set useful headers for debugging
|
15
|
-
def set_debug_response_headers
|
16
|
-
ActiveSupport::Reloader.to_prepare do
|
17
|
-
ApplicationController.send(:after_action) do
|
18
|
-
response.headers['Fly-Region'] = ENV['FLY_REGION']
|
11
|
+
ActiveRecord::Base.establish_connection(config.symbolize_keys.merge(Fly.configuration.regional_database_config))
|
19
12
|
end
|
20
13
|
end
|
21
14
|
end
|
22
15
|
|
23
16
|
initializer("fly.regional_database") do |app|
|
24
|
-
|
17
|
+
# Insert the request middleware high in the stack, but after static file delivery
|
18
|
+
app.config.middleware.insert_after ActionDispatch::Executor, Fly::Headers if Fly.configuration.web?
|
25
19
|
|
26
20
|
if Fly.configuration.eligible_for_activation?
|
27
|
-
|
28
|
-
app.config.middleware.insert_after ActionDispatch::Executor, Fly::RegionalDatabase::ReplayableRequestMiddleware
|
21
|
+
app.config.middleware.insert_after Fly::Headers, Fly::RegionalDatabase::ReplayableRequestMiddleware
|
29
22
|
# Insert the database exception handler at the bottom of the stack to take priority over other exception handlers
|
30
23
|
app.config.middleware.use Fly::RegionalDatabase::DbExceptionHandlerMiddleware
|
31
24
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rake'
|
2
4
|
|
3
5
|
module Fly
|
@@ -29,9 +31,10 @@ module Fly
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def call(env)
|
34
|
+
exceptions = Fly.configuration.replayable_exception_classes
|
32
35
|
@app.call(env)
|
33
|
-
rescue
|
34
|
-
if e.is_a?(
|
36
|
+
rescue *exceptions, ActiveRecord::RecordInvalid => e
|
37
|
+
if exceptions.any? {|ex| e.is_a?(ex) } || exceptions.any? { e&.cause&.is_a?(e) }
|
35
38
|
RegionalDatabase.replay_in_primary_region!(state: "captured_write")
|
36
39
|
else
|
37
40
|
raise e
|
@@ -53,7 +56,7 @@ module Fly
|
|
53
56
|
end
|
54
57
|
|
55
58
|
def replay_request_state(header_value)
|
56
|
-
header_value&.
|
59
|
+
header_value&.slice(/(?:^|;)state=([^;]*)/, 1)
|
57
60
|
end
|
58
61
|
|
59
62
|
def call(env)
|
data/lib/fly-ruby/version.rb
CHANGED
data/lib/fly-ruby.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fly-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Sierles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- fly-ruby.gemspec
|
42
42
|
- lib/fly-ruby.rb
|
43
43
|
- lib/fly-ruby/configuration.rb
|
44
|
+
- lib/fly-ruby/headers.rb
|
44
45
|
- lib/fly-ruby/railtie.rb
|
45
46
|
- lib/fly-ruby/regional_database.rb
|
46
47
|
- lib/fly-ruby/version.rb
|
@@ -63,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
64
|
- !ruby/object:Gem::Version
|
64
65
|
version: '0'
|
65
66
|
requirements: []
|
66
|
-
rubygems_version: 3.2.
|
67
|
+
rubygems_version: 3.2.26
|
67
68
|
signing_key:
|
68
69
|
specification_version: 4
|
69
70
|
summary: Augment Ruby web apps for deployment in Fly.io
|