sidekiq-debouncer 2.0.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +12 -0
- data/lib/sidekiq/debouncer/enq.rb +33 -0
- data/lib/sidekiq/debouncer/job.rb +41 -0
- data/lib/sidekiq/debouncer/launcher.rb +33 -0
- data/lib/sidekiq/debouncer/locales/en.yml +4 -0
- data/lib/sidekiq/debouncer/lua/debounce.lua +4 -16
- data/lib/sidekiq/debouncer/lua/zpopbyscore_multi.lua +5 -0
- data/lib/sidekiq/debouncer/lua/zpopbyscore_withscore.lua +6 -0
- data/lib/sidekiq/debouncer/lua_commands.rb +26 -0
- data/lib/sidekiq/debouncer/middleware/client.rb +18 -26
- data/lib/sidekiq/debouncer/poller.rb +14 -0
- data/lib/sidekiq/debouncer/set.rb +16 -0
- data/lib/sidekiq/debouncer/version.rb +1 -1
- data/lib/sidekiq/debouncer/views/index.html.erb +48 -0
- data/lib/sidekiq/debouncer/views/show.html.erb +38 -0
- data/lib/sidekiq/debouncer/web.rb +8 -0
- data/lib/sidekiq/debouncer/web_extension.rb +31 -0
- data/lib/sidekiq/debouncer.rb +11 -0
- data/sidekiq-debouncer.gemspec +3 -2
- metadata +32 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c98e0c985f240350757ce46298f39cb5586d7e01966f78bd3a886c8b4a78b7e0
|
4
|
+
data.tar.gz: e1f7ceda05cd4cc580fc5d318da59ccaf9a8a3f737020524c76a147add5fa5e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3175ce8da01db8a593290273a4a7c392133792de93c04a9091662ca96ab24caeea8a60e17e0ab7a7fd16e8b8273d184b62a421deb58374430e26f720f0708927
|
7
|
+
data.tar.gz: 2e42dedd11a4b6c05e9c4af5446803a1fab05daa7fe762b83ef3846b0f5c8cb253bf6f03e1bbbdc8e21311245087526c89098955c088d040c0c09606bba526da
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [3.0.0] - 2024-10-22
|
2
|
+
- Complete rewrite of the library ([#25](https://github.com/paladinsoftware/sidekiq-debouncer/pull/25))
|
3
|
+
- Read only Web UI ([#26](https://github.com/paladinsoftware/sidekiq-debouncer/pull/26))
|
4
|
+
- Drop support for sidekiq 6.x and ruby 2.7 ([#28](https://github.com/paladinsoftware/sidekiq-debouncer/pull/28))
|
5
|
+
- Respect sidekiq_options overridden by .set ([#27](https://github.com/paladinsoftware/sidekiq-debouncer/pull/27))
|
6
|
+
|
7
|
+
## [2.0.2] - 2023-03-13
|
8
|
+
- support Sidekiq::Testing
|
9
|
+
|
1
10
|
## [2.0.1] - 2023-03-04
|
2
11
|
- don't remove debounce key in redis to avoid invalid debouncing
|
3
12
|
|
data/README.md
CHANGED
@@ -99,10 +99,22 @@ Sidekiq.configure_client do |config|
|
|
99
99
|
end
|
100
100
|
```
|
101
101
|
|
102
|
+
## Web UI
|
103
|
+
Add `require 'sidekiq/debouncer/web'` after `require 'sidekiq/web'`.
|
104
|
+
|
102
105
|
## Testing
|
103
106
|
|
104
107
|
In order to test the behavior of `sidekiq-debouncer` it is necessary to disable testing mode. It is the limitation of internal implementation.
|
105
108
|
|
109
|
+
Sidekiq::Debouncer will not debounce the jobs in testing mode, instead they'll be executed like normal jobs (pushed to fake queue or executed inline depending on settings).
|
110
|
+
Server middleware needs to be added to `Sidekiq::Testing` chain:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
Sidekiq::Testing.server_middleware do |chain|
|
114
|
+
chain.add Sidekiq::Debouncer::Middleware::Server
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
106
118
|
## License
|
107
119
|
|
108
120
|
MIT Licensed. See LICENSE.txt for details.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sidekiq/scheduled"
|
4
|
+
|
5
|
+
module Sidekiq
|
6
|
+
module Debouncer
|
7
|
+
class Enq < ::Sidekiq::Scheduled::Enq
|
8
|
+
extend LuaCommands
|
9
|
+
|
10
|
+
LUA_ZPOPBYSCORE_WITHSCORE = File.read(File.expand_path("../lua/zpopbyscore_withscore.lua", __FILE__))
|
11
|
+
LUA_ZPOPBYSCORE_MULTI = File.read(File.expand_path("../lua/zpopbyscore_multi.lua", __FILE__))
|
12
|
+
|
13
|
+
define_lua_command(:zpopbyscore_withscore, LUA_ZPOPBYSCORE_WITHSCORE)
|
14
|
+
define_lua_command(:zpopbyscore_multi, LUA_ZPOPBYSCORE_MULTI)
|
15
|
+
|
16
|
+
def enqueue_jobs
|
17
|
+
redis do |conn|
|
18
|
+
while !@done && (job, score = zpopbyscore_withscore(conn, [Sidekiq::Debouncer::SET], [Time.now.to_f.to_s]))
|
19
|
+
job_args = zpopbyscore_multi(conn, [job], [score])
|
20
|
+
|
21
|
+
final_args = job_args.map { |elem| Sidekiq.load_json(elem.split("-", 2)[1]) }
|
22
|
+
job_class = job.split("/")[2]
|
23
|
+
klass = Object.const_get(job_class)
|
24
|
+
|
25
|
+
@client.push({"args" => final_args, "class" => klass, "debounce_key" => job})
|
26
|
+
|
27
|
+
logger.debug { "enqueued #{Sidekiq::Debouncer::SET}: #{job}" }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Debouncer
|
5
|
+
class Job
|
6
|
+
include Sidekiq::JobUtil
|
7
|
+
|
8
|
+
attr_reader :key, :score
|
9
|
+
|
10
|
+
def initialize(key, score)
|
11
|
+
@key = key
|
12
|
+
@score = score
|
13
|
+
end
|
14
|
+
|
15
|
+
def at
|
16
|
+
Time.at(score).utc
|
17
|
+
end
|
18
|
+
|
19
|
+
def args
|
20
|
+
@_args ||= Sidekiq.redis { |conn| conn.call("ZRANGE", key, "-inf", "+inf", "BYSCORE") }
|
21
|
+
.map { |elem| Sidekiq.load_json(elem.split("-", 2)[1]) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def queue
|
25
|
+
normalized["queue"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def klass
|
29
|
+
key.split("/")[2]
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :display_class, :klass
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def normalized
|
37
|
+
@_normalized ||= normalize_item({"args" => args, "class" => Object.const_get(klass), "debounce_key" => key})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Debouncer
|
5
|
+
module Launcher
|
6
|
+
def initialize(config, **kwargs)
|
7
|
+
@debounce_poller = Sidekiq::Debouncer::Poller.new(config)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
super
|
13
|
+
@debounce_poller.start
|
14
|
+
end
|
15
|
+
|
16
|
+
def quiet
|
17
|
+
super
|
18
|
+
@debounce_poller.terminate
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop
|
22
|
+
@debounce_poller.terminate
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Sidekiq.configure_server do
|
30
|
+
require "sidekiq/launcher"
|
31
|
+
|
32
|
+
::Sidekiq::Launcher.prepend(Sidekiq::Debouncer::Launcher)
|
33
|
+
end
|
@@ -1,22 +1,10 @@
|
|
1
1
|
local set = KEYS[1]
|
2
2
|
local debounce_key = KEYS[2]
|
3
3
|
|
4
|
-
local
|
4
|
+
local args = ARGV[1]
|
5
5
|
local time = ARGV[2]
|
6
6
|
local ttl = ARGV[3]
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
redis.call("DEL", debounce_key)
|
12
|
-
-- skip if job wasn't found in schedule set
|
13
|
-
if redis.call("ZREM", set, existing_debounce) > 0 then
|
14
|
-
local new_args = cjson.decode(job)['args'][1]
|
15
|
-
local new_job = cjson.decode(existing_debounce)
|
16
|
-
table.insert(new_job['args'], new_args)
|
17
|
-
job = cjson.encode(new_job)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
redis.call("SET", debounce_key, job, "EX", ttl)
|
22
|
-
redis.call("ZADD", set, time, job)
|
8
|
+
redis.call("ZADD", set, time, debounce_key)
|
9
|
+
redis.call("ZADD", debounce_key, time, args)
|
10
|
+
redis.call("EXPIRE", debounce_key, ttl)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "digest/sha1"
|
4
|
+
|
5
|
+
module Sidekiq
|
6
|
+
module Debouncer
|
7
|
+
module LuaCommands
|
8
|
+
def define_lua_command(command, script)
|
9
|
+
sha = Digest::SHA1.hexdigest(script)
|
10
|
+
define_method(command) do |conn, keys, argv|
|
11
|
+
retryable = true
|
12
|
+
begin
|
13
|
+
conn.call("EVALSHA", sha, keys.size, *keys, *argv)
|
14
|
+
rescue RedisClient::CommandError => e
|
15
|
+
raise if !e.message.start_with?("NOSCRIPT") || !retryable
|
16
|
+
|
17
|
+
# upload script to redis cache and retry
|
18
|
+
conn.call("SCRIPT", "LOAD", script)
|
19
|
+
retryable = false
|
20
|
+
retry
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "securerandom"
|
4
4
|
|
5
5
|
module Sidekiq
|
6
6
|
module Debouncer
|
@@ -11,10 +11,11 @@ module Sidekiq
|
|
11
11
|
# job from schedule set when another debounce occurs.
|
12
12
|
class Client
|
13
13
|
include Sidekiq::ClientMiddleware
|
14
|
+
extend Sidekiq::Debouncer::LuaCommands
|
14
15
|
|
15
16
|
LUA_DEBOUNCE = File.read(File.expand_path("../../lua/debounce.lua", __FILE__))
|
16
|
-
|
17
|
-
|
17
|
+
|
18
|
+
define_lua_command(:redis_debounce, LUA_DEBOUNCE)
|
18
19
|
|
19
20
|
def initialize(options = {})
|
20
21
|
@debounce_key_ttl = options.fetch(:ttl, 60 * 60 * 24) # 24 hours by default
|
@@ -28,9 +29,6 @@ module Sidekiq
|
|
28
29
|
return job if !klass.get_sidekiq_options["debounce"] || job["debounce_key"]
|
29
30
|
|
30
31
|
debounce(klass, job)
|
31
|
-
|
32
|
-
# prevent normal sidekiq flow
|
33
|
-
false
|
34
32
|
end
|
35
33
|
|
36
34
|
private
|
@@ -38,27 +36,31 @@ module Sidekiq
|
|
38
36
|
def debounce(klass, job)
|
39
37
|
raise NotSupportedError, "perform_at is not supported with debounce" if job.key?("at")
|
40
38
|
|
41
|
-
options = debounce_options(klass)
|
39
|
+
options = debounce_options(klass, job)
|
42
40
|
key = debounce_key(klass, job, options)
|
43
41
|
time = (options[:time].to_f + Time.now.to_f).to_s
|
44
42
|
|
45
|
-
job["
|
46
|
-
|
47
|
-
|
43
|
+
return job.merge("args" => [job["args"]], "debounce_key" => key) if testing?
|
44
|
+
|
45
|
+
args_stringified = "#{SecureRandom.hex(12)}-#{Sidekiq.dump_json(job["args"])}"
|
48
46
|
|
49
47
|
redis do |connection|
|
50
|
-
redis_debounce(connection,
|
48
|
+
redis_debounce(connection, [Sidekiq::Debouncer::SET, key], [args_stringified, time, @debounce_key_ttl])
|
51
49
|
end
|
50
|
+
|
51
|
+
# prevent normal sidekiq flow
|
52
|
+
false
|
52
53
|
end
|
53
54
|
|
54
55
|
def debounce_key(klass, job, options)
|
55
56
|
method = options[:by]
|
56
57
|
result = method.is_a?(Symbol) ? klass.send(method, job["args"]) : method.call(job["args"])
|
57
|
-
"debounce/#{klass.name}/#{result}"
|
58
|
+
"debounce/v3/#{klass.name}/#{result}"
|
58
59
|
end
|
59
60
|
|
60
|
-
def debounce_options(klass)
|
61
|
-
options = klass.get_sidekiq_options["debounce"]
|
61
|
+
def debounce_options(klass, job)
|
62
|
+
options = job.fetch("debounce") { klass.get_sidekiq_options["debounce"] }
|
63
|
+
options = options.transform_keys(&:to_sym)
|
62
64
|
|
63
65
|
raise MissingArgumentError, "'by' attribute not provided" unless options[:by]
|
64
66
|
raise MissingArgumentError, "'time' attribute not provided" unless options[:time]
|
@@ -66,18 +68,8 @@ module Sidekiq
|
|
66
68
|
options
|
67
69
|
end
|
68
70
|
|
69
|
-
def
|
70
|
-
|
71
|
-
begin
|
72
|
-
connection.call("EVALSHA", LUA_DEBOUNCE_SHA, keys.size, *keys, *argv)
|
73
|
-
rescue REDIS_ERROR_CLASS => e
|
74
|
-
raise if !e.message.start_with?("NOSCRIPT") || !retryable
|
75
|
-
|
76
|
-
# upload script to redis cache and retry
|
77
|
-
connection.call("SCRIPT", "LOAD", LUA_DEBOUNCE)
|
78
|
-
retryable = false
|
79
|
-
retry
|
80
|
-
end
|
71
|
+
def testing?
|
72
|
+
defined?(Sidekiq::Testing) && Sidekiq::Testing.enabled?
|
81
73
|
end
|
82
74
|
end
|
83
75
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Debouncer
|
5
|
+
class Set < Sidekiq::JobSet
|
6
|
+
def initialize
|
7
|
+
super Sidekiq::Debouncer::SET
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch_by_key(key)
|
11
|
+
score = Sidekiq.redis { |conn| conn.zscore(Sidekiq::Debouncer::SET, key) }
|
12
|
+
Job.new(key, score)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<header class='row'>
|
2
|
+
<div class='col-sm-5 pull-left'>
|
3
|
+
<h3><%= t('Debounces') %></h3>
|
4
|
+
</div>
|
5
|
+
<div class='col-sm-7 pull-right'>
|
6
|
+
<%= erb :_paging, locals: { url: "#{root_path}debounces" } %>
|
7
|
+
</div>
|
8
|
+
</header>
|
9
|
+
|
10
|
+
<% if @debounces.size > 0 %>
|
11
|
+
<form action="<%= root_path %>debounces" method="post">
|
12
|
+
<%= csrf_tag %>
|
13
|
+
<div class="table_container">
|
14
|
+
<table class="table table-striped table-bordered table-hover">
|
15
|
+
<thead>
|
16
|
+
<tr>
|
17
|
+
<th class="table-checkbox checkbox-column">
|
18
|
+
<label>
|
19
|
+
<input type="checkbox" class="check_all" />
|
20
|
+
</label>
|
21
|
+
</th>
|
22
|
+
<th><%= t('When') %></th>
|
23
|
+
<th><%= t('DebounceKey') %></th>
|
24
|
+
</tr>
|
25
|
+
</thead>
|
26
|
+
<% @debounces.each do |entry| %>
|
27
|
+
<tr>
|
28
|
+
<td class="table-checkbox">
|
29
|
+
<label>
|
30
|
+
<input type='checkbox' name='key[]' value='<%= entry.key %>' class='shift_clickable' />
|
31
|
+
</label>
|
32
|
+
</td>
|
33
|
+
<td>
|
34
|
+
<a href="<%= root_path %>debounces/<%= ::Base64.urlsafe_encode64(entry.key) %>"><%= relative_time(entry.at) %></a>
|
35
|
+
</td>
|
36
|
+
<td>
|
37
|
+
<a href="<%= root_path %>debounces/<%= ::Base64.urlsafe_encode64(entry.key) %>"><%= entry.key %></a>
|
38
|
+
</td>
|
39
|
+
</tr>
|
40
|
+
<% end %>
|
41
|
+
</table>
|
42
|
+
</div>
|
43
|
+
<!-- <input class="btn btn-danger pull-right flip" type="submit" name="delete" value="<%#= t('Delete') %>" />-->
|
44
|
+
<!-- <input class="btn btn-danger pull-right flip" type="submit" name="add_to_queue" value="<%#= t('AddToQueue') %>" />-->
|
45
|
+
</form>
|
46
|
+
<% else %>
|
47
|
+
<div class="alert alert-success"><%= t('NoDebouncesFound') %></div>
|
48
|
+
<% end %>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<div class="header-container">
|
2
|
+
<h3><%= t('Job') %></h3>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<div class="table_container">
|
6
|
+
<table class="table table-bordered table-striped table-hover">
|
7
|
+
<tbody>
|
8
|
+
<tr>
|
9
|
+
<th><%= t('Queue') %></th>
|
10
|
+
<td><%= @job.queue %></td>
|
11
|
+
</tr>
|
12
|
+
<tr>
|
13
|
+
<th><%= t('When') %></th>
|
14
|
+
<td><%= relative_time(@job.at) %></td>
|
15
|
+
</tr>
|
16
|
+
<tr>
|
17
|
+
<th><%= t('DebounceKey') %></th>
|
18
|
+
<td>
|
19
|
+
<%= @job.key %>
|
20
|
+
</td>
|
21
|
+
</tr>
|
22
|
+
<tr>
|
23
|
+
<th><%= t('Job') %></th>
|
24
|
+
<td>
|
25
|
+
<%= @job.display_class %>
|
26
|
+
</td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<th><%= t('Arguments') %></th>
|
30
|
+
<td>
|
31
|
+
<code class="code-wrap">
|
32
|
+
<div class="args-extended"><%= display_args(@job.args, nil) %></div>
|
33
|
+
</code>
|
34
|
+
</td>
|
35
|
+
</tr>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
</div>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "base64"
|
4
|
+
|
5
|
+
module Sidekiq
|
6
|
+
module Debouncer
|
7
|
+
module WebExtension
|
8
|
+
def self.registered(app)
|
9
|
+
app.settings.locales << File.join(File.expand_path("..", __FILE__), "locales")
|
10
|
+
|
11
|
+
app.get "/debounces" do
|
12
|
+
view_path = File.join(File.expand_path("..", __FILE__), "views")
|
13
|
+
|
14
|
+
@count = (params["count"] || 25).to_i
|
15
|
+
(@current_page, @total_size, @debounces) = page("debouncer", params["page"], @count)
|
16
|
+
@debounces = @debounces.map { |key, score| Sidekiq::Debouncer::Job.new(key, score) }
|
17
|
+
|
18
|
+
render(:erb, File.read(File.join(view_path, "index.html.erb")))
|
19
|
+
end
|
20
|
+
|
21
|
+
app.get "/debounces/:key" do
|
22
|
+
view_path = File.join(File.expand_path("..", __FILE__), "views")
|
23
|
+
|
24
|
+
@job = Sidekiq::Debouncer::Set.new.fetch_by_key(Base64.urlsafe_decode64(route_params[:key]))
|
25
|
+
|
26
|
+
render(:erb, File.read(File.join(view_path, "show.html.erb")))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/sidekiq/debouncer.rb
CHANGED
@@ -2,11 +2,16 @@
|
|
2
2
|
|
3
3
|
require "sidekiq/debouncer/version"
|
4
4
|
require "sidekiq/debouncer/errors"
|
5
|
+
require "sidekiq/debouncer/lua_commands"
|
5
6
|
require "sidekiq/debouncer/middleware/client"
|
6
7
|
require "sidekiq/debouncer/middleware/server"
|
8
|
+
require "sidekiq/debouncer/job"
|
9
|
+
require "sidekiq/debouncer/set"
|
7
10
|
|
8
11
|
module Sidekiq
|
9
12
|
module Debouncer
|
13
|
+
SET = "debouncer"
|
14
|
+
|
10
15
|
def self.included(base)
|
11
16
|
base.extend ClassMethods
|
12
17
|
end
|
@@ -19,3 +24,9 @@ module Sidekiq
|
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
27
|
+
|
28
|
+
Sidekiq.configure_server do
|
29
|
+
require "sidekiq/debouncer/enq"
|
30
|
+
require "sidekiq/debouncer/poller"
|
31
|
+
require "sidekiq/debouncer/launcher"
|
32
|
+
end
|
data/sidekiq-debouncer.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
DESCRIPTION
|
19
19
|
gem.homepage = "https://github.com/paladinsoftware/sidekiq-debouncer"
|
20
20
|
gem.license = "MIT"
|
21
|
-
gem.required_ruby_version = ">=
|
21
|
+
gem.required_ruby_version = ">= 3.0.0"
|
22
22
|
|
23
23
|
gem.files = Dir.glob("lib/**/*") + [
|
24
24
|
"CHANGELOG.md",
|
@@ -27,11 +27,12 @@ Gem::Specification.new do |gem|
|
|
27
27
|
"sidekiq-debouncer.gemspec"
|
28
28
|
]
|
29
29
|
|
30
|
-
gem.add_dependency "sidekiq", ">=
|
30
|
+
gem.add_dependency "sidekiq", ">= 7.0", "< 8.0"
|
31
31
|
|
32
32
|
gem.add_development_dependency "rspec", "~> 3.12.0"
|
33
33
|
gem.add_development_dependency "timecop", "~> 0.9.6"
|
34
34
|
gem.add_development_dependency "simplecov", "~> 0.22.0"
|
35
35
|
gem.add_development_dependency "parallel", "~> 1.22.1"
|
36
36
|
gem.add_development_dependency "standard", "~> 1.24.3"
|
37
|
+
gem.add_development_dependency "rack-test", "~> 2.1.0"
|
37
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-debouncer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Zuchmański
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-10-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sidekiq
|
@@ -17,7 +17,7 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '7.0'
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: '8.0'
|
@@ -27,7 +27,7 @@ dependencies:
|
|
27
27
|
requirements:
|
28
28
|
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version: '
|
30
|
+
version: '7.0'
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '8.0'
|
@@ -101,6 +101,20 @@ dependencies:
|
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 1.24.3
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: rack-test
|
106
|
+
requirement: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.1.0
|
111
|
+
type: :development
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.1.0
|
104
118
|
description: |
|
105
119
|
Sidekiq extension that adds the ability to debounce job execution.
|
106
120
|
Worker will postpone its execution after `wait time` have elapsed since the last time it was invoked.
|
@@ -117,11 +131,24 @@ files:
|
|
117
131
|
- README.md
|
118
132
|
- lib/sidekiq-debouncer.rb
|
119
133
|
- lib/sidekiq/debouncer.rb
|
134
|
+
- lib/sidekiq/debouncer/enq.rb
|
120
135
|
- lib/sidekiq/debouncer/errors.rb
|
136
|
+
- lib/sidekiq/debouncer/job.rb
|
137
|
+
- lib/sidekiq/debouncer/launcher.rb
|
138
|
+
- lib/sidekiq/debouncer/locales/en.yml
|
121
139
|
- lib/sidekiq/debouncer/lua/debounce.lua
|
140
|
+
- lib/sidekiq/debouncer/lua/zpopbyscore_multi.lua
|
141
|
+
- lib/sidekiq/debouncer/lua/zpopbyscore_withscore.lua
|
142
|
+
- lib/sidekiq/debouncer/lua_commands.rb
|
122
143
|
- lib/sidekiq/debouncer/middleware/client.rb
|
123
144
|
- lib/sidekiq/debouncer/middleware/server.rb
|
145
|
+
- lib/sidekiq/debouncer/poller.rb
|
146
|
+
- lib/sidekiq/debouncer/set.rb
|
124
147
|
- lib/sidekiq/debouncer/version.rb
|
148
|
+
- lib/sidekiq/debouncer/views/index.html.erb
|
149
|
+
- lib/sidekiq/debouncer/views/show.html.erb
|
150
|
+
- lib/sidekiq/debouncer/web.rb
|
151
|
+
- lib/sidekiq/debouncer/web_extension.rb
|
125
152
|
- sidekiq-debouncer.gemspec
|
126
153
|
homepage: https://github.com/paladinsoftware/sidekiq-debouncer
|
127
154
|
licenses:
|
@@ -135,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
162
|
requirements:
|
136
163
|
- - ">="
|
137
164
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
165
|
+
version: 3.0.0
|
139
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
167
|
requirements:
|
141
168
|
- - ">="
|