Skip to content

Commit afff147

Browse files
committed
Clear previous changes before locking process for heartbeat
For example, in case of a previous heartbeat failed because of a DB issue (with SQLite depending on configuration, a `BusyException` is not rare) and we still have the unpersisted value in `last_heartbeat_at`, which means that `with_lock` will result in: ``` RuntimeError: Locking a record with unpersisted changes is not supported ``` Fixes #350
1 parent fdd7595 commit afff147

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

app/models/solid_queue/process.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ def self.register(**attributes)
2020
end
2121

2222
def heartbeat
23-
touch(:last_heartbeat_at)
23+
# Clear any previous changes before locking, for example, in case a previous heartbeat
24+
# failed because of a DB issue (with SQLite depending on configuration, a BusyException
25+
# is not rare) and we still have the unpersisted value
26+
restore_attributes
27+
with_lock { touch(:last_heartbeat_at) }
2428
end
2529

2630
def deregister(pruned: false)

lib/solid_queue/processes/registrable.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def stop_heartbeat
5353
end
5454

5555
def heartbeat
56-
process.with_lock { process.heartbeat }
56+
process.heartbeat
5757
rescue ActiveRecord::RecordNotFound
5858
self.process = nil
5959
wake_up

test/models/solid_queue/process_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,16 @@ class SolidQueue::ProcessTest < ActiveSupport::TestCase
6969
worker.stop
7070
end
7171
end
72+
73+
test "clear unregistered changes before locking for heartbeat" do
74+
process = SolidQueue::Process.register(kind: "Supervisor", pid: 43, name: "supervisor-43")
75+
76+
# Pretend a heartbeat failed to persist
77+
failed_heartbeat_at = 10.minutes.ago
78+
process.last_heartbeat_at = failed_heartbeat_at
79+
80+
assert_changes -> { process.last_heartbeat_at } do
81+
process.heartbeat
82+
end
83+
end
7284
end

0 commit comments

Comments
 (0)