From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-2.9 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, URIBL_BLOCKED shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: yahns-public@yhbt.net Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 5CEA21F7C7; Thu, 5 Feb 2015 20:47:33 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Cc: Eric Wong Subject: [PATCH] use the monotonic clock under Ruby 2.1+ Date: Thu, 5 Feb 2015 20:47:26 +0000 Message-Id: <1423169246-7243-2-git-send-email-e@80x24.org> List-Id: The monotonic clock is immune to time adjustments so it is not thrown off by misconfigured clocks. Process.clock_gettime also generates less garbage on 64-bit systems due to the use of Flonum. --- lib/yahns.rb | 13 +++++++++++++ lib/yahns/client_expire_generic.rb | 2 +- lib/yahns/fdmap.rb | 4 ++-- lib/yahns/server.rb | 6 +++--- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/yahns.rb b/lib/yahns.rb index a55837f..fd84223 100644 --- a/lib/yahns.rb +++ b/lib/yahns.rb @@ -55,6 +55,19 @@ module Yahns # :nodoc: class ClientTimeout < RuntimeError # :nodoc: end + + # try to use the monotonic clock in Ruby >= 2.1, it is immune to clock + # offset adjustments and generates less garbage (Float vs Time object) + begin + Process.clock_gettime(Process::CLOCK_MONOTONIC) + def self.now + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + rescue NameError, NoMethodError + def self.now # Ruby <= 2.0 + Time.now.to_f + end + end end # FIXME: require lazily diff --git a/lib/yahns/client_expire_generic.rb b/lib/yahns/client_expire_generic.rb index 7e80406..2beabb8 100644 --- a/lib/yahns/client_expire_generic.rb +++ b/lib/yahns/client_expire_generic.rb @@ -2,7 +2,7 @@ # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) module Yahns::ClientExpireGeneric # :nodoc: def __timestamp - Time.now.to_f + Yahns.now end def yahns_init diff --git a/lib/yahns/fdmap.rb b/lib/yahns/fdmap.rb index bac327e..d1f752a 100644 --- a/lib/yahns/fdmap.rb +++ b/lib/yahns/fdmap.rb @@ -81,7 +81,7 @@ class Yahns::Fdmap # :nodoc: def __expire(timeout) return if @count == 0 nr = 0 - now = Time.now.to_f + now = Yahns.now (now - @last_expire) >= 1.0 or return # don't expire too frequently # @fdmap_ary may be huge, so always expire a bunch at once to @@ -93,7 +93,7 @@ class Yahns::Fdmap # :nodoc: nr += c.yahns_expire(tout) end - @last_expire = Time.now.to_f + @last_expire = Yahns.now msg = timeout ? "timeout=#{timeout}" : "client_timeout" @logger.info("dropping #{nr} of #@count clients for #{msg}") end diff --git a/lib/yahns/server.rb b/lib/yahns/server.rb index e05a0e4..3b9addc 100644 --- a/lib/yahns/server.rb +++ b/lib/yahns/server.rb @@ -385,7 +385,7 @@ class Yahns::Server # :nodoc: def quit_enter(alive) if alive @logger.info("gracefully exiting shutdown_timeout=#@shutdown_timeout") - @shutdown_expire ||= Time.now + @shutdown_timeout + 1 + @shutdown_expire ||= Yahns.now + @shutdown_timeout + 1 else # drop connections immediately if signaled twice @logger.info("graceful exit aborted, exiting immediately") # we will still call any app-defined at_exit hooks here @@ -416,7 +416,7 @@ class Yahns::Server # :nodoc: # response bodies out (e.g. "tail -F") Oh well, have a timeout begin @wthr.delete_if { |t| t.join(0.01) } - end while @wthr[0] && Time.now <= @shutdown_expire + end while @wthr[0] && Yahns.now <= @shutdown_expire # cleanup, our job is done @queues.each(&:close).clear @@ -466,7 +466,7 @@ class Yahns::Server # :nodoc: def dropping(fdmap) if drop_acceptors[0] || fdmap.size > 0 - timeout = @shutdown_expire < Time.now ? -1 : @shutdown_timeout + timeout = @shutdown_expire < Yahns.now ? -1 : @shutdown_timeout fdmap.desperate_expire(timeout) true else -- EW