1
0
Fork 0
mirror of https://github.com/mperham/connection_pool synced 2023-03-27 23:22:21 -04:00

Monotonic clock for more accurate timeouts.

This commit is contained in:
Jerry D'Antonio 2015-10-13 09:38:29 -04:00
parent 84f6eeeaf9
commit 9f295f49a2
2 changed files with 69 additions and 2 deletions

View file

@ -0,0 +1,66 @@
# Global monotonic clock from Concurrent Ruby 1.0.
# Copyright (c) Jerry D'Antonio -- released under the MIT license.
# Slightly modified; used with permission.
# https://github.com/ruby-concurrency/concurrent-ruby
require 'thread'
class ConnectionPool
class_definition = Class.new do
if defined?(Process::CLOCK_MONOTONIC)
# @!visibility private
def get_time
Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
# @!visibility private
def get_time
java.lang.System.nanoTime() / 1_000_000_000.0
end
else
# @!visibility private
def initialize
@mutex = Mutex.new
@last_time = Time.now.to_f
end
# @!visibility private
def get_time
@mutex.synchronize do
now = Time.now.to_f
if @last_time < now
@last_time = now
else # clock has moved back in time
@last_time += 0.000_001
end
end
end
end
end
##
# Clock that cannot be set and represents monotonic time since
# some unspecified starting point.
#
# @!visibility private
GLOBAL_MONOTONIC_CLOCK = class_definition.new
private_constant :GLOBAL_MONOTONIC_CLOCK
class << self
##
# Returns the current time a tracked by the application monotonic clock.
#
# @return [Float] The current monotonic time when `since` not given else
# the elapsed monotonic time between `since` and the current time
def monotonic_time
GLOBAL_MONOTONIC_CLOCK.get_time
end
end
end

View file

@ -1,5 +1,6 @@
require 'thread'
require 'timeout'
require_relative 'monotonic_time'
##
# Raised when you attempt to retrieve a connection from a pool that has been
@ -72,7 +73,7 @@ class ConnectionPool::TimedStack
options, timeout = timeout, 0.5 if Hash === timeout
timeout = options.fetch :timeout, timeout
deadline = Time.now + timeout
deadline = ConnectionPool.monotonic_time + timeout
@mutex.synchronize do
loop do
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
@ -81,7 +82,7 @@ class ConnectionPool::TimedStack
connection = try_create(options)
return connection if connection
to_wait = deadline - Time.now
to_wait = deadline - ConnectionPool.monotonic_time
raise Timeout::Error, "Waited #{timeout} sec" if to_wait <= 0
@resource.wait(@mutex, to_wait)
end