lib/double_restraint.rb in double_restraint-1.0.0 vs lib/double_restraint.rb in double_restraint-1.0.1

- old
+ new

@@ -1,10 +1,12 @@ # frozen_string_literal: true require "restrainer" class DoubleRestraint + attr_reader :timeout, :long_running_timeout + # @param name [String, Symbol] The name of the restraint. # @param timeout [Numeric] The first timeout that will be yielded to the block. # @param long_running_timeout [Numeric] The timeout that will be yielded to the block if # the block times out the first time it is excuted. # @param long_running_limit [Integer] The maximum number of times the block can be run @@ -18,26 +20,24 @@ # If this is not set, the default value set for `Restrainer.redis` will be used. def initialize(name, timeout:, long_running_timeout:, long_running_limit:, limit: nil, timeout_errors: [Timeout::Error], redis: nil) @timeout = timeout @long_running_timeout = long_running_timeout @timeout_errors = Array(timeout_errors) - @restrainer = Restrainer.new("DoubleRestrainer(#{name})", limit: limit, redis: redis) if limit + limit = -1 if limit.to_i <= 0 + @restrainer = Restrainer.new("DoubleRestrainer(#{name})", limit: limit, redis: redis) @long_running_restrainer = Restrainer.new("DoubleRestrainer(#{name}).long_running", limit: long_running_limit, redis: redis) end # Execute a block of code. The block will be yielded with the timeout value. If the block raises # a timeout error, then it will be called again with the long running timeout. The code in the block # must be idempotent since it can be run twice. + # # @yieldparam [Numeric] the timeout value to use in the block. # @raise [Restrainer::ThrottleError] if too many concurrent processes are trying to use the restraint. - def execute + def execute(&block) begin - if @restrainer - @restrainer.throttle do - yield @timeout - end - else + @restrainer.throttle do yield @timeout end rescue => e if @timeout_errors.any? { |error_class| e.is_a?(error_class) } @long_running_restrainer.throttle do @@ -45,7 +45,47 @@ end else raise e end end + end + + # Get the current size of the default pool. This can be useful in + # collecting realtime stats about how the pool is being utilized. + # + # @return [Integer] + def default_pool_size + @restrainer.current + end + + # Get the current size of the long running pool. This can be useful in + # collecting realtime stats about how the pool is being utilized. + # + # @return [Integer] + def long_running_pool_size + @long_running_restrainer.current + end + + # Get the limit for the default pool. This will return -1 if there + # is no limit set on that pool. + # + # @return [Integer] + def default_pool_limit + @restrainer.limit + end + + # Get the limit for the long running pool. + # + # @return [Integer] + def long_running_pool_limit + @long_running_restrainer.limit + end + + # Helper method to determine if a timeout represents the long running timeout. + # Note that the timeout and long running timeouts need to be different values + # in order for this to work. + # + # @return [Boolean] + def long_running?(timeout) + timeout.to_f.round(6) == @long_running_timeout.to_f.round(6) end end