socketry / async-http

MIT License
298 stars 45 forks source link

Can I have more connections? #4

Closed yfractal closed 6 years ago

yfractal commented 6 years ago

I want the server sleep for a while before return the result.

Code as below:

class Server < Async::HTTP::Server
  def handle_request(request, peer, address)
    Async::Task.current.sleep(0.1)
    [200, {}, ["Hello World"]]
  end
end

Load testing results: wrk -c 16 -d 5s http://127.0.0.1:9294 got Requests/sec: 152.70, wrk -c 32 -d 5s http://127.0.0.1:9294 got Requests/sec: 305.01,

More connections more requests, looks good.

But I can't get too much connections, eg 256, the server will rise exception:

<internal:prelude>:136:in `__write_nonblock': Protocol wrong type for socket (Errno::EPROTOTYPE)
    from <internal:prelude>:136:in `write_nonblock'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/generic.rb:125:in `block in async_send'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/generic.rb:131:in `async'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/generic.rb:124:in `async_send'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/generic.rb:47:in `block in wrap_blocking_method'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/stream.rb:175:in `syswrite'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/stream.rb:76:in `flush'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-http-0.16.0/lib/async/http/protocol/http11.rb:134:in `write_response'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-http-0.16.0/lib/async/http/protocol/http11.rb:73:in `receive_requests'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-http-0.16.0/lib/async/http/protocol/http1.rb:59:in `receive_requests'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-http-0.16.0/lib/async/http/server.rb:48:in `block in accept'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-http-0.16.0/lib/async/http/server.rb:47:in `catch'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-http-0.16.0/lib/async/http/server.rb:47:in `accept'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/socket.rb:46:in `block in accept_each'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-io-1.6.1/lib/async/io/socket.rb:79:in `block in accept'
    from /Users/y/.rvm/gems/ruby-2.4.3/gems/async-1.5.0/lib/async/task.rb:74:in `block in initialize'

aysnc-http's version is "0.16.0".

ioquatix commented 6 years ago

There are two issues here.

The first one has been resolved but you will need to update your gems (async-io specifically) and Ruby has also fixed this issue: https://bugs.ruby-lang.org/issues/14713

The second issue is you are running on Mac OS X. The default file handle limit is

> ulimit -n
256

Try increasing this limit, e.g. ulimit -n 1000.

ioquatix commented 6 years ago

Hopefully the ruby issue will be back ported, but in any case, EPROTOTYPE is the same as EPIPE and is caused by the connection being terminated either by the remote end or the OS (hit file limit).

ioquatix commented 6 years ago

Thanks for your interest in the project, hopefully the advice about ulimit helps.