lib/attempt.rb in attempt-0.6.1 vs lib/attempt.rb in attempt-0.6.2
- old
+ new
@@ -1,14 +1,20 @@
-require 'safe_timeout'
+# frozen_string_literal: true
+
+if File::ALT_SEPARATOR
+ require 'timeout'
+else
+ require 'safe_timeout'
+end
+
require 'structured_warnings'
# The Attempt class encapsulates methods related to multiple attempts at
# running the same method before actually failing.
class Attempt
-
# The version of the attempt library.
- VERSION = '0.6.1'.freeze
+ VERSION = '0.6.2'
# Warning raised if an attempt fails before the maximum number of tries
# has been reached.
class Warning < StructuredWarnings::StandardWarning; end
@@ -49,11 +55,11 @@
# * increment - The amount to increment the interval between tries. The default is 0.
# * level - The level of exception to be caught. The default is everything, i.e. Exception.
# * warnings - Boolean value that indicates whether or not errors are treated as warnings
# until the maximum number of attempts has been made. The default is true.
# * timeout - Boolean value to indicate whether or not to automatically wrap your
- # proc in a SafeTimeout block. The default is false.
+ # proc in a Timeout/SafeTimeout block. The default is false.
#
# Example:
#
# a = Attempt.new(tries: 5, increment: 10, timeout: true)
# a.attempt{ http.get("http://something.foo.com") }
@@ -72,22 +78,22 @@
# times, sleeping +interval+ between each try.
#
# You will not typically use this method directly, but the Kernel#attempt
# method instead.
#
- def attempt
+ def attempt(&block)
count = 1
begin
if @timeout
- SafeTimeout.timeout(@timeout){ yield }
+ File::ALT_SEPARATOR ? Timeout.timeout(@timeout, &block) : SafeTimeout.timeout(@timeout, &block)
else
yield
end
- rescue @level => error
+ rescue @level => err
@tries -= 1
if @tries > 0
- msg = "Error on attempt # #{count}: #{error}; retrying"
+ msg = "Error on attempt # #{count}: #{err}; retrying"
count += 1
warn Warning, msg if @warnings
if @log # Accept an IO or Logger object
@log.respond_to?(:puts) ? @log.puts(msg) : @log.warn(msg)
@@ -100,32 +106,33 @@
raise
end
end
end
+# Extend the Kernel module with a simple interface for the Attempt class.
module Kernel
- # :call-seq:
- # attempt(tries: 3, interval: 60, timeout: 10){ # some op }
- #
- # Attempt to perform the operation in the provided block up to +tries+
- # times, sleeping +interval+ between each try. By default the number
- # of tries defaults to 3, the interval defaults to 60 seconds, and there
- # is no timeout specified.
- #
- # If +timeout+ is provided then the operation is wrapped in a Timeout
- # block as well. This is handy for those rare occasions when an IO
- # connection could hang indefinitely, for example.
- #
- # If the operation still fails the (last) error is then re-raised.
- #
- # This is really just a convenient wrapper for Attempt.new + Attempt#attempt.
- #
- # Example:
- #
- # # Make 3 attempts to connect to the database, 60 seconds apart.
- # attempt{ DBI.connect(dsn, user, passwd) }
- #
- def attempt(**kwargs, &block)
- object = Attempt.new(kwargs)
- object.attempt(&block)
- end
+ # :call-seq:
+ # attempt(tries: 3, interval: 60, timeout: 10){ # some op }
+ #
+ # Attempt to perform the operation in the provided block up to +tries+
+ # times, sleeping +interval+ between each try. By default the number
+ # of tries defaults to 3, the interval defaults to 60 seconds, and there
+ # is no timeout specified.
+ #
+ # If +timeout+ is provided then the operation is wrapped in a Timeout
+ # block as well. This is handy for those rare occasions when an IO
+ # connection could hang indefinitely, for example.
+ #
+ # If the operation still fails the (last) error is then re-raised.
+ #
+ # This is really just a convenient wrapper for Attempt.new + Attempt#attempt.
+ #
+ # Example:
+ #
+ # # Make 3 attempts to connect to the database, 60 seconds apart.
+ # attempt{ DBI.connect(dsn, user, passwd) }
+ #
+ def attempt(**kwargs, &block)
+ object = Attempt.new(**kwargs)
+ object.attempt(&block)
+ end
end