Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic Fork Safety #814

Merged
merged 1 commit into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/excon/connection.rb
Expand Up @@ -62,6 +62,7 @@ def logger=(logger)
# @option params [Class] :instrumentor Responds to #instrument as in ActiveSupport::Notifications
# @option params [String] :instrumentor_name Name prefix for #instrument events. Defaults to 'excon'
def initialize(params = {})
@pid = Process.pid
@data = Excon.defaults.dup
# merge does not deep-dup, so make sure headers is not the original
@data[:headers] = @data[:headers].dup
Expand Down Expand Up @@ -480,6 +481,11 @@ def sockets
@_excon_sockets ||= {}
@_excon_sockets.compare_by_identity

if @pid != Process.pid
@_excon_sockets.clear # GC will take care of closing sockets
@pid = Process.pid
end

if @data[:thread_safe_sockets]
# In a multi-threaded world, if the same connection is used by multiple
# threads at the same time to connect to the same destination, they may
Expand Down
16 changes: 16 additions & 0 deletions tests/connection_tests.rb
Expand Up @@ -36,6 +36,22 @@
response = connection.request(path: '/bar', method: 'get')
response.body == 'bar'
end

if ::Process.respond_to?(:fork)
connection_id = connection.send(:socket).object_id
test("fork safety") do
read, write = IO.pipe
pid = fork do
connection_id = connection.send(:socket).object_id
write.write(Marshal.dump(connection_id))
write.close
exit!(0)
end
Process.waitpid(pid)
child_connection_id = Marshal.load(read)
child_connection_id != connection_id
end
end
end
end

Expand Down