sidekiq-antidote 1.0.0.alpha.1 → 1.0.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: 3692f76b40f4cf3cf7c8231c3a882e09ab5f81dec49cc3711b268602cd9bb0a3
4
+ data.tar.gz: 2845af94e4a35930c1cd775a075774ee72a70af2c3a498f802f2cc56f99edf07
5
5
  SHA512:
6
- metadata.gz: d9cf2a9e0db287b0b6c7d40a4fe99c7927dbb9aee9fdfd8efc06bdb81c91396f6b169271973746d2b543ac34673694c7894338d8c43d9f947f5f17659bafb4b8
7
- data.tar.gz: 57d9306f0b40cbccd67a1cf9f5d7260ddb59098cf1078fca7aca4ae88df58b669e38e2a2dd6059cb4d1c48ecdbf35e2eb56ff55bcdf957f4955dca33f0dee102
6
+ metadata.gz: 15c6e2fc733cae175d0e1d3b4b2f23ae666156c0b4386cf51287306d9601e3a09f4fccb2cac5adb6270f7e39e5937b99071e82804666a4fecc130ab2da020c04
7
+ data.tar.gz: a7307425321fd20db807a2e16419b6cad463288658cf78ce9063cacf828b83b84977075686882fb35c56e0c87cb8c060dc451bd6a788fe3b8af48f8d892ddc52
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
@@ -50,6 +53,43 @@ require "sidekiq/antidote/web"
50
53
  ----
51
54
 
52
55
 
56
+ == Inhibitors
57
+
58
+ === Treatments
59
+
60
+ When adding antidote you must pick on of the treatments:
61
+
62
+ skip::
63
+ Skip the job (don't enqueue and/or perform)
64
+ kill::
65
+ Kill the job (send to the dead set instead of enqueueing and/or performing)
66
+
67
+
68
+ === Antidote Qualifiers
69
+
70
+ Qualifier is the job class pattern. It may match the job class or the job class
71
+ and method name (when used with ActionMailer delayed deliveries):
72
+
73
+ * `ExampleJob`
74
+ * `Namespaced::ExampleJob`
75
+ * `UserMailer#welcome`
76
+
77
+ You can also use pattern matching:
78
+
79
+ *::
80
+ Matches any number of alpha-numeric characters and underscores:
81
+ * `*Job` matches: `ExampleJob`, but not `Namespaced::ExampleJob`, or `UserMailer#welcome`
82
+ * `UserMailer#*` matches any method of `UserMailer`
83
+ **::
84
+ Matches any number of components:
85
+ * `**` mathes any job or mailer method
86
+ * `A::**::Job` matches `A::B::Job`, `A::B::C::D::CJob`, etc.
87
+ * `A**::Job` matches `A::Job`, `Abc::Job`, `A::B::Job`, etc.
88
+ {}::
89
+ Matches any of the given literal:
90
+ * `{A,B,C}Job` matches `AJob`, `BJob`, and `CJob`
91
+
92
+
53
93
  == Supported Ruby Versions
54
94
 
55
95
  This library aims to support and is tested against the following Ruby versions:
@@ -76,8 +116,6 @@ dropped.
76
116
 
77
117
  This library aims to support and work with following Sidekiq versions:
78
118
 
79
- * Sidekiq 7.0.x
80
- * Sidekiq 7.1.x
81
119
  * Sidekiq 7.2.x
82
120
 
83
121
 
@@ -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
@@ -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
@@ -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.0.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.qualifier: 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.qualifier") %></label>
29
+ <div class="col-sm-10">
30
+ <input id="antidote-inhibitor-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-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>
@@ -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.0.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: 2023-12-11 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.0.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.0.0/CHANGES.md
72
72
  rubygems_mfa_required: 'true'
73
73
  post_install_message:
74
74
  rdoc_options: []
@@ -81,9 +81,9 @@ 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
88
  rubygems_version: 3.4.10
89
89
  signing_key: