From be3e4ab3f55afb1f89bdd702f069b44a8bcef8e7 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 18 Feb 2020 13:50:15 +0000 Subject: [PATCH] DEV: Report simultaneous use of PG::Connection objects --- .../initializers/000-trace_pg_connections.rb | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/config/initializers/000-trace_pg_connections.rb b/config/initializers/000-trace_pg_connections.rb index fcda5bb611f..c652f64985d 100644 --- a/config/initializers/000-trace_pg_connections.rb +++ b/config/initializers/000-trace_pg_connections.rb @@ -24,6 +24,8 @@ if ENV["TRACE_PG_CONNECTIONS"] FileUtils.mkdir_p(TRACE_DIR) @trace_filename = "#{TRACE_DIR}/#{Process.pid}_#{self.object_id}.txt" trace File.new(@trace_filename, "w") + @access_log_mutex = Mutex.new + @accessor_thread = nil end end @@ -34,5 +36,47 @@ if ENV["TRACE_PG_CONNECTIONS"] end end + def log_access(&blk) + @access_log_mutex.synchronize do + if !@accessor_thread.nil? + Rails.logger.error <<~STRING + PG Clash: A connection is being accessed from two locations + + #{@accessor_thread} was using the connection. Backtrace: + + #{@accessor_thread.backtrace.join("\n")} + + #{Thread.current} is now attempting to use the connection. Backtrace: + + #{Thread.current.backtrace.join("\n")} + STRING + end + @accessor_thread = Thread.current + end + result = yield + @access_log_mutex.synchronize do + @accessor_thread = nil + end + result + end + end) + + class PG::Connection + LOG_ACCESS_METHODS = [:exec, :sync_exec, :async_exec, + :sync_exec_params, :async_exec_params, + :sync_prepare, :async_prepare, + :sync_exec_prepared, :async_exec_prepared, + ] + + LOG_ACCESS_METHODS.each do |method| + new_method = "#{method}_without_logging".to_sym + alias_method new_method, method + + define_method(method) do |*args, &blk| + log_access { send(new_method, *args, &blk) } + end + end + end + end