From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.0 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 2E69B206A4 for ; Sat, 29 Oct 2016 01:31:46 +0000 (UTC) From: Eric Wong To: http_spew-public@bogomips.org Subject: [PATCH] use monotonic clock for timing Date: Sat, 29 Oct 2016 01:31:46 +0000 Message-Id: <20161029013146.4570-1-e@80x24.org> List-Id: This makes us immune to system clock changes and has a nice side effect of reducing runtime garbage. The downside is the additional cache overhead for extra constant lookups. This requires Ruby 2.1 or later, but this is an unimportant project and we can get away without caring for 2.0 and earlier. --- README | 1 - http_spew.gemspec | 1 + lib/http_spew/class_methods.rb | 8 ++++---- lib/http_spew/request.rb | 8 ++++---- test/test_input_spray_with_md5.rb | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README b/README index c8c2828..74aadd5 100644 --- a/README +++ b/README @@ -11,7 +11,6 @@ Use HTTP Spew if you wish you could kinda multicast with HTTP... * No support for DNS resolution (WONTFIX, ever) * No support for HTTPS * No support for keepalive (yet?) -* No support for Ruby 1.8, this is Ruby 1.9-only * Not remotely RFC-compliant * Messes up analytics/reporting on servers * Resets server connections diff --git a/http_spew.gemspec b/http_spew.gemspec index 4aafc26..4bede9b 100644 --- a/http_spew.gemspec +++ b/http_spew.gemspec @@ -18,5 +18,6 @@ Gem::Specification.new do |s| s.add_dependency(%q, [ "~> 0.3", ">= 0.3.1"]) s.add_dependency(%q, "~> 2.6") s.add_development_dependency(%q, "~> 1.0") + s.required_ruby_version = '>= 2.1' s.licenses = %w(GPL-2.0+) end diff --git a/lib/http_spew/class_methods.rb b/lib/http_spew/class_methods.rb index 938b55c..f068f6b 100644 --- a/lib/http_spew/class_methods.rb +++ b/lib/http_spew/class_methods.rb @@ -41,11 +41,11 @@ module HTTP_Spew::ClassMethods end def with_timeout(t) - t0 = Time.now + t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) yield - ensure - t[0] -= Time.now - t0 - t[0] = 0.0 if t[0] < 0 + ensure + t[0] -= Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0 + t[0] = 0.0 if t[0] < 0 end # Returns an array of requests that are complete, including those diff --git a/lib/http_spew/request.rb b/lib/http_spew/request.rb index 16db39d..63bac64 100644 --- a/lib/http_spew/request.rb +++ b/lib/http_spew/request.rb @@ -55,17 +55,17 @@ class HTTP_Spew::Request # returns a 3-element Rack response array on successful completion # returns an Exception if one was raised def run(timeout) - t0 = Time.now + t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) buf, @buf = @buf, nil # make inspect nicer @to_io.write(buf) if @input @to_io.write(buf) while @input.read(0x4000, buf) end - timeout -= (Time.now - t0) + timeout -= (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0) while :wait_readable == (rv = read_response) && timeout >= 0.0 - t0 = Time.now + t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) @to_io.kgio_wait_readable(timeout) if timeout > 0.0 - timeout -= (Time.now - t0) + timeout -= (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0) end rv rescue => e diff --git a/test/test_input_spray_with_md5.rb b/test/test_input_spray_with_md5.rb index 1e030e0..37819e9 100644 --- a/test/test_input_spray_with_md5.rb +++ b/test/test_input_spray_with_md5.rb @@ -60,9 +60,9 @@ class TestInputSprayWithMD5 < Test::Unit::TestCase HTTP_Spew::Request.new(@env, md5_input, @sockaddr) end assert_equal @nr, reqs.size - t0 = Time.now + t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) rv = HTTP_Spew.wait_mt reqs.size, reqs, 3600 - elapsed = Time.now - t0 + elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0 assert(elapsed <= 30, "took too long: #{elapsed}s") assert_equal @nr, rv.size rv.each { |r| -- EW