advanced_connection 0.5.12 → 0.5.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ca32aa10dbd8b756bb82f0d2592a13ca1155ecc
4
- data.tar.gz: 75a52b7b6983556c3c1c86670d60b419e1a42e23
3
+ metadata.gz: 6d9bda6b436e364dda841af17bf2b2915d3e261d
4
+ data.tar.gz: 6248d54d405b47f4bb26d8c38d3a102b71d78342
5
5
  SHA512:
6
- metadata.gz: b48c3f8b4453614e6ee45d729f883b1a73112ccf88de8a947ca278815703817585764b0b4d1062e24b4708dd2172b75ffa023535de4e9d3a4ca421804664b331
7
- data.tar.gz: 44d5368de1b9a5d70696ba8a0a726c728dfcb33cfd7ae5345bcc99f483c9e5c0e82542498c77b59ee5dea3e6c75731079fc0268b2bdcc4aa103c8e4626f55ed5
6
+ metadata.gz: 4ad06944f5895088cdf3c3b0edb8fea2f329a8f77b9a77ec5a0f76fe73fa6ca7d63f61c99d6227fa7a1302e817efc780b0cb97c126604976c3f1c7caf125db4c
7
+ data.tar.gz: 7d7ae267de0aa0973ea4ad381c01b8ce9ec07ee65f1be3dcb65672ed79e46e1ca2389e97559d12b7d99c15ea5edd1d27a07aaf700a4bf1f64a6ebfb802ed76b4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- advanced_connection (0.5.12)
4
+ advanced_connection (0.5.13)
5
5
  activerecord (~> 4.1)
6
6
  activesupport (~> 4.1)
7
7
  rails (~> 4.1)
@@ -46,11 +46,8 @@ GEM
46
46
  tzinfo (~> 1.1)
47
47
  arel (6.0.3)
48
48
  builder (3.2.2)
49
- charlock_holmes (0.7.3)
50
49
  coderay (1.1.1)
51
50
  concurrent-ruby (1.0.1)
52
- copyright-header (1.0.15)
53
- github-linguist (~> 2.6)
54
51
  coveralls (0.8.13)
55
52
  json (~> 1.8)
56
53
  simplecov (~> 0.11.0)
@@ -60,15 +57,9 @@ GEM
60
57
  diff-lcs (1.2.5)
61
58
  docile (1.1.5)
62
59
  erubis (2.7.0)
63
- escape_utils (1.0.1)
64
60
  ffi (1.9.10)
65
61
  ffi (1.9.10-java)
66
62
  formatador (0.2.5)
67
- github-linguist (2.12.0)
68
- charlock_holmes (~> 0.7.3)
69
- escape_utils (~> 1.0.1)
70
- mime-types (~> 1.19)
71
- pygments.rb (~> 0.6.0)
72
63
  globalid (0.3.6)
73
64
  activesupport (>= 4.1.0)
74
65
  guard (2.13.0)
@@ -97,7 +88,9 @@ GEM
97
88
  mail (2.6.4)
98
89
  mime-types (>= 1.16, < 4)
99
90
  method_source (0.8.2)
100
- mime-types (1.25.1)
91
+ mime-types (3.0)
92
+ mime-types-data (~> 3.2015)
93
+ mime-types-data (3.2016.0221)
101
94
  mini_portile2 (2.0.0)
102
95
  minitest (5.8.4)
103
96
  nenv (0.3.0)
@@ -107,7 +100,6 @@ GEM
107
100
  nenv (~> 0.1)
108
101
  shellany (~> 0.0)
109
102
  pg (0.18.4)
110
- posix-spawn (0.3.11)
111
103
  pry (0.10.3)
112
104
  coderay (~> 1.1.0)
113
105
  method_source (~> 0.8.1)
@@ -119,9 +111,6 @@ GEM
119
111
  spoon (~> 0.0)
120
112
  pry-nav (0.2.4)
121
113
  pry (>= 0.9.10, < 0.11.0)
122
- pygments.rb (0.6.3)
123
- posix-spawn (~> 0.3.6)
124
- yajl-ruby (~> 1.2.0)
125
114
  rabbitt-githooks (1.6.1)
126
115
  rainbow (~> 2.0.0)
127
116
  thor (~> 0.19.1)
@@ -198,7 +187,6 @@ GEM
198
187
  tins (1.6.0)
199
188
  tzinfo (1.2.2)
200
189
  thread_safe (~> 0.1)
201
- yajl-ruby (1.2.1)
202
190
 
203
191
  PLATFORMS
204
192
  java
@@ -206,7 +194,6 @@ PLATFORMS
206
194
 
207
195
  DEPENDENCIES
208
196
  advanced_connection!
209
- copyright-header (~> 1.0.15)
210
197
  coveralls (~> 0.8.13)
211
198
  guard-rspec (~> 4.6.4)
212
199
  pg (~> 0.18.4)
data/Rakefile CHANGED
@@ -91,46 +91,6 @@ namespace :db do
91
91
  end
92
92
  end
93
93
 
94
- namespace :copyright do
95
- namespace :headers do
96
- desc 'add copyright headers'
97
- task :add do
98
- require 'copyright_header'
99
-
100
- args = {
101
- license: 'MIT',
102
- copyright_software: 'Advanced Connection',
103
- copyright_software_description: "A Rails plugin providing an Idle Database Connection Manager",
104
- copyright_holders: ['Finalsite, LLC', 'Carl P. Corliss <carl.corliss@finalsite.com>'],
105
- copyright_years: ['2016'],
106
- add_path: 'lib',
107
- output_dir: '.'
108
- }
109
-
110
- command_line = CopyrightHeader::CommandLine.new( args )
111
- command_line.execute
112
- end
113
-
114
- desc 'remove copyright headers'
115
- task :remove do
116
- require 'copyright_header'
117
-
118
- args = {
119
- license: 'MIT',
120
- copyright_software: 'Advanced Connection',
121
- copyright_software_description: "A Rails plugin providing an Idle Database Connection Manager",
122
- copyright_holders: ['Finalsite, LLC', 'Carl P. Corliss <carl.corliss@finalsite.com>'],
123
- copyright_years: ['2016'],
124
- remove_path: 'lib',
125
- output_dir: '.'
126
- }
127
-
128
- command_line = CopyrightHeader::CommandLine.new( args )
129
- command_line.execute
130
- end
131
- end
132
- end
133
-
134
94
  namespace :postgres do
135
95
  require 'active_record'
136
96
 
@@ -1,22 +1,22 @@
1
- $:.push File.expand_path("../lib", __FILE__)
1
+ $:.push File.expand_path('../lib', __FILE__)
2
2
 
3
3
  # Maintain your gem's version:
4
- require "advanced_connection/version"
4
+ require 'advanced_connection/version'
5
5
 
6
6
  # Describe your gem and declare its dependencies:
7
7
  Gem::Specification.new do |spec|
8
- spec.name = "advanced_connection"
8
+ spec.name = 'advanced_connection'
9
9
  spec.version = AdvancedConnection::VERSION
10
- spec.authors = ["Carl P. Corliss"]
11
- spec.email = ["carl.corliss@finalsite.com"]
12
- spec.homepage = "https://github.com/finalsite/advanced_connection"
13
- spec.summary = "Provides advanced connection options for rails connection pools"
14
- spec.description = "Adds idle connection management, statement pooling, and other advanced connection features"
15
- spec.license = "MIT"
10
+ spec.authors = ['Carl P. Corliss']
11
+ spec.email = ['carl.corliss@finalsite.com']
12
+ spec.homepage = 'https://github.com/finalsite/advanced_connection'
13
+ spec.summary = 'Provides advanced connection options for rails connection pools'
14
+ spec.description = 'Adds idle connection management, statement pooling, and other advanced connection features'
15
+ spec.license = 'MIT'
16
16
 
17
17
  spec.files = `git ls-files`.split($/)
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
21
  # eventually support this:
22
22
  # spec.required_engine_version = {
@@ -24,27 +24,27 @@ Gem::Specification.new do |spec|
24
24
  # :jruby => '~> 1.7',
25
25
  # }
26
26
 
27
- spec.add_runtime_dependency "rails", "~> 4.1"
28
- spec.add_runtime_dependency "activerecord", "~> 4.1"
29
- spec.add_runtime_dependency "activesupport", "~> 4.1"
27
+ spec.add_runtime_dependency 'rails', '~> 4.1'
28
+ spec.add_runtime_dependency 'activerecord', '~> 4.1'
29
+ spec.add_runtime_dependency 'activesupport', '~> 4.1'
30
30
 
31
- spec.add_development_dependency "rake", '~> 10.5.0'
32
- spec.add_development_dependency "rack", '~> 1.6.4'
33
- spec.add_development_dependency "rspec", '~> 3.4.0'
34
- spec.add_development_dependency "rspec-its", '~> 1.2.0'
35
- spec.add_development_dependency "rspec-collection_matchers", '~> 1.1.2'
31
+ spec.add_development_dependency 'rake', '~> 10.5.0'
32
+ spec.add_development_dependency 'rack', '~> 1.6.4'
33
+ spec.add_development_dependency 'rspec', '~> 3.4.0'
34
+ spec.add_development_dependency 'rspec-its', '~> 1.2.0'
35
+ spec.add_development_dependency 'rspec-collection_matchers', '~> 1.1.2'
36
36
 
37
37
  # optional dependencies
38
38
  if RUBY_ENGINE == 'jruby'
39
- spec.add_development_dependency "activerecord-jdbcpostgresql-adapter", "~> 1.3.19"
39
+ spec.add_development_dependency 'activerecord-jdbcpostgresql-adapter', '~> 1.3.19'
40
+ spec.add_development_dependency 'puma', '~> 3.4.0'
40
41
  else
41
- spec.add_development_dependency "pg", "~> 0.18.4"
42
- spec.add_development_dependency "pry", '~> 0.10.3'
43
- spec.add_development_dependency "pry-nav", '~> 0.2.4'
42
+ spec.add_development_dependency 'pg', '~> 0.18.4'
43
+ spec.add_development_dependency 'pry', '~> 0.10.3'
44
+ spec.add_development_dependency 'pry-nav', '~> 0.2.4'
44
45
  end
45
46
 
46
- spec.add_development_dependency "guard-rspec", '~> 4.6.4'
47
- spec.add_development_dependency "coveralls", '~> 0.8.13'
47
+ spec.add_development_dependency 'guard-rspec', '~> 4.6.4'
48
+ spec.add_development_dependency 'coveralls', '~> 0.8.13'
48
49
  spec.add_development_dependency 'rabbitt-githooks', '~> 1.6.0'
49
- spec.add_development_dependency 'copyright-header', '~> 1.0.15'
50
50
  end
@@ -44,5 +44,9 @@ module AdvancedConnection::ActiveRecordExt
44
44
  def instance_age
45
45
  (Time.now - @instantiated_at).to_f
46
46
  end
47
+
48
+ def idle_time
49
+ (in_use? ? 0.0 : Time.now - @last_checked_in).to_f
50
+ end
47
51
  end
48
52
  end
@@ -1,4 +1,4 @@
1
- #
1
+
2
2
  # Copyright (C) 2016 Finalsite, LLC
3
3
  # Copyright (C) 2016 Carl P. Corliss <carl.corliss@finalsite.com>
4
4
  #
@@ -32,13 +32,48 @@ module AdvancedConnection::ActiveRecordExt
32
32
 
33
33
  class IdleManager
34
34
  attr_accessor :interval
35
- attr_reader :thread
35
+ attr_reader :thread, :logger
36
36
  private :thread
37
37
 
38
38
  def initialize(pool, interval)
39
39
  @pool = pool
40
40
  @interval = interval.to_i
41
41
  @thread = nil
42
+ @logger = ActiveSupport::Logger.new(Rails.root.join('log', 'idle_manager.log'))
43
+ @logger.level = Rails.logger.level
44
+ end
45
+
46
+ def log_info(format, *args)
47
+ @logger.info(format("#{idle_stats} #{format}", *args))
48
+ end
49
+
50
+ def log_debug(format, *args)
51
+ @logger.debug(format("#{idle_stats} #{format}", *args))
52
+ end
53
+
54
+ def log_warn(format, *args)
55
+ @logger.debug(format("#{idle_stats} #{format}", *args))
56
+ end
57
+
58
+ def dump_stats
59
+ if (stats_dump = Rails.root.join('tmp', 'dump-idle-stats.txt')).exist?
60
+ log_info "Dumping statistics"
61
+ id_size = self.object_id.to_s.size
62
+ @logger.info(format("%3s: %#{id_size}s\t%9s\t%9s", 'IDX', 'OID', 'AGE', 'IDLE'))
63
+ @pool.idle_connections.each_with_index do |connection, index|
64
+ @logger.info(format("%3d: %#{id_size}d\t%9d\t%9d",
65
+ index, connection.object_id, connection.instance_age, connection.idle_time))
66
+ end
67
+ !!(stats_dump.unlink rescue true)
68
+ end
69
+ end
70
+
71
+ def idle_stats
72
+ stats = @pool.pool_statistics
73
+ format(
74
+ "[#{Time.now}] IdleManager (Actv:%d,Avail:%d,Idle:%d,Total:%d):",
75
+ stats.active, stats.available, stats.idle, stats.total,
76
+ )
42
77
  end
43
78
 
44
79
  def status
@@ -63,19 +98,23 @@ module AdvancedConnection::ActiveRecordExt
63
98
  return unless @interval > 0
64
99
 
65
100
  @thread ||= Thread.new(@pool, @interval) { |pool, interval|
66
- pool.send(:idle_info, "starting idle manager; running every #{interval} seconds")
101
+ log_info("starting idle manager; running every #{interval} seconds")
67
102
 
68
103
  loop do
69
104
  sleep interval
70
105
 
71
106
  begin
72
107
  start = Time.now
73
- pool.send(:idle_debug, "beginning idle connection cleanup")
108
+ dump_stats
109
+
110
+ log_debug("beginning idle connection cleanup")
74
111
  pool.remove_idle_connections
75
- pool.send(:idle_debug, "beginning idle connection warmup")
112
+
113
+ log_debug("beginning idle connection warmup")
76
114
  pool.create_idle_connections
115
+
77
116
  finish = (Time.now - start).round(6)
78
- pool.send(:idle_debug, "finished idle connection tasks in #{finish} seconds; next run in #{pool.max_idle_time} seconds")
117
+ log_info("finished idle connection tasks in #{finish} seconds; next run in #{interval} seconds")
79
118
  rescue => e
80
119
  Rails.logger.error "#{e.class.name}: #{e.message}"
81
120
  e.backtrace.each { |line| Rails.logger.error line }
@@ -94,6 +133,7 @@ module AdvancedConnection::ActiveRecordExt
94
133
  when :prefer_older then Queues::OldAgeBiased.new
95
134
  when :prefer_younger then Queues::YoungAgeBiased.new
96
135
  when :lifo, :stack then Queues::Stack.new
136
+ when :fifo, :queue then Queues::FIFO.new
97
137
  else
98
138
  Rails.logger.warn "Unknown queue_type #{queue_type.inspect} - using standard FIFO instead"
99
139
  Queues::FIFO.new
@@ -151,7 +191,7 @@ module AdvancedConnection::ActiveRecordExt
151
191
 
152
192
  def checkin_with_last_checked_in(conn)
153
193
  conn.last_checked_in = Time.now
154
- idle_debug "checking in connection #{conn.object_id} at #{conn.last_checked_in}"
194
+ idle_manager.debug "checking in connection #{conn.object_id} at #{conn.last_checked_in}"
155
195
  checkin_without_last_checked_in(conn)
156
196
  end
157
197
 
@@ -213,7 +253,7 @@ module AdvancedConnection::ActiveRecordExt
213
253
 
214
254
  return unless slots >= count
215
255
 
216
- idle_info "Warming up #{count} connection#{count > 1 ? 's' : ''}"
256
+ idle_manager.log_info "Warming up #{count} connection#{count > 1 ? 's' : ''}"
217
257
  synchronize do
218
258
  count.times {
219
259
  conn = checkout_new_connection
@@ -242,27 +282,36 @@ module AdvancedConnection::ActiveRecordExt
242
282
 
243
283
  def remove_idle_connections
244
284
  # don't attempt to remove idle connections if we have threads waiting
245
- return if @available.num_waiting > 0
285
+ if @available.num_waiting > 0
286
+ idle_manager.log_warn "Cannot reap while threads actively waiting on db connections"
287
+ return
288
+ end
246
289
 
247
290
  idle_conns = idle_connections
248
291
  idle_count = idle_conns.size
249
292
 
250
- return unless idle_count > max_idle_connections
293
+ unless idle_count > max_idle_connections
294
+ idle_manager.log_warn "idle count (#{idle_count}) does not exceed max idle connections (#{max_idle_connections}); skipping reap."
295
+ return
296
+ end
251
297
 
252
298
  cull_count = (idle_count - max_idle_connections)
253
299
 
254
300
  culled = 0
255
301
  idle_conns.each_with_index do |conn, idx|
256
- last_ci = (Time.now - conn.last_checked_in).to_f
257
302
  if idx < cull_count
258
- culled += remove_connection(conn) ? 1 : 0
259
- idle_info "culled connection ##{idx} id##{conn.object_id} - age:#{conn.instance_age} last_checkin:#{last_ci}"
303
+ if remove_connection(conn)
304
+ culled += 1
305
+ idle_manager.log_info "culled connection ##{idx} id##{conn.object_id} - age:#{conn.instance_age.to_i} idle_time:#{conn.idle_time.to_i}"
306
+ else
307
+ idle_manager.log_info "kept connection ##{idx} id##{conn.object_id} - age:#{conn.instance_age.to_i} idle_time:#{conn.idle_time.to_i}"
308
+ end
260
309
  else
261
- idle_info "kept connection ##{idx} id##{conn.object_id} - age:#{conn.instance_age} last_checkin:#{last_ci}"
310
+ idle_manager.log_info "kept connection ##{idx} id##{conn.object_id} - age:#{conn.instance_age.to_i} idle_time:#{conn.idle_time.to_i}"
262
311
  end
263
312
  end
264
313
 
265
- idle_info "culled %d connections" % culled
314
+ idle_manager.log_info "culled %d connections" % culled
266
315
  end
267
316
 
268
317
  private
@@ -275,23 +324,6 @@ module AdvancedConnection::ActiveRecordExt
275
324
  end
276
325
  true
277
326
  end
278
-
279
- def idle_message(format, *args)
280
- stats = pool_statistics
281
- format(
282
- "IdleManager (Actv:%d,Avail:%d,Idle:%d,Total:%d): #{format}",
283
- stats.active, stats.available, stats.idle, stats.total,
284
- *args
285
- )
286
- end
287
-
288
- def idle_debug(format, *args)
289
- Rails.logger.debug idle_message(format, *args)
290
- end
291
-
292
- def idle_info(format, *args)
293
- Rails.logger.info idle_message(format, *args)
294
- end
295
327
  end
296
328
  end
297
329
  end
@@ -46,13 +46,13 @@ module AdvancedConnection::ActiveRecordExt
46
46
 
47
47
  class YoungAgeBiased < AgeSorted
48
48
  def remove
49
- @queue.pop
49
+ @queue.shift
50
50
  end
51
51
  end
52
52
 
53
53
  class OldAgeBiased < AgeSorted
54
54
  def remove
55
- @queue.shift
55
+ @queue.pop
56
56
  end
57
57
  end
58
58
  end
@@ -45,7 +45,7 @@ module AdvancedConnection
45
45
  min_idle_connections: 0,
46
46
  max_idle_connections: ::Float::INFINITY,
47
47
  max_idle_time: 0,
48
- idle_check_interval: 0,
48
+ idle_check_interval: nil,
49
49
  callbacks: ActiveSupport::OrderedOptions.new
50
50
  ).freeze unless defined? DEFAULT_CONFIG
51
51
 
@@ -22,7 +22,7 @@
22
22
  module AdvancedConnection
23
23
  MAJOR = 0
24
24
  MINOR = 5
25
- PATCH = 12
25
+ PATCH = 13
26
26
 
27
27
  VERSION = "%d.%d.%d" % [ MAJOR, MINOR, PATCH ]
28
28
  GEM_VERSION = Gem::Version.new(VERSION)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: advanced_connection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.12
4
+ version: 0.5.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl P. Corliss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-26 00:00:00.000000000 Z
11
+ date: 2016-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -206,20 +206,6 @@ dependencies:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
208
  version: 1.6.0
209
- - !ruby/object:Gem::Dependency
210
- name: copyright-header
211
- requirement: !ruby/object:Gem::Requirement
212
- requirements:
213
- - - "~>"
214
- - !ruby/object:Gem::Version
215
- version: 1.0.15
216
- type: :development
217
- prerelease: false
218
- version_requirements: !ruby/object:Gem::Requirement
219
- requirements:
220
- - - "~>"
221
- - !ruby/object:Gem::Version
222
- version: 1.0.15
223
209
  description: Adds idle connection management, statement pooling, and other advanced
224
210
  connection features
225
211
  email: