activerecord_connection_reaper 0.2.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/Rakefile +8 -4
- data/lib/activerecord_connection_reaper/extensions/active_record/connection_adapters/abstract_adapter_track_connected_since.rb +2 -2
- data/lib/activerecord_connection_reaper/extensions/active_record/connection_adapters/pool_max_age.rb +4 -0
- data/lib/activerecord_connection_reaper/extensions/active_record/connection_adapters/reaper_check_max_age.rb +53 -12
- data/lib/activerecord_connection_reaper/railtie.rb +3 -3
- data/lib/activerecord_connection_reaper/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cde5ce57597f3080ebda91544487f81477143a38d99355e4eb8ee4e70d0b75e3
|
|
4
|
+
data.tar.gz: 23d8417049ec5aa708458063d2227ef7825a62f8e54b44c64f9b083ab5f1280e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ebaff298730cb4acbeaff6adf2e92fb6ed31471ba178e5b50ffeff410a6cb92bcec683d1bed824ec143dd550897825eecea8f280b2f34565cf00e4d989ff1409
|
|
7
|
+
data.tar.gz: f30372920b56840936cb5cb4bdfc29360fde15421480605ec6cbec4c2cfb5eaa74e495dad983d1bfa37cbf72b3b2e522a663ae6b8e7b48a6c43e63341713a740
|
data/Rakefile
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'bundler/gem_tasks'
|
|
4
|
-
require '
|
|
5
|
-
|
|
6
|
-
Minitest::TestTask.create # rubocop:disable Rails/SaveBang
|
|
7
|
-
|
|
4
|
+
require 'rake/testtask'
|
|
8
5
|
require 'rubocop/rake_task'
|
|
9
6
|
|
|
10
7
|
RuboCop::RakeTask.new
|
|
11
8
|
|
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
|
10
|
+
t.libs << 'test'
|
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
|
12
|
+
t.verbose = false
|
|
13
|
+
t.warning = false
|
|
14
|
+
end
|
|
15
|
+
|
|
12
16
|
task static: :rubocop
|
|
13
17
|
task default: %i[static test]
|
|
@@ -23,9 +23,9 @@ module ActiveRecordConnectionReaper
|
|
|
23
23
|
duration * (1.0 - @pool_jitter)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
MAX_JITTER =
|
|
26
|
+
MAX_JITTER = 1.0
|
|
27
27
|
def max_jitter
|
|
28
|
-
(@config[:pool_jitter] || 0.2).to_f.clamp(MAX_JITTER)
|
|
28
|
+
(@config[:pool_jitter] || 0.2).to_f.clamp(0.0, MAX_JITTER)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
end
|
|
@@ -1,24 +1,65 @@
|
|
|
1
|
+
require 'weakref'
|
|
2
|
+
|
|
1
3
|
module ActiveRecordConnectionReaper
|
|
2
4
|
module Extensions
|
|
3
5
|
module ActiveRecord
|
|
4
6
|
module ConnectionAdapters
|
|
5
7
|
module ReaperCheckMaxAge
|
|
6
|
-
def
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def self.prepended(base)
|
|
9
|
+
base.instance_variable_set(:@mutex, Mutex.new) if base.instance_variable_get(:@mutex).nil?
|
|
10
|
+
base.instance_variable_set(:@pools, {}) if base.instance_variable_get(:@pools).nil?
|
|
11
|
+
base.instance_variable_set(:@threads, {}) if base.instance_variable_get(:@threads).nil?
|
|
12
|
+
|
|
13
|
+
base.singleton_class.send(:prepend, ClassMethods)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module ClassMethods
|
|
17
|
+
def __patched_register_pool(pool, frequency) # :nodoc:
|
|
18
|
+
@mutex.synchronize do
|
|
19
|
+
@threads[frequency] = __patched_spawn_thread(frequency) unless @threads[frequency]&.alive?
|
|
20
|
+
@pools[frequency] ||= []
|
|
21
|
+
@pools[frequency] << WeakRef.new(pool)
|
|
12
22
|
end
|
|
13
23
|
end
|
|
14
|
-
end
|
|
15
24
|
|
|
16
|
-
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def __patched_spawn_thread(frequency) # rubocop:disable Metrics/MethodLength
|
|
28
|
+
Thread.new(frequency) do |t|
|
|
29
|
+
# Advise multi-threaded app servers to ignore this thread for
|
|
30
|
+
# the purposes of fork safety warnings
|
|
31
|
+
Thread.current.thread_variable_set(:fork_safe, true)
|
|
32
|
+
Thread.current.name = 'AR Pool Reaper'
|
|
33
|
+
running = true
|
|
34
|
+
while running
|
|
35
|
+
sleep t
|
|
36
|
+
@mutex.synchronize do
|
|
37
|
+
@pools[frequency].select! do |pool|
|
|
38
|
+
pool.weakref_alive? && !pool.__patched_discarded?
|
|
39
|
+
end
|
|
17
40
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
41
|
+
@pools[frequency].each do |p|
|
|
42
|
+
p.reap
|
|
43
|
+
p.flush
|
|
44
|
+
p.retire_old_connections
|
|
45
|
+
rescue WeakRef::RefError
|
|
46
|
+
# Pool has been garbage collected. Nothing we can do here, move on.
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if @pools[frequency].empty?
|
|
50
|
+
@pools.delete(frequency)
|
|
51
|
+
@threads.delete(frequency)
|
|
52
|
+
running = false
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def run
|
|
61
|
+
return unless frequency&.positive?
|
|
62
|
+
self.class.__patched_register_pool(pool, frequency)
|
|
22
63
|
end
|
|
23
64
|
end
|
|
24
65
|
end
|
|
@@ -9,9 +9,9 @@ module ActiveRecordConnectionReaper
|
|
|
9
9
|
require 'activerecord_connection_reaper/extensions/active_record/connection_adapters/reaper_check_max_age'
|
|
10
10
|
require 'activerecord_connection_reaper/extensions/active_record/connection_adapters/pool_max_age'
|
|
11
11
|
|
|
12
|
-
ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecordConnectionReaper::Extensions::ActiveRecord::ConnectionAdapters::AbstractAdapterTrackConnectedSince)
|
|
13
|
-
ActiveRecord::ConnectionAdapters::ConnectionPool::Reaper.prepend(ActiveRecordConnectionReaper::Extensions::ActiveRecord::ConnectionAdapters::ReaperCheckMaxAge)
|
|
14
|
-
ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecordConnectionReaper::Extensions::ActiveRecord::ConnectionAdapters::PoolMaxAge)
|
|
12
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecordConnectionReaper::Extensions::ActiveRecord::ConnectionAdapters::AbstractAdapterTrackConnectedSince) # rubocop:disable Layout/LineLength
|
|
13
|
+
ActiveRecord::ConnectionAdapters::ConnectionPool::Reaper.prepend(ActiveRecordConnectionReaper::Extensions::ActiveRecord::ConnectionAdapters::ReaperCheckMaxAge) # rubocop:disable Layout/LineLength
|
|
14
|
+
ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecordConnectionReaper::Extensions::ActiveRecord::ConnectionAdapters::PoolMaxAge) # rubocop:disable Layout/LineLength
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord_connection_reaper
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miriam Technologies
|
|
@@ -77,9 +77,12 @@ require_paths:
|
|
|
77
77
|
- lib
|
|
78
78
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '2.5'
|
|
83
|
+
- - "<"
|
|
81
84
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: 3.
|
|
85
|
+
version: '3.5'
|
|
83
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
87
|
requirements:
|
|
85
88
|
- - ">="
|