Skip to content

Commit

Permalink
Fix socksify incompatibility
Browse files Browse the repository at this point in the history
Similarly to `resolv-replace`, `sockify` monkey patches
`TCPSocket#initialize` which causes an error if it is called with
`connect_timeout:`.

Rather than check only for `resolv-replace`'s specific method, we can
check if if the method's parameters have changed.
  • Loading branch information
sambostock committed Mar 8, 2024
1 parent 610a4b9 commit 0530aea
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 7 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ group :development, :test do

# For compatibility testing
gem 'resolv-replace', require: false
gem 'socksify', require: false
end

group :test do
Expand Down
13 changes: 6 additions & 7 deletions lib/dalli/socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,14 @@ def self.open(host, port, options = {})
end
end

TCPSOCKET_ORIGINAL_INITIALIZE_PARAMETERS = [[:rest].freeze].freeze
private_constant :TCPSOCKET_ORIGINAL_INITIALIZE_PARAMETERS

def self.create_socket_with_timeout(host, port, options)
# Check that TCPSocket#initialize was not overwritten by resolv-replace gem
# (part of ruby standard library since 3.0.0, should be removed in 3.4.0),
# as it does not handle keyword arguments correctly.
# To check this we are using the fact that resolv-replace
# aliases TCPSocket#initialize method to #original_resolv_initialize.
# https://github.com/ruby/resolv-replace/blob/v0.1.1/lib/resolv-replace.rb#L21
# Some gems like resolv-replace and socksify monkey patch TCPSocket and make it impossible to use the
# Ruby 3+ `connect_timeout:` keyword argument. If that's the case, we fallback to using the `Timeout` module.
if RUBY_VERSION >= '3.0' &&
!::TCPSocket.private_instance_methods.include?(:original_resolv_initialize)
::TCPSocket.instance_method(:initialize).parameters == TCPSOCKET_ORIGINAL_INITIALIZE_PARAMETERS
sock = new(host, port, connect_timeout: options[:socket_timeout])
yield(sock)
else
Expand Down
1 change: 1 addition & 0 deletions test/test_gem_compatibility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
describe 'gem compatibility' do
%w[
resolv-replace
socksify
].each do |gem_name|
it "passes smoke test with #{gem_name.inspect} gem required" do
memcached(:binary, rand(21_397..21_896)) do |_, port|
Expand Down

0 comments on commit 0530aea

Please sign in to comment.