sidekiq-debouncer 2.0.1 → 3.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/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
|
- - ">="
|