advanced_connection 0.5.12 → 0.5.13

Sign up to get free protection for your applications and to get access to all the features.
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: