Feature #10532
closed[PATCH] accept_nonblock supports "exception: false"
Description
This is analogous to functionality found in IO#read_nonblock and
IO#wait_nonblock. Raising exceptions for common failures on
non-blocking servers is expensive and makes $DEBUG too noisy.
This also increases performance slightly, see patch for benchmarks.
I also intend to support this in the "openssl" extension as well as
supporting connect_nonblock if this is accepted.
Files
Updated by normalperson (Eric Wong) about 10 years ago
normalperson@yhbt.net wrote:
I also intend to support this in the "openssl" extension as well as
accept_nonblock for openssl:
http://80x24.org/spew/m/f453956f3b04d2445e54d3141cc564a2529ce0f7.txt
Also pushed to the "more_nonblock" branch on git://80x24.org/ruby
Updated by matz (Yukihiro Matsumoto) almost 10 years ago
- Status changed from Open to Feedback
I like the basic idea. Once someone review the patch (Nobu, are you willing?), it's OK to merge.
Matz.
Updated by nobu (Nobuyoshi Nakada) almost 10 years ago
Why only OpenSSL?
Doesn't Socket#accept_nonblock
need it?
Updated by nobu (Nobuyoshi Nakada) almost 10 years ago
Sorry, I've read the second link only.
Both look fine.
Updated by Anonymous almost 10 years ago
- Status changed from Feedback to Closed
- % Done changed from 0 to 100
Applied in changeset r49948.
accept_nonblock supports "exception: false"
This is analogous to functionality found in IO#read_nonblock and
IO#wait_nonblock. Raising exceptions for common failures on
non-blocking servers is expensive and makes $DEBUG too noisy.
Benchmark results:
user system total real
default 2.790000 0.870000 3.660000 ( 3.671597)
exception: false 1.120000 0.800000 1.920000 ( 1.922032)
exception: false (cached arg) 0.820000 0.770000 1.590000 ( 1.589267)
--------------------- benchmark script ------------------------
require 'socket'
require 'benchmark'
require 'tmpdir'
nr = 1000000
Dir.mktmpdir('nb_bench') do |path|
sock_path = "#{path}/test.sock"
s = UNIXServer.new(sock_path)
Benchmark.bmbm do |x|
x.report("default") do
nr.times do
begin
s.accept_nonblock
rescue IO::WaitReadable
end
end
end
x.report("exception: false") do
nr.times do
begin
s.accept_nonblock(exception: false)
rescue IO::WaitReadable
abort "should not raise"
end
end
end
x.report("exception: false (cached arg)") do
arg = { exception: false }
nr.times do
begin
s.accept_nonblock(arg)
rescue IO::WaitReadable
abort "should not raise"
end
end
end
end
end
- ext/socket/init.c (rsock_s_accept_nonblock):
support exception: false
[ruby-core:66385] [Feature #10532] - ext/socket/init.c (rsock_init_socket_init): define new symbols
- ext/socket/rubysocket.h: adjust prototype
- ext/socket/socket.c (sock_accept_nonblock): support exception: false
- ext/openssl/ossl_ssl.c (ossl_ssl_accept_nonblock): ditto
- ext/socket/socket.c (Init_socket): adjust accept_nonblock definition
- ext/openssl/ossl_ssl.c (Init_ossl_ssl): ditto
- ext/socket/tcpserver.c (rsock_init_tcpserver): ditto
- ext/socket/unixserver.c (rsock_init_unixserver): ditto
- ext/socket/tcpserver.c (tcp_accept_nonblock): adjust
rsock_s_accept_nonblock call - ext/socket/unixserver.c (unix_accept_nonblock): ditto
- ext/openssl/ossl_ssl.c (ossl_start_ssl): support no_exception
- ext/openssl/ossl_ssl.c (ossl_ssl_connect): adjust ossl_start_ssl call
- ext/openssl/ossl_ssl.c (ossl_ssl_connect_nonblock): ditto
- ext/openssl/ossl_ssl.c (ossl_ssl_accept): ditto
- test/socket/test_nonblock.rb (test_accept_nonblock): test for
"exception :false" - test/socket/test_tcp.rb (test_accept_nonblock): new test
- test/socket/test_unix.rb (test_accept_nonblock): ditto
- test/openssl/test_pair.rb (test_accept_nonblock_no_exception): ditto