activerecord-health 0.1.0 → 0.2.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/CHANGELOG.md +12 -0
- data/README.md +3 -1
- data/lib/activerecord/health/adapters/mysql_adapter.rb +12 -0
- data/lib/activerecord/health/adapters/postgresql_adapter.rb +11 -0
- data/lib/activerecord/health/railtie.rb +1 -1
- data/lib/activerecord/health/version.rb +1 -1
- data/lib/activerecord/health.rb +23 -44
- data/test/integration/mysql_integration_test.rb +1 -1
- data/test/integration/postgresql_integration_test.rb +1 -1
- data/test/integration/rails_app/config/application.rb +15 -0
- data/test/integration/rails_app/config/boot.rb +7 -0
- data/test/integration/rails_app/config/database.yml +3 -0
- data/test/integration/rails_app/config/environment.rb +5 -0
- data/test/integration/rails_app/config/fixtures/missing_cache.rb +5 -0
- data/test/integration/rails_app/config/fixtures/missing_vcpu.rb +5 -0
- data/test/integration/rails_app/config/fixtures/valid.rb +6 -0
- data/test/integration/rails_app/config/initializers/activerecord_health.rb +4 -0
- data/test/integration/rails_integration_test.rb +65 -0
- data/test/test_helper.rb +3 -35
- data/test/unit/configuration_test.rb +11 -11
- data/test/unit/extensions_test.rb +5 -5
- data/test/unit/health_test.rb +8 -8
- data/test/unit/sheddable_test.rb +5 -5
- metadata +11 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c72d2a420a64a52fd3cf223bafb4e84e4dab50b5fa807b512a322a8dc909f62d
|
|
4
|
+
data.tar.gz: 98962aa4a2527386c888791d9b123967a004175305f985068e475b4f8557e653
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c816d187880de866ee3e48fd972ea3b80543bfeba86d4a16466279a0bb45ae776f976f16f7d39dbdb68dd422f1f3fe0d92b8bf4ba2269e6c462ce6a85337b3c3
|
|
7
|
+
data.tar.gz: 291b81fb5116df82c6b310d17e7077701648e16b9eacf24cd57447f60bda87e8e0483d13b4cc3b92ba772d878566bf11a098a2a32e4bb80a84e5a357139c596c
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
|
@@ -137,7 +137,7 @@ class DatabaseHealthMiddleware
|
|
|
137
137
|
|
|
138
138
|
def call(_worker, job, _queue)
|
|
139
139
|
if THROTTLED_QUEUES.include?(job["queue"]) && !ActiveRecord::Health.ok?
|
|
140
|
-
raise
|
|
140
|
+
raise "Database unhealthy, try again later"
|
|
141
141
|
end
|
|
142
142
|
yield
|
|
143
143
|
end
|
|
@@ -150,6 +150,8 @@ Sidekiq.configure_server do |config|
|
|
|
150
150
|
end
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
+
This uses Sidekiq's [exponential backoff retries](https://github.com/sidekiq/sidekiq/wiki/Error-Handling#automatic-job-retry) to push load into the future.
|
|
154
|
+
|
|
153
155
|
## Multi-Database Support
|
|
154
156
|
|
|
155
157
|
Pass the model class that connects to your database:
|
|
@@ -8,6 +8,11 @@ module ActiveRecord
|
|
|
8
8
|
|
|
9
9
|
attr_reader :version_string
|
|
10
10
|
|
|
11
|
+
def self.build(connection)
|
|
12
|
+
version = connection.select_value("SELECT VERSION()")
|
|
13
|
+
new(version)
|
|
14
|
+
end
|
|
15
|
+
|
|
11
16
|
def initialize(version_string)
|
|
12
17
|
@version_string = version_string
|
|
13
18
|
end
|
|
@@ -24,6 +29,13 @@ module ActiveRecord
|
|
|
24
29
|
!mariadb? && mysql_version >= PERFORMANCE_SCHEMA_MIN_VERSION
|
|
25
30
|
end
|
|
26
31
|
|
|
32
|
+
def execute_with_timeout(connection, query, timeout)
|
|
33
|
+
connection.transaction do
|
|
34
|
+
connection.execute("SET max_execution_time = #{timeout * 1000}")
|
|
35
|
+
connection.select_value(query)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
27
39
|
private
|
|
28
40
|
|
|
29
41
|
def mariadb?
|
|
@@ -4,6 +4,10 @@ module ActiveRecord
|
|
|
4
4
|
module Health
|
|
5
5
|
module Adapters
|
|
6
6
|
class PostgreSQLAdapter
|
|
7
|
+
def self.build(_connection)
|
|
8
|
+
new
|
|
9
|
+
end
|
|
10
|
+
|
|
7
11
|
def name
|
|
8
12
|
:postgresql
|
|
9
13
|
end
|
|
@@ -17,6 +21,13 @@ module ActiveRecord
|
|
|
17
21
|
AND pid != pg_backend_pid()
|
|
18
22
|
SQL
|
|
19
23
|
end
|
|
24
|
+
|
|
25
|
+
def execute_with_timeout(connection, query, timeout)
|
|
26
|
+
connection.transaction do
|
|
27
|
+
connection.execute("SET LOCAL statement_timeout = '#{timeout}s'")
|
|
28
|
+
connection.select_value(query)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
20
31
|
end
|
|
21
32
|
end
|
|
22
33
|
end
|
data/lib/activerecord/health.rb
CHANGED
|
@@ -54,68 +54,47 @@ module ActiveRecord
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def read_from_cache(cache_key)
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
configuration.cache.read(cache_key) || write_to_cache(cache_key, yield)
|
|
58
|
+
rescue
|
|
59
|
+
0.0
|
|
60
|
+
end
|
|
59
61
|
|
|
60
|
-
|
|
62
|
+
def write_to_cache(cache_key, value)
|
|
61
63
|
configuration.cache.write(cache_key, value, expires_in: configuration.cache_ttl)
|
|
62
64
|
value
|
|
63
|
-
rescue
|
|
64
|
-
0.0
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def query_load_pct(model)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
config = config_for(model)
|
|
71
|
-
db_config_name = model.connection_db_config.name
|
|
72
|
-
|
|
73
|
-
active_sessions = execute_with_timeout(connection, adapter.active_session_count_query)
|
|
74
|
-
load_pct = active_sessions.to_f / config.vcpu_count
|
|
75
|
-
|
|
76
|
-
instrument(db_config_name, load_pct, active_sessions)
|
|
77
|
-
|
|
78
|
-
load_pct
|
|
68
|
+
active_sessions = fetch_active_sessions(model)
|
|
69
|
+
calculate_and_instrument_load(model, active_sessions)
|
|
79
70
|
rescue
|
|
80
71
|
1.0
|
|
81
72
|
end
|
|
82
73
|
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
case adapter_name
|
|
87
|
-
when /postgresql/
|
|
88
|
-
execute_with_postgresql_timeout(connection, query)
|
|
89
|
-
when /mysql/
|
|
90
|
-
execute_with_mysql_timeout(connection, query)
|
|
91
|
-
else
|
|
92
|
-
connection.select_value(query)
|
|
93
|
-
end
|
|
74
|
+
def fetch_active_sessions(model)
|
|
75
|
+
adapter = adapter_for(model.connection)
|
|
76
|
+
execute_with_timeout(model.connection, adapter, adapter.active_session_count_query)
|
|
94
77
|
end
|
|
95
78
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
end
|
|
79
|
+
def calculate_and_instrument_load(model, active_sessions)
|
|
80
|
+
load_pct = active_sessions.to_f / config_for(model).vcpu_count
|
|
81
|
+
instrument(model.connection_db_config.name, load_pct, active_sessions)
|
|
82
|
+
load_pct
|
|
101
83
|
end
|
|
102
84
|
|
|
103
|
-
def
|
|
104
|
-
connection
|
|
105
|
-
connection.execute("SET max_execution_time = #{QUERY_TIMEOUT * 1000}")
|
|
106
|
-
connection.select_value(query)
|
|
107
|
-
end
|
|
85
|
+
def execute_with_timeout(connection, adapter, query)
|
|
86
|
+
adapter.execute_with_timeout(connection, query, QUERY_TIMEOUT)
|
|
108
87
|
end
|
|
109
88
|
|
|
110
89
|
def adapter_for(connection)
|
|
90
|
+
adapter_class_for(connection).build(connection)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def adapter_class_for(connection)
|
|
111
94
|
case connection.adapter_name.downcase
|
|
112
|
-
when /postgresql/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
version = connection.select_value("SELECT VERSION()")
|
|
116
|
-
Adapters::MySQLAdapter.new(version)
|
|
117
|
-
else
|
|
118
|
-
raise "Unsupported database adapter: #{connection.adapter_name}"
|
|
95
|
+
when /postgresql/ then Adapters::PostgreSQLAdapter
|
|
96
|
+
when /mysql/ then Adapters::MySQLAdapter
|
|
97
|
+
else raise "Unsupported database adapter: #{connection.adapter_name}"
|
|
119
98
|
end
|
|
120
99
|
end
|
|
121
100
|
|
|
@@ -17,7 +17,7 @@ class MySQLIntegrationTest < ActiveRecord::Health::TestCase
|
|
|
17
17
|
database: ENV.fetch("MYSQL_DB", "activerecord_health_test")
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
-
@cache =
|
|
20
|
+
@cache = ActiveSupport::Cache::MemoryStore.new
|
|
21
21
|
@baseline_sessions = count_active_sessions
|
|
22
22
|
ActiveRecord::Health.configure do |config|
|
|
23
23
|
config.vcpu_count = @baseline_sessions + 4
|
|
@@ -17,7 +17,7 @@ class PostgreSQLIntegrationTest < ActiveRecord::Health::TestCase
|
|
|
17
17
|
database: ENV.fetch("POSTGRES_DB", "activerecord_health_test")
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
-
@cache =
|
|
20
|
+
@cache = ActiveSupport::Cache::MemoryStore.new
|
|
21
21
|
@baseline_sessions = count_active_sessions
|
|
22
22
|
ActiveRecord::Health.configure do |config|
|
|
23
23
|
config.vcpu_count = @baseline_sessions + 4
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "boot"
|
|
4
|
+
|
|
5
|
+
require "rails"
|
|
6
|
+
require "active_record/railtie"
|
|
7
|
+
require "activerecord/health"
|
|
8
|
+
|
|
9
|
+
module RailsApp
|
|
10
|
+
class Application < Rails::Application
|
|
11
|
+
config.load_defaults Rails::VERSION::STRING.to_f
|
|
12
|
+
config.eager_load = false
|
|
13
|
+
config.logger = Logger.new(nil)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Set up gems listed in the Gemfile.
|
|
4
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", __dir__)
|
|
5
|
+
|
|
6
|
+
require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
|
|
7
|
+
$LOAD_PATH.unshift File.expand_path("../../../../lib", __dir__)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
require "open3"
|
|
5
|
+
|
|
6
|
+
class RailsIntegrationTest < Minitest::Test
|
|
7
|
+
def test_boots_successfully_with_valid_initializer_configuration
|
|
8
|
+
output, status = run_rails_runner("puts ActiveRecord::Health.configuration.vcpu_count")
|
|
9
|
+
|
|
10
|
+
assert status.success?, "Expected success but got: #{output}"
|
|
11
|
+
assert_equal "4", output.strip
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_configuration_from_initializer_is_applied
|
|
15
|
+
output, status = run_rails_runner(<<~RUBY)
|
|
16
|
+
puts ActiveRecord::Health.configuration.vcpu_count
|
|
17
|
+
puts ActiveRecord::Health.configuration.cache.class.name
|
|
18
|
+
RUBY
|
|
19
|
+
|
|
20
|
+
assert status.success?, "Expected success but got: #{output}"
|
|
21
|
+
lines = output.strip.split("\n")
|
|
22
|
+
assert_equal "4", lines[0]
|
|
23
|
+
assert_equal "ActiveSupport::Cache::MemoryStore", lines[1]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_raises_configuration_error_when_vcpu_count_missing
|
|
27
|
+
output, status = run_rails_runner("puts 'ok'", fixture: "missing_vcpu")
|
|
28
|
+
|
|
29
|
+
refute status.success?
|
|
30
|
+
assert_match(/vcpu_count must be configured/, output)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_raises_configuration_error_when_cache_missing
|
|
34
|
+
output, status = run_rails_runner("puts 'ok'", fixture: "missing_cache")
|
|
35
|
+
|
|
36
|
+
refute status.success?
|
|
37
|
+
assert_match(/cache must be configured/, output)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_configuration_defaults_are_preserved
|
|
41
|
+
output, status = run_rails_runner(<<~RUBY)
|
|
42
|
+
puts ActiveRecord::Health.configuration.threshold
|
|
43
|
+
puts ActiveRecord::Health.configuration.cache_ttl
|
|
44
|
+
RUBY
|
|
45
|
+
|
|
46
|
+
assert status.success?, "Expected success but got: #{output}"
|
|
47
|
+
lines = output.strip.split("\n")
|
|
48
|
+
assert_equal "0.75", lines[0]
|
|
49
|
+
assert_equal "60", lines[1]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def run_rails_runner(code, fixture: "valid")
|
|
55
|
+
rails_app_path = File.expand_path("rails_app", __dir__)
|
|
56
|
+
|
|
57
|
+
env = {
|
|
58
|
+
"BUNDLE_GEMFILE" => File.expand_path("../../Gemfile", __dir__),
|
|
59
|
+
"HEALTH_CONFIG_FIXTURE" => fixture
|
|
60
|
+
}
|
|
61
|
+
cmd = "bundle exec ruby -e \"require '#{rails_app_path}/config/environment'; #{code.gsub('"', '\\"').gsub("\n", "; ")}\""
|
|
62
|
+
|
|
63
|
+
Open3.capture2e(env, cmd, chdir: rails_app_path)
|
|
64
|
+
end
|
|
65
|
+
end
|
data/test/test_helper.rb
CHANGED
|
@@ -14,19 +14,9 @@ require "minitest/reporters"
|
|
|
14
14
|
Minitest::Reporters.use! Minitest::Reporters::DefaultReporter.new
|
|
15
15
|
|
|
16
16
|
if ENV["FAIL_ON_SKIP"]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def run(args = [])
|
|
22
|
-
result = original_run(args)
|
|
23
|
-
reporter = Minitest::Reporters.reporters.first
|
|
24
|
-
if reporter && reporter.skips > 0
|
|
25
|
-
warn "\nCI failed: #{reporter.skips} tests were skipped"
|
|
26
|
-
exit 1
|
|
27
|
-
end
|
|
28
|
-
result
|
|
29
|
-
end
|
|
17
|
+
class Minitest::Test
|
|
18
|
+
def skip(msg = nil, _bt = caller)
|
|
19
|
+
flunk(msg || "Test was skipped")
|
|
30
20
|
end
|
|
31
21
|
end
|
|
32
22
|
end
|
|
@@ -41,28 +31,6 @@ class ActiveRecord::Health::TestCase < Minitest::Test
|
|
|
41
31
|
end
|
|
42
32
|
end
|
|
43
33
|
|
|
44
|
-
class MockCache
|
|
45
|
-
def initialize
|
|
46
|
-
@store = {}
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def read(key)
|
|
50
|
-
@store[key]
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def write(key, value, options = {})
|
|
54
|
-
@store[key] = value
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def delete(key)
|
|
58
|
-
@store.delete(key)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def clear
|
|
62
|
-
@store.clear
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
34
|
class FailingCache
|
|
67
35
|
def read(key)
|
|
68
36
|
raise "Cache connection failed"
|
|
@@ -6,7 +6,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
6
6
|
def test_configure_sets_vcpu_count
|
|
7
7
|
ActiveRecord::Health.configure do |config|
|
|
8
8
|
config.vcpu_count = 16
|
|
9
|
-
config.cache =
|
|
9
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
assert_equal 16, ActiveRecord::Health.configuration.vcpu_count
|
|
@@ -15,7 +15,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
15
15
|
def test_configure_sets_threshold_with_default
|
|
16
16
|
ActiveRecord::Health.configure do |config|
|
|
17
17
|
config.vcpu_count = 16
|
|
18
|
-
config.cache =
|
|
18
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
assert_equal 0.75, ActiveRecord::Health.configuration.threshold
|
|
@@ -25,14 +25,14 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
25
25
|
ActiveRecord::Health.configure do |config|
|
|
26
26
|
config.vcpu_count = 16
|
|
27
27
|
config.threshold = 0.5
|
|
28
|
-
config.cache =
|
|
28
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
assert_equal 0.5, ActiveRecord::Health.configuration.threshold
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def test_configure_sets_cache
|
|
35
|
-
cache =
|
|
35
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
36
36
|
ActiveRecord::Health.configure do |config|
|
|
37
37
|
config.vcpu_count = 16
|
|
38
38
|
config.cache = cache
|
|
@@ -44,7 +44,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
44
44
|
def test_configure_sets_cache_ttl_with_default
|
|
45
45
|
ActiveRecord::Health.configure do |config|
|
|
46
46
|
config.vcpu_count = 16
|
|
47
|
-
config.cache =
|
|
47
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
assert_equal 60, ActiveRecord::Health.configuration.cache_ttl
|
|
@@ -53,7 +53,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
53
53
|
def test_configure_sets_custom_cache_ttl
|
|
54
54
|
ActiveRecord::Health.configure do |config|
|
|
55
55
|
config.vcpu_count = 16
|
|
56
|
-
config.cache =
|
|
56
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
57
57
|
config.cache_ttl = 120
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -62,7 +62,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
62
62
|
|
|
63
63
|
def test_raises_without_vcpu_count
|
|
64
64
|
ActiveRecord::Health.configure do |config|
|
|
65
|
-
config.cache =
|
|
65
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
error = assert_raises(ActiveRecord::Health::ConfigurationError) do
|
|
@@ -85,7 +85,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
85
85
|
def test_for_model_configures_specific_database
|
|
86
86
|
ActiveRecord::Health.configure do |config|
|
|
87
87
|
config.vcpu_count = 16
|
|
88
|
-
config.cache =
|
|
88
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
89
89
|
|
|
90
90
|
config.for_model(AnimalsRecord) do |db|
|
|
91
91
|
db.vcpu_count = 8
|
|
@@ -99,7 +99,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
def test_for_model_inherits_cache_from_default
|
|
102
|
-
cache =
|
|
102
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
103
103
|
ActiveRecord::Health.configure do |config|
|
|
104
104
|
config.vcpu_count = 16
|
|
105
105
|
config.cache = cache
|
|
@@ -115,7 +115,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
115
115
|
def test_for_model_inherits_threshold_from_default_when_not_specified
|
|
116
116
|
ActiveRecord::Health.configure do |config|
|
|
117
117
|
config.vcpu_count = 16
|
|
118
|
-
config.cache =
|
|
118
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
119
119
|
|
|
120
120
|
config.for_model(AnimalsRecord) do |db|
|
|
121
121
|
db.vcpu_count = 8
|
|
@@ -129,7 +129,7 @@ class ConfigurationTest < ActiveRecord::Health::TestCase
|
|
|
129
129
|
ActiveRecord::Health.configure do |config|
|
|
130
130
|
config.vcpu_count = 16
|
|
131
131
|
config.threshold = 0.75
|
|
132
|
-
config.cache =
|
|
132
|
+
config.cache = ActiveSupport::Cache::MemoryStore.new
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
assert_equal 12, ActiveRecord::Health.configuration.max_healthy_sessions
|
|
@@ -5,7 +5,7 @@ require "activerecord/health/extensions"
|
|
|
5
5
|
|
|
6
6
|
class ConnectionExtensionTest < ActiveRecord::Health::TestCase
|
|
7
7
|
def test_healthy_returns_true_when_below_threshold
|
|
8
|
-
cache =
|
|
8
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
9
9
|
cache.write("activerecord_health:load_pct:primary", 0.5)
|
|
10
10
|
|
|
11
11
|
ActiveRecord::Health.configure do |config|
|
|
@@ -19,7 +19,7 @@ class ConnectionExtensionTest < ActiveRecord::Health::TestCase
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def test_healthy_returns_false_when_above_threshold
|
|
22
|
-
cache =
|
|
22
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
23
23
|
cache.write("activerecord_health:load_pct:primary", 0.9)
|
|
24
24
|
|
|
25
25
|
ActiveRecord::Health.configure do |config|
|
|
@@ -33,7 +33,7 @@ class ConnectionExtensionTest < ActiveRecord::Health::TestCase
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def test_load_pct_returns_cached_value
|
|
36
|
-
cache =
|
|
36
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
37
37
|
cache.write("activerecord_health:load_pct:primary", 0.625)
|
|
38
38
|
|
|
39
39
|
ActiveRecord::Health.configure do |config|
|
|
@@ -48,7 +48,7 @@ end
|
|
|
48
48
|
|
|
49
49
|
class ModelExtensionTest < ActiveRecord::Health::TestCase
|
|
50
50
|
def test_database_healthy_returns_true_when_below_threshold
|
|
51
|
-
cache =
|
|
51
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
52
52
|
cache.write("activerecord_health:load_pct:primary", 0.5)
|
|
53
53
|
|
|
54
54
|
ActiveRecord::Health.configure do |config|
|
|
@@ -61,7 +61,7 @@ class ModelExtensionTest < ActiveRecord::Health::TestCase
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def test_database_healthy_returns_false_when_above_threshold
|
|
64
|
-
cache =
|
|
64
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
65
65
|
cache.write("activerecord_health:load_pct:primary", 0.9)
|
|
66
66
|
|
|
67
67
|
ActiveRecord::Health.configure do |config|
|
data/test/unit/health_test.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "test_helper"
|
|
|
4
4
|
|
|
5
5
|
class HealthTest < ActiveRecord::Health::TestCase
|
|
6
6
|
def test_ok_returns_true_when_load_below_threshold
|
|
7
|
-
cache =
|
|
7
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
8
8
|
cache.write("activerecord_health:load_pct:primary", 0.5)
|
|
9
9
|
|
|
10
10
|
ActiveRecord::Health.configure do |config|
|
|
@@ -18,7 +18,7 @@ class HealthTest < ActiveRecord::Health::TestCase
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def test_ok_returns_false_when_load_above_threshold
|
|
21
|
-
cache =
|
|
21
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
22
22
|
cache.write("activerecord_health:load_pct:primary", 0.9)
|
|
23
23
|
|
|
24
24
|
ActiveRecord::Health.configure do |config|
|
|
@@ -32,7 +32,7 @@ class HealthTest < ActiveRecord::Health::TestCase
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def test_ok_returns_true_when_load_equals_threshold
|
|
35
|
-
cache =
|
|
35
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
36
36
|
cache.write("activerecord_health:load_pct:primary", 0.75)
|
|
37
37
|
|
|
38
38
|
ActiveRecord::Health.configure do |config|
|
|
@@ -56,7 +56,7 @@ class HealthTest < ActiveRecord::Health::TestCase
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def test_load_pct_returns_cached_value
|
|
59
|
-
cache =
|
|
59
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
60
60
|
cache.write("activerecord_health:load_pct:primary", 0.625)
|
|
61
61
|
|
|
62
62
|
ActiveRecord::Health.configure do |config|
|
|
@@ -79,7 +79,7 @@ class HealthTest < ActiveRecord::Health::TestCase
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def test_load_pct_queries_database_when_not_cached
|
|
82
|
-
cache =
|
|
82
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
83
83
|
|
|
84
84
|
ActiveRecord::Health.configure do |config|
|
|
85
85
|
config.vcpu_count = 16
|
|
@@ -94,7 +94,7 @@ class HealthTest < ActiveRecord::Health::TestCase
|
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
def test_load_pct_returns_1_0_when_database_query_fails
|
|
97
|
-
cache =
|
|
97
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
98
98
|
|
|
99
99
|
ActiveRecord::Health.configure do |config|
|
|
100
100
|
config.vcpu_count = 16
|
|
@@ -108,7 +108,7 @@ class HealthTest < ActiveRecord::Health::TestCase
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def test_ok_returns_false_when_database_query_fails
|
|
111
|
-
cache =
|
|
111
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
112
112
|
|
|
113
113
|
ActiveRecord::Health.configure do |config|
|
|
114
114
|
config.vcpu_count = 16
|
|
@@ -123,7 +123,7 @@ class HealthTest < ActiveRecord::Health::TestCase
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def test_uses_per_model_configuration
|
|
126
|
-
cache =
|
|
126
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
127
127
|
cache.write("activerecord_health:load_pct:animals", 0.6)
|
|
128
128
|
|
|
129
129
|
ActiveRecord::Health.configure do |config|
|
data/test/unit/sheddable_test.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "test_helper"
|
|
|
4
4
|
|
|
5
5
|
class SheddableTest < ActiveRecord::Health::TestCase
|
|
6
6
|
def test_sheddable_executes_block_and_returns_true_when_healthy
|
|
7
|
-
cache =
|
|
7
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
8
8
|
cache.write("activerecord_health:load_pct:primary", 0.5)
|
|
9
9
|
|
|
10
10
|
ActiveRecord::Health.configure do |config|
|
|
@@ -22,7 +22,7 @@ class SheddableTest < ActiveRecord::Health::TestCase
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def test_sheddable_returns_false_and_skips_block_when_overloaded
|
|
25
|
-
cache =
|
|
25
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
26
26
|
cache.write("activerecord_health:load_pct:primary", 0.9)
|
|
27
27
|
|
|
28
28
|
ActiveRecord::Health.configure do |config|
|
|
@@ -40,7 +40,7 @@ class SheddableTest < ActiveRecord::Health::TestCase
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def test_sheddable_pct_executes_block_and_returns_true_when_below_threshold
|
|
43
|
-
cache =
|
|
43
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
44
44
|
cache.write("activerecord_health:load_pct:primary", 0.4)
|
|
45
45
|
|
|
46
46
|
ActiveRecord::Health.configure do |config|
|
|
@@ -57,7 +57,7 @@ class SheddableTest < ActiveRecord::Health::TestCase
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def test_sheddable_pct_returns_false_and_skips_block_when_above_threshold
|
|
60
|
-
cache =
|
|
60
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
61
61
|
cache.write("activerecord_health:load_pct:primary", 0.6)
|
|
62
62
|
|
|
63
63
|
ActiveRecord::Health.configure do |config|
|
|
@@ -74,7 +74,7 @@ class SheddableTest < ActiveRecord::Health::TestCase
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def test_sheddable_pct_executes_block_and_returns_true_when_at_threshold
|
|
77
|
-
cache =
|
|
77
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
|
78
78
|
cache.write("activerecord_health:load_pct:primary", 0.5)
|
|
79
79
|
|
|
80
80
|
ActiveRecord::Health.configure do |config|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-health
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nate Berkopec
|
|
@@ -45,6 +45,7 @@ executables: []
|
|
|
45
45
|
extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
|
47
47
|
files:
|
|
48
|
+
- CHANGELOG.md
|
|
48
49
|
- CONTRIBUTING.md
|
|
49
50
|
- LICENSE.txt
|
|
50
51
|
- README.md
|
|
@@ -60,6 +61,15 @@ files:
|
|
|
60
61
|
- lib/activerecord/health/version.rb
|
|
61
62
|
- test/integration/mysql_integration_test.rb
|
|
62
63
|
- test/integration/postgresql_integration_test.rb
|
|
64
|
+
- test/integration/rails_app/config/application.rb
|
|
65
|
+
- test/integration/rails_app/config/boot.rb
|
|
66
|
+
- test/integration/rails_app/config/database.yml
|
|
67
|
+
- test/integration/rails_app/config/environment.rb
|
|
68
|
+
- test/integration/rails_app/config/fixtures/missing_cache.rb
|
|
69
|
+
- test/integration/rails_app/config/fixtures/missing_vcpu.rb
|
|
70
|
+
- test/integration/rails_app/config/fixtures/valid.rb
|
|
71
|
+
- test/integration/rails_app/config/initializers/activerecord_health.rb
|
|
72
|
+
- test/integration/rails_integration_test.rb
|
|
63
73
|
- test/test_helper.rb
|
|
64
74
|
- test/unit/adapters/mysql_adapter_test.rb
|
|
65
75
|
- test/unit/adapters/postgresql_adapter_test.rb
|