postgres-vacuum-monitor 0.16.0 → 0.18.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d9e8b90692a2b1bbadc40202497aae4af9a3e088b8c5a47869396ba5d14e796
4
- data.tar.gz: 7db2e649f6c350a613e6b765f0cf9fe4f10cae9a4b0aa05f47a585519a029ad3
3
+ metadata.gz: e48388bc503322ef09d9dc165846baf812303f134d1b6a21a27c5ddddf61e1e1
4
+ data.tar.gz: 47e0f3a4b1f889fae3e4a36d9e12609fe15ea66b24ed935f3d43493d37e55f74
5
5
  SHA512:
6
- metadata.gz: 7668c76a3666dfa35a70c26a923b2a9aebd1f0d1d96c3f4f5fe868dcba9c6f2ec4e15edcf1dbba07b17ab460b04d898c3468709e0dfd54532d6b503ca02f63f7
7
- data.tar.gz: 284047bdc67471afda8abc017e377d3536de6e1593bfcc9993bc8ff16d5be562194b4f552f36ef150259c51b34571fcfc5b6ada56767da6fb2469d48c50aeca0
6
+ metadata.gz: 771a3f359d8618df3b57e14fff6cfd744a1efe6da4324579713ad1d549f26a3fbfac9671ee86253f6a3b6e4572c45577862dabf4dc3c4fdbfcd5c77901fecc48
7
+ data.tar.gz: 61a8ba22eb3a71c4847a86e94ac2f5e0c2feb91b74dee2a32ae93f1d58272b76efc3cbff92269dead4a6aa35635faa6a30664a7d13e26d82d67fd3c7b3444daa
data/.circleci/config.yml CHANGED
@@ -8,15 +8,15 @@ version: 2.1
8
8
  jobs:
9
9
  lint:
10
10
  docker:
11
- - image: $SALSIFY_ECR_REPO/ruby_ci:3.0.6
11
+ - image: $SALSIFY_ECR_REPO/ruby_ci:3.2.8
12
12
  <<: *aws-auth
13
13
  working_directory: ~/postgres-vacuum-monitor
14
14
  steps:
15
15
  - checkout
16
16
  - restore_cache:
17
17
  keys:
18
- - v1-gems-ruby-3.0.6-{{ checksum "postgres-vacuum-monitor.gemspec" }}-{{ checksum "Gemfile" }}
19
- - v1-gems-ruby-3.0.6-
18
+ - v1-gems-ruby-3.2.8-{{ checksum "postgres-vacuum-monitor.gemspec" }}-{{ checksum "Gemfile" }}
19
+ - v1-gems-ruby-3.2.8-
20
20
  - run:
21
21
  name: Install Gems
22
22
  command: |
@@ -25,7 +25,7 @@ jobs:
25
25
  bundle clean
26
26
  fi
27
27
  - save_cache:
28
- key: v1-gems-ruby-3.0.6-{{ checksum "postgres-vacuum-monitor.gemspec" }}-{{ checksum "Gemfile" }}
28
+ key: v1-gems-ruby-3.2.8-{{ checksum "postgres-vacuum-monitor.gemspec" }}-{{ checksum "Gemfile" }}
29
29
  paths:
30
30
  - "vendor/bundle"
31
31
  - "gemfiles/vendor/bundle"
@@ -94,10 +94,10 @@ workflows:
94
94
  matrix:
95
95
  parameters:
96
96
  gemfile:
97
- - "gemfiles/activerecord_6_1.gemfile"
98
- - "gemfiles/activerecord_7_0.gemfile"
99
- - "gemfiles/activerecord_7_1.gemfile"
97
+ - gemfiles/activerecord_7_1.gemfile
98
+ - gemfiles/activerecord_7_2.gemfile
99
+ - gemfiles/activerecord_8_0.gemfile
100
100
  ruby_version:
101
- - "3.0.6"
102
- - "3.1.4"
103
- - "3.2.2"
101
+ - 3.2.8
102
+ - 3.3.8
103
+ - 3.4.5
data/.rubocop.yml CHANGED
@@ -2,7 +2,7 @@ inherit_gem:
2
2
  salsify_rubocop: conf/rubocop_rails.yml
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 3.0
5
+ TargetRubyVersion: 3.2
6
6
  Exclude:
7
7
  - 'vendor/**/*'
8
8
  - 'gemfiles/**/*'
data/Appraisals CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise 'activerecord_6_1' do
4
- gem 'activerecord', '~> 6.1.7.6'
3
+ appraise 'activerecord_7_1' do
4
+ gem 'activerecord', '~> 7.1.5'
5
5
  end
6
6
 
7
- appraise 'activerecord_7_0' do
8
- gem 'activerecord', '~> 7.0.8'
7
+ appraise 'activerecord_7_2' do
8
+ gem 'activerecord', '~> 7.2.2'
9
9
  end
10
10
 
11
- appraise 'activerecord_7_1' do
12
- gem 'activerecord', '~> 7.1.1'
11
+ appraise 'activerecord_8_0' do
12
+ gem 'activerecord', '~> 8.0.2'
13
13
  end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # postgres-vacuum-monitor
2
2
 
3
+ ## v0.18.0
4
+ - Add support for Rails 7.2 and 8.0.
5
+ - Drop support for Rails 6.1 and 7.0.
6
+ - Drop support for Ruby 3.0 and 3.1.
7
+
8
+ ## v0.17.0
9
+ - Increased default `monitor_max_run_time_seconds` to 60 seconds.
10
+ - Added `monitor_statement_timeout_seconds` (defaults to 10 seconds) to limit query runtime.
11
+ - Eagerly clear connection pools when a `ActiveRecord::StatementInvalid` or `ActiveRecord::ConnectionTimeoutError`
12
+ is encountered to attempt to clear bad connections.
13
+
3
14
  ## v0.16.0
4
15
  - Add `max_attempts` and `max_run_time` to `Postgres::Vacuum::Jobs::MonitorJob` to avoid backing up the queue. The
5
16
  defaults are 1 attempt and 10 seconds, but they can be configured with `monitor_max_attempts` and
data/README.md CHANGED
@@ -37,8 +37,10 @@ Postgres::Vacuum::Monitor.configure do |config|
37
37
  config.long_running_transaction_threshold_seconds = 10 * 60
38
38
  # Optionally change `max_attempts` of the monitor job (default 1)
39
39
  config.monitor_max_attempts = 3
40
- # Optionally change `max_run_time` of the monitor job (default 10 seconds)
40
+ # Optionally change `max_run_time` of the monitor job (default 60 seconds)
41
41
  config.monitor_max_run_time_seconds = 5
42
+ # Optionally change the statement timeout of queries (default 10 seconds)
43
+ config.monitor_statement_timeout_seconds = 5
42
44
  end
43
45
  ```
44
46
 
data/Rakefile CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'bundler/gem_tasks'
4
4
  require 'bundler/setup'
5
- Bundler::GemHelper.install_tasks
6
5
 
7
6
  require 'rspec/core/rake_task'
8
7
  RSpec::Core::RakeTask.new(:spec) do |task|
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 7.1.1"
5
+ gem "activerecord", "~> 7.1.5"
6
6
 
7
7
  gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 7.0.8"
5
+ gem "activerecord", "~> 7.2.2"
6
6
 
7
7
  gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 6.1.7.6"
5
+ gem "activerecord", "~> 8.0.2"
6
6
 
7
7
  gemspec path: "../"
@@ -4,19 +4,22 @@ module Postgres
4
4
  module Vacuum
5
5
  class Configuration
6
6
  DEFAULT_LONG_RUNNING_TRANSACTION_THRESHOLD_SECONDS = 5 * 60
7
- DEFAULT_MONITOR_MAX_RUN_TIME_SECONDS = 10
7
+ DEFAULT_MONITOR_MAX_RUN_TIME_SECONDS = 60
8
8
  DEFAULT_MONITOR_MAX_ATTEMPTS = 1
9
+ DEFAULT_MONITOR_STATEMENT_TIMEOUT_SECONDS = 10
9
10
 
10
11
  attr_accessor :monitor_reporter_class_name,
11
12
  :long_running_transaction_threshold_seconds,
12
13
  :monitor_max_run_time_seconds,
13
- :monitor_max_attempts
14
+ :monitor_max_attempts,
15
+ :monitor_statement_timeout_seconds
14
16
 
15
17
  def initialize
16
18
  self.monitor_reporter_class_name = nil
17
19
  self.long_running_transaction_threshold_seconds = DEFAULT_LONG_RUNNING_TRANSACTION_THRESHOLD_SECONDS
18
20
  self.monitor_max_run_time_seconds = DEFAULT_MONITOR_MAX_RUN_TIME_SECONDS
19
21
  self.monitor_max_attempts = DEFAULT_MONITOR_MAX_ATTEMPTS
22
+ self.monitor_statement_timeout_seconds = DEFAULT_MONITOR_STATEMENT_TIMEOUT_SECONDS
20
23
  end
21
24
  end
22
25
  end
@@ -98,14 +98,42 @@ module Postgres
98
98
  databases = Set.new
99
99
  ActiveRecord::Base.connection_handler.connection_pools.map do |connection_pool|
100
100
  db_name = connection_pool.db_config.configuration_hash[:database]
101
+ next unless databases.add?(db_name)
102
+
103
+ # ActiveRecord allocates a connection pool per call to `.establish_connection`
104
+ # As a result, multiple pools might interact with the same database, so we use
105
+ # the database name to dedupe.
106
+ connection_pool.with_connection do |connection|
107
+ original_timeout = statement_timeout(connection)
108
+ set_statement_timeout(connection, "#{configured_timeout_seconds}s")
109
+
110
+ yield(db_name, connection)
111
+ ensure
112
+ set_statement_timeout(connection, original_timeout)
113
+ end
101
114
 
102
- # activerecord allocates a connection pool per call to establish_connection
103
- # multiple pools might interact with the same database so we use the
104
- # database name to dedup
105
- connection_pool.with_connection { |conn| yield(db_name, conn) } if databases.add?(db_name)
115
+ # We want to avoid hanging onto a bad connection that would cause all future
116
+ # jobs to fail, so we eagerly clear the pool.
117
+ rescue ActiveRecord::StatementInvalid, ActiveRecord::ConnectionTimeoutError
118
+ connection_pool.disconnect!
119
+ raise
106
120
  end
107
121
  end
108
122
 
123
+ def statement_timeout(connection)
124
+ result = connection.execute('SHOW statement_timeout').first
125
+ result['statement_timeout'] if result.present?
126
+ end
127
+
128
+ def set_statement_timeout(connection, timeout)
129
+ query = ActiveRecord::Base.sanitize_sql(['SET statement_timeout = ?', timeout])
130
+ connection.execute(query)
131
+ end
132
+
133
+ def configured_timeout_seconds
134
+ Postgres::Vacuum::Monitor.configuration.monitor_statement_timeout_seconds
135
+ end
136
+
109
137
  ConfigurationError = Class.new(StandardError)
110
138
  end
111
139
  end
@@ -3,7 +3,7 @@
3
3
  module Postgres
4
4
  module Vacuum
5
5
  module Monitor
6
- VERSION = '0.16.0'
6
+ VERSION = '0.18.0'
7
7
  end
8
8
  end
9
9
  end
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ['lib']
31
31
 
32
- spec.required_ruby_version = '>= 3.0'
32
+ spec.required_ruby_version = '>= 3.2'
33
33
 
34
34
  spec.add_development_dependency 'appraisal'
35
35
  spec.add_development_dependency 'bundler'
@@ -40,6 +40,6 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency 'rspec_junit_formatter'
41
41
  spec.add_development_dependency 'salsify_rubocop', '~> 1.42.1'
42
42
 
43
- spec.add_dependency 'activerecord', '>= 6.1', '< 7.2'
43
+ spec.add_dependency 'activerecord', '>= 7.1', '< 8.1'
44
44
  spec.add_dependency 'pg', '>= 0.18', '< 2.0'
45
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postgres-vacuum-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernando Garces
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-15 00:00:00.000000000 Z
11
+ date: 2025-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -128,20 +128,20 @@ dependencies:
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: '6.1'
131
+ version: '7.1'
132
132
  - - "<"
133
133
  - !ruby/object:Gem::Version
134
- version: '7.2'
134
+ version: '8.1'
135
135
  type: :runtime
136
136
  prerelease: false
137
137
  version_requirements: !ruby/object:Gem::Requirement
138
138
  requirements:
139
139
  - - ">="
140
140
  - !ruby/object:Gem::Version
141
- version: '6.1'
141
+ version: '7.1'
142
142
  - - "<"
143
143
  - !ruby/object:Gem::Version
144
- version: '7.2'
144
+ version: '8.1'
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: pg
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -184,9 +184,9 @@ files:
184
184
  - Rakefile
185
185
  - bin/console
186
186
  - bin/setup
187
- - gemfiles/activerecord_6_1.gemfile
188
- - gemfiles/activerecord_7_0.gemfile
189
187
  - gemfiles/activerecord_7_1.gemfile
188
+ - gemfiles/activerecord_7_2.gemfile
189
+ - gemfiles/activerecord_8_0.gemfile
190
190
  - lib/postgres/vacuum/configuration.rb
191
191
  - lib/postgres/vacuum/jobs/monitor_job.rb
192
192
  - lib/postgres/vacuum/monitor.rb
@@ -207,14 +207,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
207
  requirements:
208
208
  - - ">="
209
209
  - !ruby/object:Gem::Version
210
- version: '3.0'
210
+ version: '3.2'
211
211
  required_rubygems_version: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - ">="
214
214
  - !ruby/object:Gem::Version
215
215
  version: '0'
216
216
  requirements: []
217
- rubygems_version: 3.3.26
217
+ rubygems_version: 3.4.1
218
218
  signing_key:
219
219
  specification_version: 4
220
220
  summary: Simple stats collector for postgres auto vacuumer.