pg-locks-monitor 0.2.2 → 0.3.1

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: 170cb606bd1459b6b1a7525ed08ce17f2aab0757703ec9a33f64dadeafdebf7c
4
- data.tar.gz: 503f92da91e4ca9d03999c45abb50507f8888b209df33c4a0e8b87e4cfdcb6b5
3
+ metadata.gz: 609f63093dd3729e2b05577d39d55d13a09cfeb78dadc185e3cd1bbeff15a5eb
4
+ data.tar.gz: 29bb4e5292296c81338ac5250efbc8e85927cdb8ede8354f0e4300b96bca7528
5
5
  SHA512:
6
- metadata.gz: 27d0ac7d4340b0de7739b6383ec203830ab92eb5b952cbc41b9447c6d41aa540d52522f067bd1cdd857802c6c8a49a16ddaff9b95f2c51beed0f3e3b8dae6022
7
- data.tar.gz: b4594194b88910f3fcc2e9c7e79205147076ff0fcd6ccf79ca2bc0e7e4290a3d5167e041f7660e72ecdfff1e7fe598684f103256a976582c83c884b8639dc77d
6
+ metadata.gz: 50377aa6446f17e900a28d427a0c6fc734ab78e29934f73af50d7957d3f81228515abb236964c1b6d5e866c5fad001eda0853f13d5aeb0a3cb540d70c7cd0011
7
+ data.tar.gz: 782c10cf04da3cbf8ec325cb15680f90bbea646344df1e5e1a1e72125781279f98321f1cce41c6c5d7da60dd59cfaa04a04eadff3233ebe0a282202808fd308e
@@ -48,7 +48,15 @@ jobs:
48
48
  docker run --env POSTGRES_USER=postgres \
49
49
  --env POSTGRES_DB=pg-locks-monitor-test \
50
50
  --env POSTGRES_PASSWORD=secret \
51
- -d -p 5436:5432 postgres:15.1-alpine \
51
+ -d -p 5436:5432 postgres:15.8-alpine \
52
+ postgres -c shared_preload_libraries=pg_stat_statements
53
+ sleep 15
54
+ - name: Run PostgreSQL 16
55
+ run: |
56
+ docker run --env POSTGRES_USER=postgres \
57
+ --env POSTGRES_DB=pg-locks-monitor-test \
58
+ --env POSTGRES_PASSWORD=secret \
59
+ -d -p 5437:5432 postgres:16.4-alpine \
52
60
  postgres -c shared_preload_libraries=pg_stat_statements
53
61
  sleep 15
54
62
  - name: Set up Ruby ${{ matrix.ruby-version }}
@@ -73,17 +81,7 @@ jobs:
73
81
  POSTGRES_PASSWORD: secret
74
82
  DATABASE_URL: postgresql://postgres:secret@localhost:5432/pg-locks-monitor-test
75
83
  run: |
76
- bundle exec rspec spec/
77
- - name: Run tests for PG 11
78
- env:
79
- PG_VERSION: 11
80
- POSTGRES_HOST: localhost
81
- POSTGRES_USER: postgres
82
- POSTGRES_DB: pg-locks-monitor-test
83
- POSTGRES_PASSWORD: secret
84
- DATABASE_URL: postgresql://postgres:secret@localhost:5432/pg-locks-monitor-test
85
- run: |
86
- bundle exec rake test_all
84
+ bundle exec rspec spec
87
85
  - name: Run tests for PG 12
88
86
  env:
89
87
  PG_VERSION: 12
@@ -93,7 +91,7 @@ jobs:
93
91
  POSTGRES_PASSWORD: secret
94
92
  DATABASE_URL: postgresql://postgres:secret@localhost:5433/pg-locks-monitor-test
95
93
  run: |
96
- bundle exec rake test_all
94
+ bundle exec rspec spec
97
95
  - name: Run tests for PG 13
98
96
  env:
99
97
  PG_VERSION: 13
@@ -103,7 +101,7 @@ jobs:
103
101
  POSTGRES_PASSWORD: secret
104
102
  DATABASE_URL: postgresql://postgres:secret@localhost:5434/pg-locks-monitor-test
105
103
  run: |
106
- bundle exec rake test_all
104
+ bundle exec rspec spec
107
105
  - name: Run tests for PG 14
108
106
  env:
109
107
  PG_VERSION: 14
@@ -113,7 +111,7 @@ jobs:
113
111
  POSTGRES_PASSWORD: secret
114
112
  DATABASE_URL: postgresql://postgres:secret@localhost:5435/pg-locks-monitor-test
115
113
  run: |
116
- bundle exec rake test_all
114
+ bundle exec rspec spec
117
115
  - name: Run tests for PG 15
118
116
  env:
119
117
  PG_VERSION: 15
@@ -123,5 +121,17 @@ jobs:
123
121
  POSTGRES_PASSWORD: secret
124
122
  DATABASE_URL: postgresql://postgres:secret@localhost:5436/pg-locks-monitor-test
125
123
  run: |
126
- bundle exec rake test_all
124
+ bundle exec rspec spec
125
+ - name: Run tests for PG 16
126
+ env:
127
+ PG_VERSION: 15
128
+ POSTGRES_HOST: localhost
129
+ POSTGRES_USER: postgres
130
+ POSTGRES_DB: pg-locks-monitor-test
131
+ POSTGRES_PASSWORD: secret
132
+ DATABASE_URL: postgresql://postgres:secret@localhost:5437/pg-locks-monitor-test
133
+ run: |
134
+ bundle exec rspec spec
135
+
136
+
127
137
 
data/Rakefile CHANGED
@@ -5,5 +5,5 @@ RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  desc "Test all PG versions"
7
7
  task :test_all do
8
- system("PG_VERSION=11 bundle exec rspec spec/ && PG_VERSION=12 bundle exec rspec spec/ && PG_VERSION=13 bundle exec rspec spec/ && PG_VERSION=14 bundle exec rspec spec/")
8
+ system("PG_VERSION=11 bundle exec rspec spec && PG_VERSION=12 bundle exec rspec spec && PG_VERSION=13 bundle exec rspec spec && PG_VERSION=14 bundle exec rspec spec && PG_VERSION=16 bundle exec rspec spec && PG_VERSION=16 bundle exec rspec spec")
9
9
  end
@@ -1,5 +1,3 @@
1
- version: '3'
2
-
3
1
  services:
4
2
  postgres11:
5
3
  image: postgres:11.16-alpine
@@ -2,11 +2,12 @@
2
2
 
3
3
  require "uri"
4
4
  require "pg"
5
- require "ruby-pg-extras"
5
+ require "rails-pg-extras"
6
+ require "active_record"
6
7
 
7
8
  module PgLocksMonitor
8
9
  def self.snapshot!
9
- locks = RubyPgExtras.locks(
10
+ locks = RailsPgExtras.locks(
10
11
  in_format: :hash,
11
12
  ).select do |lock|
12
13
  if (age = lock.fetch("age"))
@@ -19,14 +20,21 @@ module PgLocksMonitor
19
20
  configuration.notifier_class.call(locks)
20
21
  end
21
22
 
22
- blocking = RubyPgExtras.blocking(in_format: :hash).select do |block|
23
- (ActiveSupport::Duration.parse(block.fetch("blocking_duration")).to_f * 1000) > configuration.blocking_min_duration_ms
23
+ blocking = RailsPgExtras.blocking(in_format: :hash).select do |block|
24
+ if (age = block.fetch("blocking_duration"))
25
+ (ActiveSupport::Duration.parse(age).to_f * 1000) > configuration.locks_min_duration_ms
26
+ end
24
27
  end.select(&configuration.blocking_filter_proc)
25
28
  .first(configuration.locks_limit)
26
29
 
27
30
  if blocking.count > 0 && configuration.monitor_blocking
28
31
  configuration.notifier_class.call(blocking)
29
32
  end
33
+
34
+ {
35
+ locks: locks,
36
+ blocking: blocking,
37
+ }
30
38
  end
31
39
 
32
40
  def self.configuration
@@ -36,6 +44,22 @@ module PgLocksMonitor
36
44
  def self.configure
37
45
  yield(configuration)
38
46
  end
47
+
48
+ class DurationHelper
49
+ require "date"
50
+
51
+ def self.parse_to_ms(duration_str)
52
+ time = DateTime.strptime(duration_str, "%H:%M:%S.%N")
53
+ hours = time.hour
54
+ minutes = time.minute
55
+ seconds = time.second
56
+ nanoseconds = time.second_fraction * (10 ** 9)
57
+
58
+ total_ms = (hours * 3600 * 1000) + (minutes * 60 * 1000) + (seconds * 1000) + (nanoseconds / 1_000_000).to_i
59
+
60
+ total_ms
61
+ end
62
+ end
39
63
  end
40
64
 
41
65
  require "pg_locks_monitor/default_notifier"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgLocksMonitor
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.1"
5
5
  end
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.test_files = s.files.grep(%r{^(spec)/})
16
16
  s.require_paths = ["lib"]
17
17
  s.license = "MIT"
18
- s.add_dependency "ruby-pg-extras"
18
+ s.add_dependency "rails-pg-extras"
19
19
  s.add_dependency "slack-notifier"
20
20
  s.add_development_dependency "rake"
21
21
  s.add_development_dependency "rspec"
@@ -3,14 +3,6 @@
3
3
  require "spec_helper"
4
4
 
5
5
  describe PgLocksMonitor::DefaultNotifier do
6
- before do
7
- # Mock Rails and its logger
8
- Rails = nil
9
- logger_double = double("Logger")
10
- allow(logger_double).to receive(:info)
11
- allow(Rails).to receive(:logger).and_return(logger_double)
12
- end
13
-
14
6
  it "requires correct config if Slack notifications enabled" do
15
7
  expect {
16
8
  PgLocksMonitor::DefaultNotifier.call({})
@@ -24,14 +16,26 @@ describe PgLocksMonitor::DefaultNotifier do
24
16
  }.to raise_error(RuntimeError)
25
17
  end
26
18
 
27
- it "sends the Slack notification if enabled" do
28
- PgLocksMonitor.configure do |config|
29
- config.notify_slack = true
30
- config.slack_webhook_url = "https://hooks.slack.com/services/123456789/123456789/123456789"
31
- config.slack_channel = "pg-locks-monitor"
19
+ describe "Slack notification enabled" do
20
+ before do
21
+ PgLocksMonitor.configure do |config|
22
+ config.notify_slack = true
23
+ config.slack_webhook_url = "https://hooks.slack.com/services/123456789/123456789/123456789"
24
+ config.slack_channel = "pg-locks-monitor"
25
+ end
32
26
  end
33
27
 
34
- expect_any_instance_of(Slack::Notifier).to receive(:ping)
35
- PgLocksMonitor::DefaultNotifier.call({ locks: "data" })
28
+ after do
29
+ PgLocksMonitor.configure do |config|
30
+ config.notify_slack = false
31
+ config.slack_webhook_url = nil
32
+ config.slack_channel = nil
33
+ end
34
+ end
35
+
36
+ it "sends the Slack notification" do
37
+ expect_any_instance_of(Slack::Notifier).to receive(:ping)
38
+ PgLocksMonitor::DefaultNotifier.call({ locks: "data" })
39
+ end
36
40
  end
37
41
  end
data/spec/smoke_spec.rb CHANGED
@@ -3,11 +3,37 @@
3
3
  require "spec_helper"
4
4
 
5
5
  describe PgLocksMonitor do
6
+ def spawn_update
7
+ Thread.new do
8
+ conn = RailsPgExtras.connection
9
+ conn.execute("
10
+ BEGIN;
11
+ UPDATE pg_locks_monitor_users SET name = 'Updated';
12
+ select pg_sleep(2);
13
+ COMMIT;
14
+ ")
15
+ end
16
+ end
17
+
6
18
  describe "snapshot!" do
7
19
  it "works" do
8
20
  expect {
9
21
  PgLocksMonitor.snapshot!
10
22
  }.not_to raise_error
11
23
  end
24
+
25
+ it "returns correct locks data" do
26
+ spawn_update
27
+ spawn_update
28
+ result = PgLocksMonitor.snapshot!
29
+ expect(result.fetch(:locks).count).to eq(0)
30
+ expect(result.fetch(:blocking).count).to eq(0)
31
+
32
+ sleep 1
33
+
34
+ result = PgLocksMonitor.snapshot!
35
+ expect(result.fetch(:locks).count).to eq(5)
36
+ expect(result.fetch(:blocking).count).to eq(1)
37
+ end
12
38
  end
13
39
  end
data/spec/spec_helper.rb CHANGED
@@ -14,8 +14,36 @@ port = if pg_version == "11"
14
14
  "5434"
15
15
  elsif pg_version == "14"
16
16
  "5435"
17
+ elsif pg_version == "15"
18
+ "5436"
19
+ elsif pg_version == "16"
20
+ "5437"
17
21
  else
18
22
  "5432"
19
23
  end
20
24
 
21
25
  ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/pg-locks-monitor-test"
26
+
27
+ RSpec.configure do |config|
28
+ Rails = {}
29
+
30
+ config.before(:each) do
31
+ # Mock Rails and its logger
32
+ logger_double = double("Logger")
33
+ allow(logger_double).to receive(:info)
34
+ allow(Rails).to receive(:logger).and_return(logger_double)
35
+ end
36
+
37
+ config.before(:suite) do
38
+ ActiveRecord::Base.establish_connection(ENV["DATABASE_URL"])
39
+ conn = RailsPgExtras.connection
40
+ conn.execute("CREATE TABLE IF NOT EXISTS pg_locks_monitor_users (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL);")
41
+ conn.execute("INSERT INTO pg_locks_monitor_users (name) VALUES ('Alice');")
42
+ conn.execute("INSERT INTO pg_locks_monitor_users (name) VALUES ('Bob');")
43
+ end
44
+
45
+ config.after(:suite) do
46
+ conn = RailsPgExtras.connection
47
+ conn.execute("DROP TABLE IF EXISTS pg_locks_monitor_users;")
48
+ end
49
+ end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg-locks-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-02 00:00:00.000000000 Z
11
+ date: 2024-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ruby-pg-extras
14
+ name: rails-pg-extras
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="