From 75ba183c7ff1e5fd6974a5765665f0c502efac1f Mon Sep 17 00:00:00 2001 From: Dmitriy Ivliev <3938172+moofkit@users.noreply.github.com> Date: Wed, 17 Jan 2024 23:30:12 +0200 Subject: [PATCH] adds config --- .github/workflows/main.yml | 1 + README.md | 11 +++++-- lib/sidekiq/rescue.rb | 31 ++++++++++++++----- lib/sidekiq/rescue/config.rb | 60 ++++++++++++++++++++++++++++++++++++ lib/sidekiq/rescue/dsl.rb | 4 +-- lib/sidekiq_rescue.rb | 2 ++ spec/sidekiq/rescue_spec.rb | 30 +++++++++++++++--- 7 files changed, 124 insertions(+), 15 deletions(-) create mode 100644 lib/sidekiq/rescue/config.rb diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3f4c785..e2c05b7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,6 +28,7 @@ jobs: - '3.0' - '3.1' - '3.2' + - '3.3' steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 4397f4e..c61e3dc 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,14 @@ The default values are: - `delay`: 60 seconds - `limit`: 5 retries -Delay does not increase between retries (unlike Sidekiq standard retry mechanism). +Delay and limit can be configured globally: + +```ruby +Sidekiq::Rescue.configure do |config| + config.delay = 65 + config.limit = 10 +end +``` ## Use cases @@ -102,7 +109,7 @@ make lint ## Contributing -Bug reports and pull requests are welcome on GitHub at https://github.com/moofkit/sidekiq_rescue. +Bug reports and pull requests are welcome on GitHub at https://github.com/moofkit/sidekiq-rescue. ## License diff --git a/lib/sidekiq/rescue.rb b/lib/sidekiq/rescue.rb index 9ab81f7..9222d3d 100644 --- a/lib/sidekiq/rescue.rb +++ b/lib/sidekiq/rescue.rb @@ -25,17 +25,34 @@ module Sidekiq # chain.add Sidekiq::Rescue::ServerMiddleware # ... module Rescue - DEFAULT_DELAY = 60 - DEFAULT_LIMIT = 10 + @mutex = Mutex.new + @config = Config.new.freeze class << self - attr_writer :logger - - # Returns the logger instance. If no logger is set, it defaults to Sidekiq.logger. + extend Forwardable + # Returns the logger instance # # @return [Logger] The logger instance. - def logger - @logger ||= Sidekiq.logger + def_delegators :config, :logger + + # @return [Sidekiq::Rescue::Config] The configuration object. + attr_reader :config + + # Configures Sidekiq::Rescue + # @return [void] + # @yieldparam config [Sidekiq::Rescue::Config] The configuration object. + # @example + # Sidekiq::Rescue.configure do |config| + # config.delay = 10 + # config.limit = 5 + # config.logger = Logger.new($stdout) + # end + def configure + @mutex.synchronize do + config = @config.dup + yield(config) + @config = config.freeze + end end end end diff --git a/lib/sidekiq/rescue/config.rb b/lib/sidekiq/rescue/config.rb new file mode 100644 index 0000000..3bf189e --- /dev/null +++ b/lib/sidekiq/rescue/config.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module Sidekiq + module Rescue + # Config class is used to store the configuration of Sidekiq::Rescue + # and to allow to configure it. + class Config + DEFAULTS = { + delay: 60, + limit: 10 + }.freeze + + def initialize + @delay = DEFAULTS[:delay] + @limit = DEFAULTS[:limit] + @logger = Sidekiq.logger + end + + # Delay in seconds before retrying the job. + # @return [Integer, Float] + attr_reader :delay + + # @param delay [Integer, Float] The delay in seconds before retrying the job. + # @return [void] + # @raise [ArgumentError] if delay is not an Integer or Float + def delay=(delay) + raise ArgumentError, "delay must be an Integer or Float" unless delay.is_a?(Integer) || delay.is_a?(Float) + + @delay = delay + end + + # The maximum number of retries. + # @return [Integer] + attr_reader :limit + + # @param limit [Integer] The maximum number of retries. + # @return [void] + # @raise [ArgumentError] if limit is not an Integer + def limit=(limit) + raise ArgumentError, "limit must be an Integer" unless limit.is_a?(Integer) + + @limit = limit + end + + # The logger instance. + # @return [Logger] + # @note The default logger is Sidekiq's logger. + attr_reader :logger + + # @param logger [Logger] The logger instance. + # @return [void] + # @raise [ArgumentError] if logger is not a Logger + def logger=(logger) + raise ArgumentError, "logger must be a Logger" if !logger.nil? && !logger.respond_to?(:info) + + @logger = logger + end + end + end +end diff --git a/lib/sidekiq/rescue/dsl.rb b/lib/sidekiq/rescue/dsl.rb index 07041f3..6dcd246 100644 --- a/lib/sidekiq/rescue/dsl.rb +++ b/lib/sidekiq/rescue/dsl.rb @@ -31,8 +31,8 @@ def sidekiq_rescue(error, delay: nil, limit: nil) self.sidekiq_rescue_options = { error: error, - delay: delay || Sidekiq::Rescue::DEFAULT_DELAY, - limit: limit || Sidekiq::Rescue::DEFAULT_LIMIT + delay: delay || Sidekiq::Rescue.config.delay, + limit: limit || Sidekiq::Rescue.config.limit } end diff --git a/lib/sidekiq_rescue.rb b/lib/sidekiq_rescue.rb index e24600f..61930c4 100644 --- a/lib/sidekiq_rescue.rb +++ b/lib/sidekiq_rescue.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true require "sidekiq" +require "forwardable" +require_relative "sidekiq/rescue/config" require_relative "sidekiq/rescue" require_relative "sidekiq/rescue/version" require_relative "sidekiq/rescue/dsl" diff --git a/spec/sidekiq/rescue_spec.rb b/spec/sidekiq/rescue_spec.rb index 75ac319..d2ff1ca 100644 --- a/spec/sidekiq/rescue_spec.rb +++ b/spec/sidekiq/rescue_spec.rb @@ -9,9 +9,31 @@ expect(described_class.logger).to be_a(Sidekiq::Logger) end - it "allows to set a custom logger" do - logger = Logger.new($stdout) - described_class.logger = logger - expect(described_class.logger).to eq(logger) + describe "#configure" do + it "allows to configurate the default delay" do + described_class.configure do |config| + config.delay = 10 + end + + expect(described_class.config.delay).to eq(10) + end + + it "allows to configurate the default limit" do + described_class.configure do |config| + config.limit = 5 + end + + expect(described_class.config.limit).to eq(5) + end + + it "allows to configurate the logger" do + logger = Logger.new(nil) + + described_class.configure do |config| + config.logger = logger + end + + expect(described_class.config.logger).to eq(logger) + end end end