Skip to content

Commit

Permalink
Fix possible deadlock in the PostgreSQL specs
Browse files Browse the repository at this point in the history
Force the lock_timeout and table_exists? queries to use the same
connection, otherwise they could use two different connections,
and the table_exists? query will hang until the database default
lock timeout.

This deadlock in the specs could only be hit if there were
3+ available connections in the connection pool before the
spec was running (1 for the lock, 1 for the lock_timeout,
1 for the table_exists). If 0-2 available connections were
in the pool, then 1 would be taken by the lock, and the 2nd
would be used for both the lock_timeout and table_exists?.
  • Loading branch information
jeremyevans committed Jul 2, 2024
1 parent 0c7294e commit 93987e6
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions spec/adapters/postgres_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,16 @@ def c.exec_prepared(*); super; nil end
t = []
@db[:test].lock('ACCESS EXCLUSIVE') do
Thread.new do
@db.run "SET lock_timeout = 1"
t << @db.table_exists?(:test)
@db.synchronize do
@db.run "SET lock_timeout = 1"
t << @db.table_exists?(:test)
end
end.join
Thread.new do
@db.run "SET statement_timeout = 1"
t << @db.table_exists?(:test)
@db.synchronize do
@db.run "SET statement_timeout = 1"
t << @db.table_exists?(:test)
end
end.join
end
t.must_equal [true, true]
Expand Down

0 comments on commit 93987e6

Please sign in to comment.