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

Closed stream / Bad file descriptor on TCP Server example #120

Open
renatolond opened this issue Aug 28, 2023 · 4 comments
Open

Closed stream / Bad file descriptor on TCP Server example #120

renatolond opened this issue Aug 28, 2023 · 4 comments

Comments

@renatolond
Copy link

Hi! Thank you for your work in Polyphony!

We were testing polyphony internally and we ran into some issues. To make sure it was not our code, we tried running the TCP Server example and we've got the same issue.

The issue is, if we run multiple clients connection to the server by running multiple nc loops, like so:

while true
   echo 'foo' | nc localhost 1234
end

Then, when we start the server, it runs for some time before giving us one of the following two errors:

tcpserver.rb:12:in `block in <main>': Bad file descriptor - Bad file descriptor (Errno::EBADF)
        from tcpserver.rb:10:in `<main>'

or

tcpserver.rb:12:in `block in <main>': closed stream (IOError)
        from tcpserver.rb:10:in `<main>'

The issue varies both in how long it takes to happen and which one happens first. (Also, the line number is a bit different because we added a few puts to see what was happening, but it happens without the puts there too), but it never takes longer than a few minutes (usually quite quick, actually).

To make matters more interesting, we tried the Http simple server that was recently committed and we didn't have the same issue at first, but we stripped it down further and further to get close to the example and when the code looks like this it gives us the issue:

# frozen_string_literal: true

require 'bundler/setup'
require 'polyphony'

PORT = 1234

server = TCPServer.open('127.0.0.1', PORT)
puts "pid #{Process.pid} Polyphony (#{Thread.current.backend.kind}) listening on port #{PORT}"

while (client = server.accept)
  spin do
    data = client.gets(8192)
    client << "you said: #{data}"
    client.close
  end
end

However, this does not seem to give the issue:

# frozen_string_literal: true

require 'bundler/setup'
require 'polyphony'

PORT = 4006

server = TCPServer.open('127.0.0.1', PORT)
puts "pid #{Process.pid} Polyphony (#{Thread.current.backend.kind}) listening on port #{PORT}"

def handle_close(client)
  spin do
    data = client.gets(8192)
    client << "you said: #{data}"
    client.close
  end
end

while (client = server.accept)
  handle_close(client)
end

Here's more details:
polyphony version: 1.6
Ruby version: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Uname: Linux 6.4.10-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 11 Aug 2023 11:03:36 +0000 x86_64 GNU/Linux

@clonezone
Copy link

Seeing similar results when attempting to connect to PostgreSQL on localhost. With or without

require 'polyphony/adapters/postgres'

I'm getting a Errno::EBADF Bad file descriptor - fstat(2) at pg-1.5.4/lib/pg/connection.rb:659.

@noteflakes
Copy link
Collaborator

Seeing similar results when attempting to connect to PostgreSQL on localhost. With or without

Can you include a working reproduction code?

@noteflakes
Copy link
Collaborator

The issue varies both in how long it takes to happen and which one happens first.

This seems to be a simple matter of variable shadowing. In the first example, the value of client will be rewritten as the loop is iterated consecutively:

while (client = server.accept)
  spin do
    data = client.gets(8192)
    client << "you said: #{data}"
    client.close
  end
end

You should either call spin in a separate method, as you do in the second example, or use TCPServer#accept_loop:

server.accept_loop do |client|
  spin do
    data = client.gets(8192)
    client << "you said: #{data}"
    client.close
  end
end

I'll make sure to update the bundled examples to work correctly.

@v-kolesnikov
Copy link

Seeing similar results when attempting to connect to PostgreSQL on localhost. With or without

Can you include a working reproduction code?

@noteflakes I've meet the same issue and made a reproduction code here: https://github.com/v-kolesnikov/bug-sequel-fibers/blob/polyphony/run.rb

Run log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants