Project

General

Profile

Actions

Bug #19412

open

Socket starts queueing and not responding after a certain amount of requests

Added by brodock (Gabriel Mazetto) almost 2 years ago. Updated over 1 year ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [arm64-darwin22]
[ruby-core:112213]

Description

Here is a an example code:

require 'socket'

PORT = 8080
BACKLOG = 50
LISTEN = '127.0.0.1'

def handle_connection(connection, _addrinfo)
  request = connection.gets

  puts request

  connection.write "HTTP/1.1 200\r\n"
  connection.write "Content-Type: text/html\r\n"
  connection.write "\r\n"
  connection.write "Hello world! Current time is #{Time.now}"

ensure
  connection.close
end

begin
  socket = Socket.new(:INET, :STREAM)
  socket.bind(Addrinfo.tcp(LISTEN, PORT))
  socket.listen(BACKLOG)

  puts "Requested queue size: #{BACKLOG} bigger then limit: #{Socket::SOMAXCONN}" if BACKLOG > Socket::SOMAXCONN

  loop do
    listening, = IO.select([socket])
    io, = listening
    connection, addrinfo = io.accept
    handle_connection(connection, addrinfo)
  end
ensure
  socket.close
end

This tries to simulate a TCP server that responds as if it was an HTTP server.

The amount of requests it can sustain seems to depend on the OS. On a Linux machine running ubuntu 20.04 I get something around 7.6K to 7.8K until it stops responding.

$ uname -a
Linux ... 5.17.5-x86_64-linode154 #1 SMP PREEMPT Mon May 2 15:07:22 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux

$ ab -n 20000 -c 50 http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
apr_pollset_poll: The timeout specified has expired (70007)
Total of 7883 requests completed

on MacOS Ventura I get around 16K:

$ uname -a
Darwin ... 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:04:44 PST 2022; root:xnu-8792.61.2~4/RELEASE_ARM64_T8103 arm64

$ ab -n 20000 -c 50 http://127.0.0.1:8080/     
                                                                                                                            
This is ApacheBench, Version 2.3 <$Revision: 1901567 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
apr_socket_recv: Operation timed out (60)
Total of 16375 requests completed

in both cases when that limit reaches, if I abort the program (CTRL-C) and try to run it again it takes a while until the port is released:

...
GET / HTTP/1.0
GET / HTTP/1.0
GET / HTTP/1.0
^Csocketserver.rb:29:in `select': Interrupt
	from socketserver.rb:29:in `block in <main>'
	from socketserver.rb:28:in `loop'
	from socketserver.rb:28:in `<main>'
$ ruby socketserver.rb                                                                                                                                                  
socketserver.rb:23:in `bind': Address already in use - bind(2) for 127.0.0.1:8080 (Errno::EADDRINUSE)
	from socketserver.rb:23:in `<main>'

After killing the process it seems no process is holding the port:

lsof -wni tcp:8080

Running the command above does not return anything (it does when the program is still running).

I think we may be failing to release something when interacting with the Socket on syscalls/kernel level and we endup filling up some queue/buffer that eventually gets freed.


Files

clipboard-202303161214-zhq7o.png (1.02 MB) clipboard-202303161214-zhq7o.png brodock (Gabriel Mazetto), 03/16/2023 11:14 AM
clipboard-202303161214-7xx91.png (683 KB) clipboard-202303161214-7xx91.png brodock (Gabriel Mazetto), 03/16/2023 11:14 AM
clipboard-202303161215-5wjbo.png (1.02 MB) clipboard-202303161215-5wjbo.png brodock (Gabriel Mazetto), 03/16/2023 11:15 AM
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0