summary refs log tree commit
diff options
context:
space:
mode:
authorAndrew Marshall <andrew@johnandrewmarshall.com>2014-11-26 23:12:14 -0500
committerAaron Patterson <aaron.patterson@gmail.com>2015-02-19 10:57:38 -0800
commitd170b2363c949dce60871f9d5a6bfc83da2bedb5 (patch)
tree997751e051d2b9277ec71bbd59d41376e52f6f8f
parent8d21788798b521b97beb10047ebf593ddc0aaed2 (diff)
downloadrack-d170b2363c949dce60871f9d5a6bfc83da2bedb5.tar.gz
Use a monotonic time for Rack::Runtime, if available
Time.now is prone to inaccuracies if the system time changes during the
request. This could be due to DST, NTP, etc. Using a monotonic clock
(available in Ruby 2.1+ on certain platforms) avoids this problem.
-rw-r--r--lib/rack/runtime.rb16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/rack/runtime.rb b/lib/rack/runtime.rb
index 83d6c0ca..e86add31 100644
--- a/lib/rack/runtime.rb
+++ b/lib/rack/runtime.rb
@@ -14,9 +14,9 @@ module Rack
 
     FORMAT_STRING = "%0.6f"
     def call(env)
-      start_time = Time.now
+      start_time = clock_time
       status, headers, body = @app.call(env)
-      request_time = Time.now - start_time
+      request_time = clock_time - start_time
 
       if !headers.has_key?(@header_name)
         headers[@header_name] = FORMAT_STRING % request_time
@@ -24,5 +24,17 @@ module Rack
 
       [status, headers, body]
     end
+
+    private
+
+    if defined?(Process::CLOCK_MONOTONIC)
+      def clock_time
+        Process.clock_gettime(Process::CLOCK_MONOTONIC)
+      end
+    else
+      def clock_time
+        Time.now.to_f
+      end
+    end
   end
 end