Ruby mogilefs-client dev/users discussion/patches/bugs/help/...
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: mogilefs-client-public@bogomips.org
Subject: [PATCH] avoid excessive garbage on uploads with Ruby 2.2+
Date: Fri, 27 Jan 2017 02:56:28 +0000	[thread overview]
Message-ID: <20170127025628.4524-1-e@80x24.org> (raw)

This is a workaround for <https://bugs.ruby-lang.org/issues/13085>
since we use non-blocking sockets anyways.
---
 lib/mogilefs/socket_common.rb | 12 ++++++++++++
 test/test_cmogstored.rb       | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/lib/mogilefs/socket_common.rb b/lib/mogilefs/socket_common.rb
index 5ba8c10..ad66164 100644
--- a/lib/mogilefs/socket_common.rb
+++ b/lib/mogilefs/socket_common.rb
@@ -56,4 +56,16 @@ def read(size, buf = "", timeout = 5)
   def readpartial(size, buf = "", timeout = 5)
     timed_read(size, buf, timeout) or raise EOFError, "end of file reached"
   end
+
+  # workaround for https://bugs.ruby-lang.org/issues/13085
+  # (excessive garbage from IO#write)
+  # XXX maybe this can be fixed for Ruby 2.5 final, but maybe not:
+  # Update this when Ruby 2.5 is released on 2017-12-25
+  if RUBY_VERSION.to_f >= 2.2 && RUBY_VERSION.to_f <= 2.5
+    def write(buf)
+      # Blocking TCP writes would error out long before one day,
+      # and MogileFS won't allow file creations which take over a day.
+      timed_write(buf, 86400)
+    end
+  end
 end
diff --git a/test/test_cmogstored.rb b/test/test_cmogstored.rb
index 1036429..d112d38 100644
--- a/test/test_cmogstored.rb
+++ b/test/test_cmogstored.rb
@@ -1,6 +1,20 @@
 # -*- encoding: binary -*-
 require "./test/fresh"
 
+# The goal of this is to use a synthetic (non-IO) reader
+# to trigger the read/write loop of IO.copy_stream,
+# bypassing in-kernel mechanisms like sendfile for zero copy,
+# so we wrap the /dev/zero IO object:
+class Zero
+  def initialize
+    @in = File.open('/dev/zero', 'rb')
+  end
+
+  def read(len, buf)
+    @in.read(len, buf)
+  end
+end if File.readable?('/dev/zero')
+
 class Test_cmogstored < Test::Unit::TestCase
   include TestFreshSetup
   alias setup setup_mogilefs
@@ -26,6 +40,24 @@ def test_range_put_new_file
     assert_equal "a\nb\nc\nd\ne\n", client.get_file_data("puts")
   end
 
+  def test_garbage
+    add_host_device_domain
+    client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain,
+                                    :timeout => 60
+    nr = 1024 * 1024 * 1024
+    client.new_file('giant', :largefile => :stream,
+                    :content_length => nr) do |io|
+      assert_instance_of MogileFS::NewFile::Stream, io
+      zero = Zero.new
+      before = GC.count
+      wr = IO.copy_stream(zero, io, nr)
+      after = GC.count
+      assert_equal nr, wr
+      assert_in_delta before, after, 1
+    end
+  end if IO.respond_to?(:copy_stream) && defined?(Zero) &&
+         GC.respond_to?(:count) && ENV['TEST_EXPENSIVE'].to_i != 0
+
   def test_stream_new_file
     add_host_device_domain
     client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
-- 
EW


                 reply	other threads:[~2017-01-27  2:56 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=20170127025628.4524-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).