sidekiq-antidote 1.0.0.alpha.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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