* [PATCH] use monotonic clock if possible on Ruby 2.1+
@ 2015-05-27 22:02 Eric Wong
0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2015-05-27 22:02 UTC (permalink / raw)
To: mogilefs-client-public; +Cc: Eric Wong
The monotonic clock is immune to discontinuous time jumps while
still taking into account clock imperfections, making it appropriate
for calculating time differences and timeouts.
---
lib/mogilefs.rb | 10 ++++++++++
lib/mogilefs/backend.rb | 14 +++++++-------
lib/mogilefs/http_reader.rb | 4 ++--
lib/mogilefs/mogilefs.rb | 2 +-
lib/mogilefs/mysql.rb | 14 +++++++++-----
lib/mogilefs/new_file/common.rb | 2 +-
6 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/lib/mogilefs.rb b/lib/mogilefs.rb
index dd60e91..6059836 100644
--- a/lib/mogilefs.rb
+++ b/lib/mogilefs.rb
@@ -5,6 +5,16 @@
# Client usage information is available in MogileFS::MogileFS.
module MogileFS
+ if defined?(Process::CLOCK_MONOTONIC)
+ def self.now
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ end
+ else
+ def self.now
+ Time.now.to_f
+ end
+ end
+
# Standard error class for most MogileFS-specific errors
class Error < StandardError; end
diff --git a/lib/mogilefs/backend.rb b/lib/mogilefs/backend.rb
index 48f3a2e..01203f6 100644
--- a/lib/mogilefs/backend.rb
+++ b/lib/mogilefs/backend.rb
@@ -147,7 +147,7 @@ def dispatch_unlocked(request, timeout = @timeout) # :nodoc:
tries ||= Hash.new { |hash,host| hash[host] = 0 }
nr = tries[@active_host] += 1
if nr >= 2
- @dead[@active_host] = [ Time.now, err ]
+ @dead[@active_host] = [ MogileFS.now, err ]
end
shutdown_unlocked
retry
@@ -163,7 +163,7 @@ def pipeline_gets_unlocked(io, timeout) # :nodoc:
end
def timeout_update(timeout, t0) # :nodoc:
- timeout -= (Time.now - t0)
+ timeout -= (MogileFS.now - t0)
timeout < 0 ? 0 : timeout
end
@@ -174,12 +174,12 @@ def timeout_update(timeout, t0) # :nodoc:
def pipeline_drain_unlocked(io, timeout) # :nodoc:
set = [ io ]
while @pending.size > 0
- t0 = Time.now
+ t0 = MogileFS.now
r = IO.select(set, set, nil, timeout)
timeout = timeout_update(timeout, t0)
if r && r[0][0]
- t0 = Time.now
+ t0 = MogileFS.now
pipeline_gets_unlocked(io, timeout)
timeout = timeout_update(timeout, t0)
else
@@ -207,7 +207,7 @@ def pipeline_dispatch(cmd, args, &block) # :nodoc:
io.timed_write(request, timeout)
@pending << [ request, block ]
rescue SystemCallError, MogileFS::RequestTruncatedError => err
- @dead[@active_host] = [ Time.now, err ]
+ @dead[@active_host] = [ MogileFS.now, err ]
shutdown_unlocked(@pending[0])
io = socket
retry
@@ -343,14 +343,14 @@ def socket
return @socket if @socket and not @socket.closed?
@hosts.shuffle.each do |host|
- next if dead = @dead[host] and dead[0] > (Time.now - @fail_timeout)
+ next if dead = @dead[host] and dead[0] > (MogileFS.now - @fail_timeout)
begin
addr, port = host.split(/:/)
@socket = MogileFS::Socket.tcp(addr, port, @timeout)
@active_host = host
rescue SystemCallError, MogileFS::Timeout => err
- @dead[host] = [ Time.now, err ]
+ @dead[host] = [ MogileFS.now, err ]
next
end
diff --git a/lib/mogilefs/http_reader.rb b/lib/mogilefs/http_reader.rb
index e6b037d..bd3713c 100644
--- a/lib/mogilefs/http_reader.rb
+++ b/lib/mogilefs/http_reader.rb
@@ -46,13 +46,13 @@ def self.first(paths, timeout, range = nil)
# body of the response.
def self.try(path, timeout, range) # :nodoc:
uri = URI.parse(path)
- expire_at = Time.now + timeout
+ expire_at = MogileFS.now + timeout
sock = tcp(uri.host, uri.port, timeout)
buf = "GET #{uri.request_uri} HTTP/1.0\r\n#{range}\r\n" # no chunking
sock.timed_write(buf, timeout)
begin
- raise MogileFS::Timeout if Time.now > expire_at
+ raise MogileFS::Timeout if MogileFS.now > expire_at
sock.timed_peek(2048, buf, timeout) or
raise MogileFS::InvalidResponseError, "EOF while reading header", []
end until /\r\n\r\n/ =~ buf
diff --git a/lib/mogilefs/mogilefs.rb b/lib/mogilefs/mogilefs.rb
index cd6f7c6..2ccd78b 100644
--- a/lib/mogilefs/mogilefs.rb
+++ b/lib/mogilefs/mogilefs.rb
@@ -318,7 +318,7 @@ def new_file(key, args = nil, bytes = nil) # :yields: file
opts[:fid] = res['fid']
opts[:content_length] ||= bytes if bytes
opts[:new_file_max_time] ||= @new_file_max_time
- opts[:start_time] = Time.now
+ opts[:start_time] = MogileFS.now
info = opts[:info] and info["class"] = klass || "default"
case (dests[0][1] rescue nil)
diff --git a/lib/mogilefs/mysql.rb b/lib/mogilefs/mysql.rb
index 9d59a0a..e2a16e5 100644
--- a/lib/mogilefs/mysql.rb
+++ b/lib/mogilefs/mysql.rb
@@ -21,7 +21,7 @@ class MogileFS::Mysql
def initialize(args = {})
@my = args[:mysql]
@query_method = @my.respond_to?(:c_async_query) ? :c_async_query : :query
- @last_update_device = @last_update_domain = Time.at(0)
+ @last_update_device = @last_update_domain = 0
@cache_domain = @cache_device = nil
end
@@ -139,7 +139,9 @@ def query(sql)
}.freeze
def refresh_device(force = false)
- return @cache_device if ! force && ((Time.now - @last_update_device) < 60)
+ if ! force && ((MogileFS.now - @last_update_device) < 60)
+ return @cache_device
+ end
tmp = {}
res = query(GET_DEVICES)
res.each do |devid, hostip, altip, http_port, http_get_port,
@@ -154,16 +156,18 @@ def refresh_device(force = false)
:http_get_port => http_get_port ? http_get_port.to_i : http_port,
}.freeze
end
- @last_update_device = Time.now
+ @last_update_device = MogileFS.now
@cache_device = tmp.freeze
end
def refresh_domain(force = false)
- return @cache_domain if ! force && ((Time.now - @last_update_domain) < 5)
+ if ! force && ((MogileFS.now - @last_update_domain) < 5)
+ return @cache_domain
+ end
tmp = {}
res = query(GET_DOMAINS)
res.each { |dmid,namespace| tmp[namespace] = dmid.to_i }
- @last_update_domain = Time.now
+ @last_update_domain = MogileFS.now
@cache_domain = tmp.freeze
end
diff --git a/lib/mogilefs/new_file/common.rb b/lib/mogilefs/new_file/common.rb
index b901f67..c102901 100644
--- a/lib/mogilefs/new_file/common.rb
+++ b/lib/mogilefs/new_file/common.rb
@@ -20,7 +20,7 @@ class NonRetryableError < MogileFS::Error; end
def read_response(sock)
tout = @opts[:new_file_max_time] || 3600.0
- start_time = @opts[:start_time] and tout -= Time.now - start_time
+ start_time = @opts[:start_time] and tout -= MogileFS.now - start_time
set_socket_options(sock)
case line = sock.timed_read(23, "", tout > 0.0 ? tout : 0)
when %r{^HTTP/\d\.\d\s+(2\d\d)\s} # success!
--
EW
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-05-27 22:02 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-27 22:02 [PATCH] use monotonic clock if possible on Ruby 2.1+ Eric Wong
Code repositories for project(s) associated with this public inbox
https://yhbt.net/mogilefs-client.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).