From eb90ff89627a9001ae224f542e75919dc6fd96c9 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 5 Feb 2015 20:46:14 +0000 Subject: use the monotonic clock under Ruby 2.1+ 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(-) (limited to 'lib') 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 -- cgit v1.2.3-24-ge0c7