sidekiq-antidote 1.0.0.alpha.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 052bc50b4ce029ead4b2a4e6253625cf9a82a9c4071be61945e76336d9d13f18
4
- data.tar.gz: a12ac47db5f3edee4fba2e600b1da4029db87657a8bde540a7b3f2fb2c07911b
3
+ metadata.gz: 9f5bdf47fd299dc626c6fc0afb94896301c66e5b1f9f33875383375d0d5ac483
4
+ data.tar.gz: bb9966c063f7ca0325d31229c6f4d0cf445d53392bb89a201dba92891759ece3
5
5
  SHA512:
6
- metadata.gz: d9cf2a9e0db287b0b6c7d40a4fe99c7927dbb9aee9fdfd8efc06bdb81c91396f6b169271973746d2b543ac34673694c7894338d8c43d9f947f5f17659bafb4b8
7
- data.tar.gz: 57d9306f0b40cbccd67a1cf9f5d7260ddb59098cf1078fca7aca4ae88df58b669e38e2a2dd6059cb4d1c48ecdbf35e2eb56ff55bcdf957f4955dca33f0dee102
6
+ metadata.gz: 87e30e47eb2e37cea51f9037469a4395651d49da8664558d893a71e83d7af275c32ea5ce2e6e8c6b6d464e979af684498972dd2a21c5ddedaf9fe73a2e4a1e62
7
+ data.tar.gz: ffea8f3beef24555534621992e60d18c3c3ec0ab3855e07a65e5a274a434a0285f8442efe851ef8c1377df8f9f72920d290c545b42eb56566c3ee0d53a124362
data/README.adoc CHANGED
@@ -1,5 +1,12 @@
1
1
  = Sidekiq::Antidote
2
2
 
3
+ :ci-url: https://github.com/ixti/sidekiq-antidote/actions/workflows/ci.yml?query=branch%3Amain
4
+ :ci-img: https://github.com/ixti/sidekiq-antidote/actions/workflows/ci.yml/badge.svg?branch=main
5
+ :codecov-url: https://codecov.io/gh/ixti/sidekiq-antidote/tree/main
6
+ :codecov-img: https://codecov.io/gh/ixti/sidekiq-antidote/graph/badge.svg?token=F5AAMPN35A
7
+
8
+ {ci-url}[image:{ci-img}[CI]]
9
+ {codecov-url}[image:{codecov-img}[codecov]]
3
10
 
4
11
  == Installation
5
12
 
@@ -20,10 +27,6 @@ require "sidekiq"
20
27
  require "sidekiq/antidote"
21
28
 
22
29
  Sidekiq::Antidote.configure do |config|
23
- # Set redis key prefix.
24
- # Default: nil
25
- config.key_prefix = "my-app:"
26
-
27
30
  # Set inhibitors cache refresh rate in seconds.
28
31
  # Default: 5.0
29
32
  config.refresh_rate = 10.0
@@ -49,36 +52,109 @@ require "sidekiq/web"
49
52
  require "sidekiq/antidote/web"
50
53
  ----
51
54
 
55
+ === Middleware(s)
52
56
 
53
- == Supported Ruby Versions
57
+ `Sidekiq::Antidote` relies on following bundled middlewares:
54
58
 
55
- This library aims to support and is tested against the following Ruby versions:
59
+ * `Sidekiq::Antidote::Middlewares::Client`
60
+ * `Sidekiq::Antidote::Middlewares::Server`
56
61
 
57
- * Ruby 3.0.x
58
- * Ruby 3.1.x
59
- * Ruby 3.2.x
62
+ The middleware is automatically injected when you require `sidekiq/antidote`.
63
+ In rare cases, when this causes an issue, you can change middleware order manually:
60
64
 
61
- If something doesn't work on one of these versions, it's a bug.
65
+ [source,ruby]
66
+ ----
67
+ Sidekiq.configure_client do |config|
68
+ # ...
62
69
 
63
- This library may inadvertently work (or seem to work) on other Ruby versions,
64
- however support will only be provided for the versions listed above.
70
+ config.client_middleware do |chain|
71
+ chain.prepend(Sidekiq::Antidote::Middlewares::Client)
72
+ end
73
+ end
65
74
 
66
- If you would like this library to support another Ruby version or
67
- implementation, you may volunteer to be a maintainer. Being a maintainer
68
- entails making sure all tests run and pass on that implementation. When
69
- something breaks on your implementation, you will be responsible for providing
70
- patches in a timely fashion. If critical issues for a particular implementation
71
- exist at the time of a major release, support for that Ruby version may be
72
- dropped.
75
+ Sidekiq.configure_server do |config|
76
+ # ...
77
+
78
+ config.client_middleware do |chain|
79
+ chain.prepend(Sidekiq::Antidote::Middlewares::Client)
80
+ end
81
+
82
+ config.server_middleware do |chain|
83
+ chain.prepend(Sidekiq::Antidote::Middlewares::Server)
84
+ end
85
+ end
86
+ ----
87
+
88
+ See: https://github.com/sidekiq/sidekiq/blob/main/lib/sidekiq/middleware/chain.rb
89
+
90
+
91
+ == Inhibitors
92
+
93
+ === Treatments
73
94
 
95
+ When adding antidote you must pick on of the treatments:
74
96
 
75
- == Supported Sidekiq Versions
97
+ skip::
98
+ Skip the job (don't enqueue and/or perform)
99
+ kill::
100
+ Kill the job (send to the dead set instead of enqueueing and/or performing)
76
101
 
77
- This library aims to support and work with following Sidekiq versions:
78
102
 
79
- * Sidekiq 7.0.x
80
- * Sidekiq 7.1.x
81
- * Sidekiq 7.2.x
103
+ === Class Qualifiers
104
+
105
+ Class qualifier is the job class pattern. It may match the job class or the job
106
+ class and method name (when used with ActionMailer delayed deliveries):
107
+
108
+ * `ExampleJob`
109
+ * `Namespaced::ExampleJob`
110
+ * `UserMailer#welcome`
111
+
112
+ You can also use pattern matching:
113
+
114
+ *::
115
+ Matches any number of alpha-numeric characters and underscores:
116
+ * `*Job` matches: `ExampleJob`, but not `Namespaced::ExampleJob`, or `UserMailer#welcome`
117
+ * `UserMailer#*` matches any method of `UserMailer`
118
+ **::
119
+ Matches any number of components:
120
+ * `**` mathes any job or mailer method
121
+ * `A::**::Job` matches `A::B::Job`, `A::B::C::D::CJob`, etc.
122
+ * `A**::Job` matches `A::Job`, `Abc::Job`, `A::B::Job`, etc.
123
+ {}::
124
+ Matches any of the given literal:
125
+ * `{A,B,C}Job` matches `AJob`, `BJob`, and `CJob`
126
+
127
+
128
+ == Compatibility
129
+
130
+ This library aims to support and is tested against:
131
+
132
+ * https://www.ruby-lang.org[Ruby]
133
+ ** MRI 3.0.x
134
+ ** MRI 3.1.x
135
+ ** MRI 3.2.x
136
+ ** MRI 3.3.x
137
+ * https://github.com/sidekiq/sidekiq[Sidekiq]
138
+ ** 7.2.x
139
+ ** 7.3.x
140
+ * https://redis.io[Redis]
141
+ ** 6.2.x
142
+ ** 7.0.x
143
+ ** 7.2.x
144
+
145
+ If something doesn't work on one of these versions, it's a bug.
146
+
147
+ This library may inadvertently work (or seem to work) on other Ruby, Redis, and
148
+ Sidekiq versions, however support will only be provided for the versions listed
149
+ above.
150
+
151
+ If you would like this library to support another Ruby, Redis, or Sidekiq
152
+ version, you may volunteer to be a maintainer. Being a maintainer entails making
153
+ sure all tests run and pass on that implementation. When something breaks on
154
+ your implementation, you will be responsible for providing patches in a timely
155
+ fashion. If critical issues for a particular implementation exist at the time of
156
+ a major release, support for that Ruby, Redis, and/or Sidekiq version may be
157
+ dropped.
82
158
 
83
159
 
84
160
  == Development
@@ -3,53 +3,16 @@
3
3
  module Sidekiq
4
4
  module Antidote
5
5
  class Config
6
- REDIS_KEY = "sidekiq-antidote"
7
- private_constant :REDIS_KEY
8
-
9
6
  # Default refresh rate
10
7
  REFRESH_RATE = 5.0
11
8
 
12
- # @return [String?]
13
- attr_reader :key_prefix
14
-
15
9
  # @return [Float]
16
10
  attr_reader :refresh_rate
17
11
 
18
- # Fully qualified Redis key
19
- #
20
- # @example Without key prefix (default)
21
- # config.redis_key # => "sidekiq-antidote"
22
- #
23
- # @example With key prefix
24
- # config.key_prefix = "foobar:"
25
- # config.redis_key # => "foobar:sidekiq-antidote"
26
- #
27
- # @see #key_prefix
28
- # @return [String]
29
- attr_reader :redis_key
30
-
31
12
  def initialize
32
- @key_prefix = nil
33
- @redis_key = REDIS_KEY
34
13
  @refresh_rate = REFRESH_RATE
35
14
  end
36
15
 
37
- # Redis key prefix.
38
- #
39
- # @example
40
- # config.key_prefix = "foobar:"
41
- # config.redis_key # => "foobar:sidekiq-antidote"
42
- #
43
- # @see #redis_key
44
- # @param value [String, nil] String that should be prepended to redis key
45
- # @return [void]
46
- def key_prefix=(value)
47
- raise ArgumentError, "expected String, or nil; got #{value.class}" unless value.nil? || value.is_a?(String)
48
-
49
- @redis_key = [value, REDIS_KEY].compact.join.freeze
50
- @key_prefix = value&.then(&:-@) # Don't freeze original String value if it was unfrozen
51
- end
52
-
53
16
  # Inhibitors cache refresh rate in seconds.
54
17
  #
55
18
  # @param value [Float] refresh interval in seconds
@@ -33,10 +33,6 @@ module Sidekiq
33
33
  freeze
34
34
  end
35
35
 
36
- def lethal?
37
- "kill" == treatment
38
- end
39
-
40
36
  def match?(job_record)
41
37
  class_qualifier.match?(job_record.display_class)
42
38
  end
@@ -11,8 +11,8 @@ module Sidekiq
11
11
 
12
12
  # @see https://github.com/sidekiq/sidekiq/wiki/Middleware
13
13
  # @see https://github.com/sidekiq/sidekiq/wiki/Job-Format
14
- def call(_, job_payload, _, _)
15
- yield unless inhibit(job_payload)
14
+ def call(_, job_payload, queue_name, _)
15
+ yield unless inhibit(job_payload, queue_name)
16
16
  end
17
17
  end
18
18
  end
@@ -11,8 +11,8 @@ module Sidekiq
11
11
 
12
12
  # @see https://github.com/sidekiq/sidekiq/wiki/Middleware
13
13
  # @see https://github.com/sidekiq/sidekiq/wiki/Job-Format
14
- def call(_, job_payload, _)
15
- yield unless inhibit(job_payload)
14
+ def call(_, job_payload, queue_name)
15
+ yield unless inhibit(job_payload, queue_name)
16
16
  end
17
17
  end
18
18
  end
@@ -10,17 +10,27 @@ module Sidekiq
10
10
 
11
11
  # @return [true] if message was inhibited
12
12
  # @return [false] otherwise
13
- def inhibit(message)
13
+ def inhibit(message, queue_name)
14
14
  job_record = Sidekiq::JobRecord.new(message)
15
15
  inhibitor = Antidote.remedy_for(job_record)
16
16
  return false unless inhibitor
17
17
 
18
18
  Antidote.log(:warn) { "I've got a poison! -- #{job_record.display_class}" }
19
19
  Antidote.log(:warn) { "I've got a remedy! -- #{inhibitor}" }
20
- DeadSet.new.kill(Sidekiq.dump_json(message)) if inhibitor.lethal?
20
+
21
+ apply_treatment(inhibitor, job_record, queue_name)
21
22
 
22
23
  true
23
24
  end
25
+
26
+ def apply_treatment(inhibitor, job_record, queue_name)
27
+ # Ensure message has queue name
28
+ message = Sidekiq.dump_json(job_record.item.merge({ "queue" => queue_name }))
29
+
30
+ case inhibitor.treatment
31
+ when "kill" then DeadSet.new.kill(message)
32
+ end
33
+ end
24
34
  end
25
35
  end
26
36
  end
@@ -4,6 +4,7 @@ require "concurrent"
4
4
 
5
5
  module Sidekiq
6
6
  module Antidote
7
+ # @api internal
7
8
  # Eventually consistent list of inhibitors. Used by middlewares to avoid
8
9
  # hitting Redis on every lookup.
9
10
  class Remedy
@@ -12,9 +13,8 @@ module Sidekiq
12
13
  # @param refresh_rate [Float]
13
14
  # @param repository [Repository]
14
15
  def initialize(refresh_rate, repository:)
15
- @inhibitors = [].freeze
16
- @refresher = Concurrent::TimerTask.new(execution_interval: refresh_rate, run_now: true) do
17
- @inhibitors = repository.to_a.freeze
16
+ @refresher = Concurrent::TimerTask.new(execution_interval: refresh_rate, run_now: true) do
17
+ repository.to_a.freeze
18
18
  end
19
19
  end
20
20
 
@@ -29,7 +29,7 @@ module Sidekiq
29
29
  return to_enum __method__ unless block
30
30
 
31
31
  start_refresher unless refresher_running?
32
- @inhibitors.each(&block)
32
+ @refresher.value&.each(&block)
33
33
 
34
34
  self
35
35
  end
@@ -8,12 +8,7 @@ module Sidekiq
8
8
  class Repository
9
9
  include Enumerable
10
10
 
11
- # @param redis_key [#to_s]
12
- def initialize(redis_key)
13
- @redis_key = -redis_key.to_s
14
-
15
- freeze
16
- end
11
+ REDIS_KEY = "sidekiq-antidote"
17
12
 
18
13
  # @overload each
19
14
  # @return [Enumerator<Inhibitor>]
@@ -27,7 +22,7 @@ module Sidekiq
27
22
 
28
23
  broken_ids = []
29
24
 
30
- redis("HGETALL", @redis_key).each do |id, payload|
25
+ redis("HGETALL", REDIS_KEY).each do |id, payload|
31
26
  inhibitor = deserialize(id, payload)
32
27
  next yield inhibitor if inhibitor
33
28
 
@@ -50,7 +45,7 @@ module Sidekiq
50
45
  class_qualifier: class_qualifier
51
46
  )
52
47
 
53
- return inhibitor if redis("HSETNX", @redis_key, *serialize(inhibitor)).to_i.positive?
48
+ return inhibitor if redis("HSETNX", REDIS_KEY, *serialize(inhibitor)).to_i.positive?
54
49
  end
55
50
 
56
51
  raise "can't generate available ID"
@@ -59,7 +54,7 @@ module Sidekiq
59
54
  # @param ids [Array<String>]
60
55
  # @return [nil]
61
56
  def delete(*ids)
62
- redis("HDEL", @redis_key, *ids) unless ids.empty?
57
+ redis("HDEL", REDIS_KEY, *ids) unless ids.empty?
63
58
  nil
64
59
  end
65
60
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Antidote
5
- VERSION = "1.0.0.alpha.1"
5
+ VERSION = "1.1.0"
6
6
  end
7
7
  end
@@ -14,9 +14,10 @@ require_relative "./antidote/version"
14
14
  module Sidekiq
15
15
  module Antidote
16
16
  MUTEX = Mutex.new
17
+ private_constant :MUTEX
17
18
 
18
19
  @config = Config.new.freeze
19
- @repository = Repository.new(@config.redis_key)
20
+ @repository = Repository.new
20
21
  @remedy = Remedy.new(@config.refresh_rate, repository: @repository)
21
22
 
22
23
  class << self
@@ -32,10 +33,6 @@ module Sidekiq
32
33
  # @return (see Repository#delete)
33
34
  def_delegators :@repository, :delete
34
35
 
35
- # @!attribute [r] redis_key
36
- # @return [String]
37
- def_delegators :@config, :redis_key
38
-
39
36
  # @return [Array<Inhibitor>] Live list of inhibitors
40
37
  def inhibitors
41
38
  @repository.to_a
@@ -62,8 +59,7 @@ module Sidekiq
62
59
 
63
60
  yield config
64
61
 
65
- @config = config.freeze
66
- @repository = Repository.new(@config.redis_key)
62
+ @config = config.freeze
67
63
 
68
64
  self
69
65
  ensure
data/web/locales/en.yml CHANGED
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  en:
3
3
  antidote.treatment: Treatment
4
- antidote.qualifier: Job Class Pattern
4
+ antidote.class_qualifier: Class Qualifier
5
5
  antidote.actions: Actions
6
6
  antidote.add: Add Inhibitor
7
- antidote.submit: Submit
7
+ antidote.add.submit: Submit
8
+ antidote.add.confirm: Are you sure you want to add the inhibitor?
8
9
  antidote.no_inhibitors: No inhibitors found
10
+ antidote.delete.confirm: Are you sure you want to delete inhibitor of ‹%{qualifier}› with ‹%{treatment}› treatment?
@@ -6,26 +6,51 @@
6
6
  <div class="alert alert-danger"><%= @error %></div>
7
7
  <% end %>
8
8
 
9
- <form id="antidote-inhibitor" action="<%=root_path %>antidote/add" method="post">
10
- <%= csrf_tag %>
11
- <div class="form-row">
12
- <div class="form-group col-md-2">
13
- <label for="antidote-inhibitor-treatment"><%= t("antidote.treatment") %></label>
14
- <select id="antidote-inhibitor-treatment" name="treatment" class="form-control">
15
- <% Sidekiq::Antidote::Inhibitor::TREATMENTS.each do |treatment| %>
16
- <option <%= "selected" if treatment == @treatment %>><%= treatment %></option>
9
+ <div class="col-sm-12">
10
+ <form id="antidote-inhibitor" class="form-horizontal" action="<%=root_path %>antidote/add" method="post">
11
+ <%= csrf_tag %>
12
+ <div class="form-group">
13
+ <label class="col-sm-2 control-label"><%= t("antidote.treatment") %></label>
14
+ <div class="radio col-sm-10">
15
+ <label>
16
+ <input id="antidote-inhibitor-treatment-skip" type="radio" name="treatment" value="skip" <%= "checked" if "skip" == @treatment %>>
17
+ skip <em class="text-muted">(don't enqueue and/or perform)</em>
18
+ </label>
19
+ </div>
20
+ <div class="radio col-sm-offset-2 col-sm-10">
21
+ <label>
22
+ <input id="antidote-inhibitor-treatment-kill" type="radio" name="treatment" value="kill" <%= "checked" if "kill" == @treatment %>>
23
+ kill <em class="text-muted">(send to the dead set instead of enqueueing and/or performing)</em>
24
+ </label>
25
+ </div>
26
+ </div>
27
+ <div class="form-group <%= "has-error" if @class_qualifier_error %>">
28
+ <label class="col-sm-2 control-label"><%= t("antidote.class_qualifier") %></label>
29
+ <div class="col-sm-10">
30
+ <input id="antidote-inhibitor-class-qualifier" type="text" class="form-control <%= "is-invalid" if @class_qualifier_error %>" name="class_qualifier" value="<%= @class_qualifier %>">
31
+ <% if @class_qualifier_error %>
32
+ <div id="antidote-inhibitor-class-qualifier-error" class="help-block">
33
+ <strong>ERROR:</strong> <%= @class_qualifier_error %>
34
+ </div>
17
35
  <% end %>
18
- </select>
36
+ <div class="help-block">
37
+ <strong>Examples:</strong>
38
+ <ul class="list-unstyled">
39
+ <li><kbd>ExampleJob</kbd> to match <var>ExampleJob</var> exactly</li>
40
+ <li><kbd>Namespaced::ExampleJob</kbd> to match <var>Namespaced::ExampleJob</var> exactly</li>
41
+ <li><kbd>UserMailer#welcome</kbd> to match <var>welcome</var> method of <var>UserMailer</var></li>
42
+ <li><kbd>*Job</kbd> to match <var>ExampleJob</var>, but not <var>Namespaced::ExampleJob</var></li>
43
+ <li><kbd>UserMailer#*</kbd> to match any method of <var>UserMailer</var></li>
44
+ <li><kbd>**Job</kbd> to match <var>ExampleJob</var>, <var>Namespaced::ExampleJob</var>, etc.</li>
45
+ <li><kbd>{A,B,C}Job</kbd> to match <var>AJob</var>, <var>BJob</var>, or <var>CJob</var></li>
46
+ </ul>
47
+ </div>
48
+ </div>
19
49
  </div>
20
- <div class="form-group col-md-10">
21
- <label for="antidote-inhibitor-class-qualifier"><%= t("antidote.qualifier") %></label>
22
- <input id="antidote-inhibitor-class-qualifier" type="text" class="form-control <%= "is-invalid" if @class_qualifier_error %>" name="class_qualifier" value="<%= @class_qualifier %>">
23
- <% if @class_qualifier_error %>
24
- <div id="antidote-inhibitor-class-qualifier-error" class="invalid-feedback"><%= @class_qualifier_error %></div>
25
- <% end %>
50
+ <div class="form-group">
51
+ <div class="radio col-sm-offset-2 col-sm-10">
52
+ <input class="btn btn-danger" type="submit" name="add" value="<%= t("antidote.add.submit") %>" data-confirm="<%= t("antidote.add.confirm") %>" />
53
+ </div>
26
54
  </div>
27
- </div>
28
- <div class="form-row text-right">
29
- <button id="antidote-inhibitor-submit" type="submit" class="btn"><%= t("antidote.submit") %></button>
30
- </div>
31
- </form>
55
+ </form>
56
+ </div>
@@ -12,7 +12,7 @@
12
12
  <table class="antidote table table-hover table-bordered table-striped">
13
13
  <thead>
14
14
  <th><%= t("antidote.treatment") %></th>
15
- <th><%= t("antidote.qualifier") %></th>
15
+ <th><%= t("antidote.class_qualifier") %></th>
16
16
  <th><%= t("antidote.actions") %></th>
17
17
  </thead>
18
18
  <tbody>
@@ -23,7 +23,7 @@
23
23
  <td class="delete-confirm">
24
24
  <form action="<%=root_path %>antidote/<%= CGI.escape(inhibitor.id) %>/delete" method="post">
25
25
  <%= csrf_tag %>
26
- <input class="btn btn-danger" type="submit" name="delete" value="<%= t("Delete") %>" data-confirm="<%= t("AreYouSureDeleteQueue") %>" />
26
+ <input class="btn btn-danger" type="submit" name="delete" value="<%= t("Delete") %>" data-confirm="<%= t("antidote.delete.confirm", treatment: inhibitor.treatment, qualifier: inhibitor.class_qualifier) %>" />
27
27
  </form>
28
28
  </td>
29
29
  </tr>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-antidote
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Zapparov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-02 00:00:00.000000000 Z
11
+ date: 2024-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '7.0'
33
+ version: '7.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '7.0'
40
+ version: '7.2'
41
41
  description:
42
42
  email:
43
43
  - alexey@zapparov.com
@@ -66,9 +66,9 @@ licenses:
66
66
  - MIT
67
67
  metadata:
68
68
  homepage_uri: https://github.com/ixti/sidekiq-antidote
69
- source_code_uri: https://github.com/ixti/sidekiq-antidote/tree/v1.0.0.alpha.1
69
+ source_code_uri: https://github.com/ixti/sidekiq-antidote/tree/v1.1.0
70
70
  bug_tracker_uri: https://github.com/ixti/sidekiq-antidote/issues
71
- changelog_uri: https://github.com/ixti/sidekiq-antidote/blob/v1.0.0.alpha.1/CHANGES.md
71
+ changelog_uri: https://github.com/ixti/sidekiq-antidote/blob/v1.1.0/CHANGES.md
72
72
  rubygems_mfa_required: 'true'
73
73
  post_install_message:
74
74
  rdoc_options: []
@@ -81,11 +81,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
81
  version: '3.0'
82
82
  required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  requirements:
84
- - - ">"
84
+ - - ">="
85
85
  - !ruby/object:Gem::Version
86
- version: 1.3.1
86
+ version: '0'
87
87
  requirements: []
88
- rubygems_version: 3.4.10
88
+ rubygems_version: 3.5.22
89
89
  signing_key:
90
90
  specification_version: 4
91
91
  summary: Sidekiq poison-pill instant remedy