From: Eric Wong <e@80x24.org>
To: mogilefs-client-public@bogomips.org
Subject: [PATCH] socket/pure_ruby: use `:exception=>false' on Ruby 2.1+
Date: Wed, 4 Nov 2015 21:42:44 +0000 [thread overview]
Message-ID: <20151104214244.8688-1-e@80x24.org> (raw)
This feature allows us to avoid expensive exceptions when doing
non-blocking I/O without relying on horrible hacks like kgio.
---
lib/mogilefs/socket/pure_ruby.rb | 87 +++++++++++++++++++++++++++-------------
1 file changed, 60 insertions(+), 27 deletions(-)
diff --git a/lib/mogilefs/socket/pure_ruby.rb b/lib/mogilefs/socket/pure_ruby.rb
index e74bbef..d57a7c0 100644
--- a/lib/mogilefs/socket/pure_ruby.rb
+++ b/lib/mogilefs/socket/pure_ruby.rb
@@ -27,16 +27,6 @@ class MogileFS::Socket < Socket
IO.select(nil, [ self ], nil, timeout)
end unless self.instance_methods.include?(:wait_writable) # Ruby <2.0.0
- def timed_read(len, dst = "", timeout = 5)
- begin
- return read_nonblock(len, dst)
- rescue Errno::EAGAIN
- wait(timeout) or unreadable_socket!(timeout)
- rescue EOFError
- return
- end while true
- end
-
def timed_peek(len, dst, timeout = 5)
begin
rc = recv_nonblock(len, Socket::MSG_PEEK)
@@ -47,26 +37,69 @@ class MogileFS::Socket < Socket
dst.replace("")
return
end while true
+ rescue EOFError
+ nil
end
- def timed_write(buf, timeout = 5)
- written = 0
- expect = buf.bytesize
- begin
- rc = write_nonblock(buf)
- return expect if rc == buf.bytesize
- written += rc
+ # write_nonblock and read_nonblock support `exception: false`
+ if RUBY_VERSION.to_f >= 2.1
+ def timed_read(len, dst = "", timeout = 5)
+ case rc = read_nonblock(len, dst, :exception => false)
+ when String
+ return rc
+ when :wait_readable
+ wait(timeout) or unreadable_socket!(timeout)
+ when nil
+ return
+ end while true
+ rescue EOFError
+ nil
+ end
+
+ def timed_write(buf, timeout = 5)
+ written = 0
+ expect = buf.bytesize
+ case rc = write_nonblock(buf, :exception => false)
+ when Integer
+ return expect if rc == buf.bytesize
+ written += rc
+ buf = buf.byteslice(rc, buf.bytesize) # Ruby 1.9.3+
+ when :wait_writable
+ wait_writable(timeout) or request_truncated!(written, expect, timeout)
+ end while true
+ end
+ else # Ruby 1.8.7 - 2.0.0
+ def timed_read(len, dst = "", timeout = 5)
+ begin
+ return read_nonblock(len, dst)
+ rescue Errno::EAGAIN
+ wait(timeout) or unreadable_socket!(timeout)
+ rescue EOFError
+ return
+ end while true
+ rescue EOFError
+ nil
+ end
- if buf.respond_to?(:byteslice)
- buf = buf.byteslice(rc, buf.bytesize)
- else
- if buf.respond_to?(:encoding) && buf.encoding != Encoding::BINARY
- buf = buf.dup.force_encoding(Encoding::BINARY)
+ def timed_write(buf, timeout = 5)
+ written = 0
+ expect = buf.bytesize
+ begin
+ rc = write_nonblock(buf)
+ return expect if rc == buf.bytesize
+ written += rc
+
+ if buf.respond_to?(:byteslice) # Ruby 1.9.3+
+ buf = buf.byteslice(rc, buf.bytesize)
+ else
+ if buf.respond_to?(:encoding) && buf.encoding != Encoding::BINARY
+ buf = buf.dup.force_encoding(Encoding::BINARY)
+ end
+ buf = buf.slice(rc, buf.bytesize)
end
- buf = buf.slice(rc, buf.bytesize)
- end
- rescue Errno::EAGAIN
- wait_writable(timeout) or request_truncated!(written, expect, timeout)
- end while true
+ rescue Errno::EAGAIN
+ wait_writable(timeout) or request_truncated!(written, expect, timeout)
+ end while true
+ end
end
end
--
EW
reply other threads:[~2015-11-04 21:42 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/mogilefs-client/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151104214244.8688-1-e@80x24.org \
--to=e@80x24.org \
--cc=mogilefs-client-public@bogomips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhbt.net/mogilefs-client.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).