Skip to content

Commit

Permalink
Close open connections from parent after fork
Browse files Browse the repository at this point in the history
DRb::DRbConn keeps a global pool of open connections which is shared by
child processes when they are forked from a parent.  If this parent
executes a DRb call prior to forking a child process the child picks up
this open connection and uses it which can cause replies from the server
to go to the wrong DRb client.

There is a long standing ruby bug https://bugs.ruby-lang.org/issues/2718
which describes the issue and has reproducer code attached.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1385038
  • Loading branch information
agrare committed Feb 6, 2018
1 parent 03f19ed commit 271ae40
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions app/models/miq_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ def self.before_fork
def self.after_fork
close_pg_sockets_inherited_from_parent
DRb.stop_service
close_drb_pool_connections
renice(Process.pid)
end

Expand All @@ -330,6 +331,23 @@ def self.close_pg_sockets_inherited_from_parent
end
end

# Close all open DRb connections so that connections in the parent's memory space
# which is shared due to forking the child process do not pollute the child's DRb
# connection pool. This can lead to errors when the children connect to a server
# and get an incorrect response back.
#
# ref: https://bugs.ruby-lang.org/issues/2718
def self.close_drb_pool_connections
require 'drb'

# HACK: DRb doesn't provide an interface to close open pool connections.
#
# Once that is added this should be replaced.
DRb::DRbConn.instance_variable_get(:@mutex).synchronize do
DRb::DRbConn.instance_variable_get(:@pool).each(&:close)
end
end

# Overriding queue_name as now some queue names can be
# arrays of names for some workers not just a singular name.
# We use JSON.parse as the array of names is stored as a string.
Expand Down

0 comments on commit 271ae40

Please sign in to comment.