Skip to content

Commit a3e7ff4

Browse files
Add tests for lock timeout increase
1 parent adab2ba commit a3e7ff4

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

lib/safe-pg-migrations/plugins/statement_retrier.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,28 @@ def retry_if_lock_timeout
2525
raise
2626
end
2727

28-
increase_lock_timeout unless SafePgMigrations.config.lock_timeout.nil?
29-
3028
retry_delay = SafePgMigrations.config.retry_delay
3129
Helpers::Logger.say "Retrying in #{retry_delay} seconds...", sub_item: true
30+
31+
increase_lock_timeout unless SafePgMigrations.config.lock_timeout.nil?
32+
3233
sleep retry_delay
3334
Helpers::Logger.say 'Retrying now.', sub_item: true
3435
retry
3536
end
3637
end
3738

3839
def increase_lock_timeout
39-
SafePgMigrations.config.lock_timeout += lock_timeout_step
40+
Helpers::Logger.say " Increasing the lock timeout... Currently set to #{SafePgMigrations.config.lock_timeout}", sub_item: true
41+
SafePgMigrations.config.lock_timeout = (SafePgMigrations.config.lock_timeout + lock_timeout_step)
4042
unless SafePgMigrations.config.lock_timeout < SafePgMigrations.config.max_lock_timeout_for_retry
4143
SafePgMigrations.config.lock_timeout = SafePgMigrations.config.max_lock_timeout_for_retry
4244
end
45+
Helpers::Logger.say " Lock timeout is now set to #{SafePgMigrations.config.lock_timeout}", sub_item: true
4346
end
4447

4548
def lock_timeout_step
46-
(SafePgMigrations.config.max_lock_timeout_for_retry - SafePgMigrations.config.lock_timeout) / SafePgMigrations.config.max_tries
49+
@lock_timeout_step ||= (SafePgMigrations.config.max_lock_timeout_for_retry - SafePgMigrations.config.lock_timeout) / (SafePgMigrations.config.max_tries - 1)
4750
end
4851
end
4952
end

test/statement_retrier_test.rb

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,8 @@
44

55
class StatementRetrierTest < Minitest::Test
66
def test_retry_if_lock_timeout
7-
@migration =
8-
Class.new(ActiveRecord::Migration::Current) do
9-
def up
10-
connection.send(:retry_if_lock_timeout) do
11-
raise ActiveRecord::LockWaitTimeout, 'PG::LockNotAvailable: ERROR: canceling statement due to lock timeout'
12-
end
13-
end
14-
end.new
7+
calls = calls_for_lock_timeout_migration
158

16-
@connection.expects(:sleep).times(4)
17-
calls =
18-
record_calls(@migration, :write) do
19-
run_migration
20-
flunk 'run_migration should raise'
21-
rescue StandardError => e
22-
assert_instance_of ActiveRecord::LockWaitTimeout, e.cause
23-
assert_includes e.cause.message, 'canceling statement due to lock timeout'
24-
end
259
assert_equal [
2610
' -> Retrying in 60 seconds...',
2711
' -> Retrying now.',
@@ -49,7 +33,54 @@ def test_statement_retry
4933
], calls[7..9]
5034
end
5135

52-
def lock_timout_increase_on_retry
36+
def test_lock_timout_increase_on_retry
37+
SafePgMigrations.config.lock_timeout = 0.1.seconds
38+
39+
calls = calls_for_lock_timeout_migration
40+
41+
assert_equal [
42+
' -> Retrying in 60 seconds...',
43+
' -> Increasing the lock timeout... Currently set to 0.1',
44+
' -> Lock timeout is now set to 0.325',
45+
' -> Retrying now.',
46+
' -> Retrying in 60 seconds...',
47+
' -> Increasing the lock timeout... Currently set to 0.325',
48+
' -> Lock timeout is now set to 0.55',
49+
' -> Retrying now.',
50+
' -> Retrying in 60 seconds...',
51+
' -> Increasing the lock timeout... Currently set to 0.55',
52+
' -> Lock timeout is now set to 0.775',
53+
' -> Retrying now.',
54+
' -> Retrying in 60 seconds...',
55+
' -> Increasing the lock timeout... Currently set to 0.775',
56+
' -> Lock timeout is now set to 1',
57+
' -> Retrying now.',
58+
], calls[1..-1].map(&:first)
59+
60+
end
61+
62+
private
63+
64+
def calls_for_lock_timeout_migration
65+
@migration = Class.new(ActiveRecord::Migration::Current) do
66+
def up
67+
connection.send(:retry_if_lock_timeout) do
68+
raise ActiveRecord::LockWaitTimeout, 'PG::LockNotAvailable: ERROR: canceling statement due to lock timeout'
69+
end
70+
end
71+
end.new
72+
73+
@connection.expects(:sleep).times(4)
74+
75+
calls =
76+
record_calls(@migration, :write) do
77+
run_migration
78+
flunk 'run_migration should raise'
79+
rescue StandardError => e
80+
assert_instance_of ActiveRecord::LockWaitTimeout, e.cause
81+
assert_includes e.cause.message, 'canceling statement due to lock timeout'
82+
end
5383

84+
calls
5485
end
5586
end

0 commit comments

Comments
 (0)