Project

General

Profile

Actions

Bug #15636

closed

::Socket#to_a hangs Ruby interpreter

Added by arturmoczulski (Artur Moczulski) about 5 years ago. Updated about 5 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:91664]

Description

ruby -v: ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-linux]

Reproducible script

require 'socket'
s = Socket.new(:INET, :STREAM)
s.connect Socket.pack_sockaddr_in(80, 'example.com')
s.to_a

Result

Ruby hangs infinitely.

Expected

Socket instance converted to an array representation (whatever that might be). I expect this as to_a comes from the ::Enumerable mixin included in ::IO - one of ::Socket's parent classes.

Background

I came across this while working on Redis client serialization in our Rollbar SDK here: https://github.com/rollbar/rollbar-gem/blob/master/spec/rollbar/item_spec.rb#L682-L686. This becomes a problem when you try to use ActiveSupport JSON to serialize a Redis client instance:

activesupport: v4.2.8
redis: v4.1.0

  1. Object#as_json in active_support/core_ext/object/json.rb#50 <- calls as_json on the instance_values

  2. Hash@as_json in active_support/core_ext/object/json.rb#159 <- calls as_json

  3. Enumerable#as_json in lib/active_support/core_ext/object/json.rb#128 <- calls to_a on a Redis::Connection::TCPSocket object

Updated by shyouhei (Shyouhei Urabe) about 5 years ago

  • Status changed from Open to Rejected

I don't think it's a bug of socket library.

arturmoczulski (Artur Moczulski) wrote:

Result

Ruby hangs infinitely.

No, it desn't. It just takes a long time. It properly exits after 60 seconds (from my machine at least).

Expected

Socket instance converted to an array representation (whatever that might be). I expect this as to_a comes from the ::Enumerable mixin included in ::IO - one of ::Socket's parent classes.

Right. This expectation, by far, is accurate.

What is the key point here is that IO's to_a method is ultimately IO#each_line, which reads everything from the IO to split into lines.

In the reproduction code the socket connected to example.com:80, then waits for some response. But in HTTP, you have to send some request before you expect a response. So the remote endpoint waits for your program to send something. After some period of time the remote side gives up. It closes the connection and everything resumes as expected.

Background

I am not sure if your problem ultimately sources this behaviour. Because this is a pretty much standardised protocol.

Actions

Also available in: Atom PDF

Like0
Like0