about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-02-05 20:46:14 +0000
committerEric Wong <e@80x24.org>2015-02-05 20:46:14 +0000
commiteb90ff89627a9001ae224f542e75919dc6fd96c9 (patch)
treefeeb68eaff34250b3e553a2ec87f478d6e75e822 /lib
parent8df14c20ad4f0b4ec9814ba858edd7e2f5a7ca72 (diff)
downloadyahns-eb90ff89627a9001ae224f542e75919dc6fd96c9.tar.gz
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/yahns.rb13
-rw-r--r--lib/yahns/client_expire_generic.rb2
-rw-r--r--lib/yahns/fdmap.rb4
-rw-r--r--lib/yahns/server.rb6
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