sidekiq-antidote 1.0.0.alpha.1 → 1.0.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 +4 -4
- data/README.adoc +44 -6
- data/lib/sidekiq/antidote/config.rb +0 -37
- data/lib/sidekiq/antidote/remedy.rb +1 -0
- data/lib/sidekiq/antidote/repository.rb +4 -9
- data/lib/sidekiq/antidote/version.rb +1 -1
- data/lib/sidekiq/antidote.rb +3 -7
- data/web/locales/en.yml +4 -2
- data/web/views/add.html.erb +45 -20
- data/web/views/index.html.erb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3692f76b40f4cf3cf7c8231c3a882e09ab5f81dec49cc3711b268602cd9bb0a3
|
4
|
+
data.tar.gz: 2845af94e4a35930c1cd775a075774ee72a70af2c3a498f802f2cc56f99edf07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
@@ -8,12 +8,7 @@ module Sidekiq
|
|
8
8
|
class Repository
|
9
9
|
include Enumerable
|
10
10
|
|
11
|
-
|
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",
|
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",
|
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",
|
57
|
+
redis("HDEL", REDIS_KEY, *ids) unless ids.empty?
|
63
58
|
nil
|
64
59
|
end
|
65
60
|
|
data/lib/sidekiq/antidote.rb
CHANGED
@@ -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
|
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
|
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:
|
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?
|
data/web/views/add.html.erb
CHANGED
@@ -6,26 +6,51 @@
|
|
6
6
|
<div class="alert alert-danger"><%= @error %></div>
|
7
7
|
<% end %>
|
8
8
|
|
9
|
-
<
|
10
|
-
<%=
|
11
|
-
|
12
|
-
<div class="form-group
|
13
|
-
<label
|
14
|
-
<
|
15
|
-
|
16
|
-
<
|
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
|
-
|
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
|
21
|
-
<
|
22
|
-
|
23
|
-
|
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
|
-
</
|
28
|
-
|
29
|
-
<button id="antidote-inhibitor-submit" type="submit" class="btn"><%= t("antidote.submit") %></button>
|
30
|
-
</div>
|
31
|
-
</form>
|
55
|
+
</form>
|
56
|
+
</div>
|
data/web/views/index.html.erb
CHANGED
@@ -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("
|
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
|
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-
|
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.
|
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.
|
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
|
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
|
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:
|
86
|
+
version: '0'
|
87
87
|
requirements: []
|
88
88
|
rubygems_version: 3.4.10
|
89
89
|
signing_key:
|