postgres-vacuum-monitor 0.16.0 → 0.17.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: 4fdc95cbf83e6d6ea5fe51fa31fc1f42fbb5fa6ea3e3d514b7c7ec5f01f1c24c
4
+ data.tar.gz: 4b501cf4b4a06403ff4f97806062d0d343281fee0e05b9be5b2a869c1056b811
5
5
  SHA512:
6
- metadata.gz: 7668c76a3666dfa35a70c26a923b2a9aebd1f0d1d96c3f4f5fe868dcba9c6f2ec4e15edcf1dbba07b17ab460b04d898c3468709e0dfd54532d6b503ca02f63f7
7
- data.tar.gz: 284047bdc67471afda8abc017e377d3536de6e1593bfcc9993bc8ff16d5be562194b4f552f36ef150259c51b34571fcfc5b6ada56767da6fb2469d48c50aeca0
6
+ metadata.gz: a3f13ae2ee50cf641f96bb629d9e994f422b0642c0b59ec7852356e9c37bebc26685ea37ac037c3921b50fac5fae7c05719f6780c6d06c6103fb9bc15aba4d55
7
+ data.tar.gz: ccc2959571873fbec25bb9d70cd8c22346335081e685fc585db5a06df615e8192036e5da32629f6b44d1cbe3fb44dcc5160f4c1d66dbf595ccb8d3725cf6bec5
data/.circleci/config.yml CHANGED
@@ -94,10 +94,11 @@ 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_6_1.gemfile
98
+ - gemfiles/activerecord_7_0.gemfile
99
+ - gemfiles/activerecord_7_1.gemfile
100
100
  ruby_version:
101
- - "3.0.6"
102
- - "3.1.4"
103
- - "3.2.2"
101
+ - 3.0.6
102
+ - 3.1.4
103
+ - 3.2.2
104
+ - 3.3.0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # postgres-vacuum-monitor
2
2
 
3
+ ## v0.17.0
4
+ - Increased default `monitor_max_run_time_seconds` to 60 seconds.
5
+ - Added `monitor_statement_timeout_seconds` (defaults to 10 seconds) to limit query runtime.
6
+ - Eagerly clear connection pools when a `ActiveRecord::StatementInvalid` or `ActiveRecord::ConnectionTimeoutError`
7
+ is encountered to attempt to clear bad connections.
8
+
3
9
  ## v0.16.0
4
10
  - Add `max_attempts` and `max_run_time` to `Postgres::Vacuum::Jobs::MonitorJob` to avoid backing up the queue. The
5
11
  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|
@@ -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.17.0'
7
7
  end
8
8
  end
9
9
  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.17.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: 2024-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal