Dmytro Shteflyuk created THRIFT-6112:
----------------------------------------

             Summary: Ruby Socket should reject duplicate opens
                 Key: THRIFT-6112
                 URL: https://issues.apache.org/jira/browse/THRIFT-6112
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Library
            Reporter: Dmytro Shteflyuk
            Assignee: Dmytro Shteflyuk


h3. Problem

Calling {{Thrift::Socket#open}} on an already-open transport creates a second 
TCP connection and replaces the transport's {{@handle}}. The first connection 
is not closed before its handle becomes unreachable through the transport.

As a result, {{close}} only closes the replacement connection. The original 
connection remains open until some other owner closes it or Ruby eventually 
reclaims it.

This ticket is scoped to the TCP {{Thrift::Socket}} transport. Transports that 
override {{open}} have separate lifecycle implementations and are not changed 
here.

h3. Client impact

Applications that accidentally open the same transport twice—for example, 
through overlapping connection setup or retry paths—can leave an unused TCP 
connection open on both the client and server. This consumes a file descriptor 
and may leave an unexpected server-side session active even after the transport 
itself is closed.

h3. Reproduction

>From the repository root:

{code:bash}
ruby -Ilib/rb/lib /tmp/thrift_double_open.rb
{code}

With {{/tmp/thrift_double_open.rb}} containing:

{code:ruby}
require 'socket'
require 'thrift'

server = TCPServer.new('127.0.0.1', 0)
transport = Thrift::Socket.new('127.0.0.1', server.local_address.ip_port)

transport.open
first_peer = server.accept
first_handle = transport.handle

transport.open
second_peer = server.accept

puts "first_handle_closed=#{first_handle.closed?}"
puts "second_handle_same=#{transport.handle.equal?(first_handle)}"

transport.close
first_handle.close
first_peer.close
second_peer.close
server.close
{code}

The current output is:

{code}
first_handle_closed=false
second_handle_same=false
{code}

The transport has replaced its handle while leaving the first connection open.

h3. Expected behavior

Opening an already-open TCP transport should raise 
{{Thrift::TransportException}} with type {{ALREADY_OPEN}}. The existing live 
connection and handle should remain unchanged so the caller can continue using 
or explicitly close that transport.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to