Skip to content

Intermittent "stream closed in another thread" on client disconnect #35

@nbekirov

Description

@nbekirov

Context

Using the client for short-lived RPC like connections, I need to:

  1. Establishing a connection.
  2. Sending data.
  3. Waiting for and reading a response.
  4. Disconnecting.

Expected

The disconnection process should complete without exceptions.

Actual

We intermittently observe an IOError: stream closed in another thread exception during the disconnection phase.

[
    [0] "org/jruby/RubyIO.java:3011:in `getc'",
    [1] "[..]/.rvm/gems/jruby-9.4.12.0/gems/websocket-client-simple-0.8.0/lib/websocket-client-simple/client.rb:48:in `block in connect'"
]

The bug

I believe this issue stems from a race condition during the close operation. The Client#close method directly calls @socket.close. Concurrently, the dedicated reader thread (@thread) might still be actively performing a blocking read operation, such as @socket.getc, within its loop.

If @socket.close is executed before the reader thread has a chance to check its termination condition (e.g., a @closed flag) or before it's forcefully shut down, the getc call on the now-closed socket results in the IOError: stream closed in another thread.

Possible fix

def close
  [..]

  @closed = true # first mark as closed
  @thread.join(1) if @thread # allow thread loop to finish interacting with the socket
  @socket.close if @socket # only now close the socket to prevent "stream closed in another thread"
  @socket = nil
  emit :__close
end

I'm willing to submit a PR if you think this is the way to go here.

Environment

jruby 9.4.12.0 (3.1.4) 2025-02-11 f4ab75096a OpenJDK 64-Bit Server VM 17.0.3+7 on 17.0.3+7 [x86_64-darwin]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions