pg-locks-monitor 0.2.2 → 0.3.0

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
  SHA256:
3
- metadata.gz: 170cb606bd1459b6b1a7525ed08ce17f2aab0757703ec9a33f64dadeafdebf7c
4
- data.tar.gz: 503f92da91e4ca9d03999c45abb50507f8888b209df33c4a0e8b87e4cfdcb6b5
3
+ metadata.gz: a3bd2f4561c83a6d10a0120670bb89f8140f01f3afad7434fbea969e113cc542
4
+ data.tar.gz: 2fdb6e38890f1b085a32e72fee4d32eeb4e77e6a1f865737b2f3541d76d333ad
5
5
  SHA512:
6
- metadata.gz: 27d0ac7d4340b0de7739b6383ec203830ab92eb5b952cbc41b9447c6d41aa540d52522f067bd1cdd857802c6c8a49a16ddaff9b95f2c51beed0f3e3b8dae6022
7
- data.tar.gz: b4594194b88910f3fcc2e9c7e79205147076ff0fcd6ccf79ca2bc0e7e4290a3d5167e041f7660e72ecdfff1e7fe598684f103256a976582c83c884b8639dc77d
6
+ metadata.gz: 1396e94b66ae62db3ee552855cfe8b2e7d10c5efdf87f323bc889c8fb17530cf9076e6239f2dc9713907f28ddbb5de602f4baa507b38621419534be545be83c6
7
+ data.tar.gz: a9bafef4918812b931737a0096cd2096181512e6eb5b35585b4e5caf50d7230f1dca4b8b2a37eeac7b521968577cf915cd97bff1f79b757dc909b5d1a4eb4f18
@@ -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
@@ -10,7 +10,7 @@ module PgLocksMonitor
10
10
  in_format: :hash,
11
11
  ).select do |lock|
12
12
  if (age = lock.fetch("age"))
13
- (ActiveSupport::Duration.parse(age).to_f * 1000) > configuration.locks_min_duration_ms
13
+ DurationHelper.parse_to_ms(age) > configuration.locks_min_duration_ms
14
14
  end
15
15
  end.select(&configuration.locks_filter_proc)
16
16
  .first(configuration.locks_limit)
@@ -20,13 +20,18 @@ module PgLocksMonitor
20
20
  end
21
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
+ DurationHelper.parse_to_ms(block.fetch("blocking_duration")) > configuration.blocking_min_duration_ms
24
24
  end.select(&configuration.blocking_filter_proc)
25
25
  .first(configuration.locks_limit)
26
26
 
27
27
  if blocking.count > 0 && configuration.monitor_blocking
28
28
  configuration.notifier_class.call(blocking)
29
29
  end
30
+
31
+ {
32
+ locks: locks,
33
+ blocking: blocking,
34
+ }
30
35
  end
31
36
 
32
37
  def self.configuration
@@ -36,6 +41,22 @@ module PgLocksMonitor
36
41
  def self.configure
37
42
  yield(configuration)
38
43
  end
44
+
45
+ class DurationHelper
46
+ require "date"
47
+
48
+ def self.parse_to_ms(duration_str)
49
+ time = DateTime.strptime(duration_str, "%H:%M:%S.%N")
50
+ hours = time.hour
51
+ minutes = time.minute
52
+ seconds = time.second
53
+ nanoseconds = time.second_fraction * (10 ** 9)
54
+
55
+ total_ms = (hours * 3600 * 1000) + (minutes * 60 * 1000) + (seconds * 1000) + (nanoseconds / 1_000_000).to_i
56
+
57
+ total_ms
58
+ end
59
+ end
39
60
  end
40
61
 
41
62
  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.0"
5
5
  end
@@ -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,33 @@
3
3
  require "spec_helper"
4
4
 
5
5
  describe PgLocksMonitor do
6
+ def spawn_update
7
+ Thread.new do
8
+ conn = PG.connect(ENV["DATABASE_URL"])
9
+ conn.exec("
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
+ sleep 1
29
+
30
+ result = PgLocksMonitor.snapshot!
31
+ expect(result.fetch(:locks).count).to eq(5)
32
+ expect(result.fetch(:blocking).count).to eq(1)
33
+ end
12
34
  end
13
35
  end
data/spec/spec_helper.rb CHANGED
@@ -14,8 +14,35 @@ 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
+ conn = RubyPgExtras.connection
39
+ conn.exec("CREATE TABLE IF NOT EXISTS pg_locks_monitor_users (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL);")
40
+ conn.exec("INSERT INTO pg_locks_monitor_users (name) VALUES ('Alice');")
41
+ conn.exec("INSERT INTO pg_locks_monitor_users (name) VALUES ('Bob');")
42
+ end
43
+
44
+ config.after(:suite) do
45
+ conn = RubyPgExtras.connection
46
+ conn.exec("DROP TABLE IF EXISTS pg_locks_monitor_users;")
47
+ end
48
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
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.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb