diff --git a/spec/support/pg_locks.rb b/spec/support/pg_locks.rb index fdafe883c..c615e76a9 100644 --- a/spec/support/pg_locks.rb +++ b/spec/support/pg_locks.rb @@ -5,8 +5,19 @@ def initialize_type_map(map = type_map) end end +PostgresNoticeError = Class.new(StandardError) + ActiveSupport.on_load :active_record do ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend PostgresXidExtension + + ActiveRecord::ConnectionAdapters::AbstractAdapter.set_callback :checkout, :before, lambda { |conn| + raw_connection = conn.raw_connection + next unless raw_connection.class.name == "PG::Connection" + + raw_connection.set_notice_receiver do |result| + raise PostgresNoticeError, result.error_message + end + } end class PgLock < ActiveRecord::Base @@ -23,11 +34,19 @@ def unlock SQL self.class.unscoped.exists?([where_sql, classid, objid]) end + + def unlock! + where_sql = <<~SQL.squish + pg_terminate_backend(?) + SQL + self.class.unscoped.exists?([where_sql, pid]) + end end RSpec.configure do |config| config.before do - PgLock.advisory_lock.each(&:unlock) if PgLock.advisory_lock.count > 0 + PgLock.advisory_lock.owns.each(&:unlock) if PgLock.advisory_lock.owns.count > 0 + PgLock.advisory_lock.others.each(&:unlock!) if PgLock.advisory_lock.others.count > 0 expect(PgLock.advisory_lock.count).to eq(0), "Existing advisory locks BEFORE test run" end