sidekiq-defer 9.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 +7 -0
- data/Changes.md +28 -0
- data/Gemfile +33 -0
- data/LICENSE +9 -0
- data/README.md +74 -0
- data/bin/scan-usages +56 -0
- data/lib/sidekiq/defer/action_mailer.rb +54 -0
- data/lib/sidekiq/defer/active_record.rb +55 -0
- data/lib/sidekiq/defer/api.rb +47 -0
- data/lib/sidekiq/defer/class_methods.rb +51 -0
- data/lib/sidekiq/defer/generic_proxy.rb +48 -0
- data/lib/sidekiq/defer/testing.rb +25 -0
- data/lib/sidekiq/defer/version.rb +7 -0
- data/lib/sidekiq/defer.rb +52 -0
- data/lib/sidekiq/delay_extensions.rb +3 -0
- data/sidekiq-defer.gemspec +37 -0
- metadata +75 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 77c1e553b2257d6865e6c7f26f9c8f8827df0cfb3bf1cd041ca2e08ad26b3689
|
|
4
|
+
data.tar.gz: 7ceca6114681af72c73b1622ed2d771bb361b6697295f0ce6d10171b66411493
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a6a05dbce69a81702cd258c4419890d6b4767d06823b8cf16deb3e29fcb1c8e165a1dcab64e52b60175760284bc11dabb4ee9c205b7ea5a8aa2c472ef87f3d6a
|
|
7
|
+
data.tar.gz: 5afe1917ed9947930f5398617fbc5a3340cd85f47dc8c4c6ba3f5e9318f83112685a78ad4290791c6c0ea005b6cce7ee76487d1af78d50f57ad833b895cb1f3c
|
data/Changes.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# sidekiq-defer Changes
|
|
2
|
+
|
|
3
|
+
9.0.0
|
|
4
|
+
---------
|
|
5
|
+
|
|
6
|
+
- Renamed gem to `sidekiq-defer`
|
|
7
|
+
- Module renamed from `Sidekiq::DelayExtensions` to `Sidekiq::Delay`
|
|
8
|
+
- `Sidekiq::DelayExtensions` kept as a backward-compatible alias
|
|
9
|
+
|
|
10
|
+
8.0.0
|
|
11
|
+
---------
|
|
12
|
+
|
|
13
|
+
- Support sidekiq v8.0+
|
|
14
|
+
|
|
15
|
+
7.0.0
|
|
16
|
+
---------
|
|
17
|
+
|
|
18
|
+
- Support sidekiq v6.5+
|
|
19
|
+
|
|
20
|
+
6.4.1
|
|
21
|
+
---------
|
|
22
|
+
|
|
23
|
+
- Extracted from https://github.com/mperham/sidekiq/tree/v6.4.1
|
|
24
|
+
|
|
25
|
+
6.4.0
|
|
26
|
+
---------
|
|
27
|
+
|
|
28
|
+
- Extracted from https://github.com/mperham/sidekiq/tree/v6.4.0
|
data/Gemfile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gemspec
|
|
6
|
+
|
|
7
|
+
gem "activerecord-jdbcsqlite3-adapter", platforms: :jruby
|
|
8
|
+
gem "rails", "< 9"
|
|
9
|
+
gem "rake"
|
|
10
|
+
gem "redis-namespace"
|
|
11
|
+
gem "sqlite3", platforms: :ruby
|
|
12
|
+
|
|
13
|
+
# mail dependencies
|
|
14
|
+
gem "net-smtp", platforms: :mri, require: false
|
|
15
|
+
|
|
16
|
+
group :test do
|
|
17
|
+
gem "codecov", require: false
|
|
18
|
+
gem "minitest"
|
|
19
|
+
gem "simplecov"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
group :development, :test do
|
|
23
|
+
gem "rubocop", require: false
|
|
24
|
+
gem "rubocop-minitest", require: false
|
|
25
|
+
gem "rubocop-rails", require: false
|
|
26
|
+
gem "rubocop-rake", require: false
|
|
27
|
+
gem "standard", ">= 1.35.1", require: false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
group :load_test do
|
|
31
|
+
gem "hiredis"
|
|
32
|
+
gem "toxiproxy"
|
|
33
|
+
end
|
data/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Copyright (c) Contributed Systems LLC
|
|
2
|
+
|
|
3
|
+
Sidekiq is an Open Source project licensed under the terms of
|
|
4
|
+
the LGPLv3 license. Please see <http://www.gnu.org/licenses/lgpl-3.0.html>
|
|
5
|
+
for license text.
|
|
6
|
+
|
|
7
|
+
Sidekiq Pro and Sidekiq Enterprise have a commercial-friendly license.
|
|
8
|
+
You can find the commercial license in COMM-LICENSE.txt.
|
|
9
|
+
Please see https://sidekiq.org for purchasing options.
|
data/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
sidekiq-defer
|
|
2
|
+
==============
|
|
3
|
+
|
|
4
|
+
[](https://rubygems.org/gems/sidekiq-defer)
|
|
5
|
+
|
|
6
|
+
The Sidekiq delay extensions were removed in Sidekiq 7.x. This gem restores them for apps still relying on the `delay`/`delay_for`/`delay_until` pattern.
|
|
7
|
+
|
|
8
|
+
Each target class gets its own namespaced worker (e.g. `MyModel::DeferredJob`, `UserMailer::DeferredJob`), so jobs appear clearly in Sidekiq metrics instead of a generic wrapper class name.
|
|
9
|
+
|
|
10
|
+
Requirements
|
|
11
|
+
-----------------
|
|
12
|
+
|
|
13
|
+
- Redis: 6.2+
|
|
14
|
+
- Ruby: MRI 3.2+
|
|
15
|
+
- Sidekiq 7.0+
|
|
16
|
+
|
|
17
|
+
Installation
|
|
18
|
+
-----------------
|
|
19
|
+
|
|
20
|
+
gem 'sidekiq-defer'
|
|
21
|
+
|
|
22
|
+
In your initializer:
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
Sidekiq::Delay.enable_delay!
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Pass `limit_payload_size: true` (or a byte count) to log warnings on large YAML payloads:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
Sidekiq::Delay.enable_delay!(limit_payload_size: 8_192)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Upgrading from Sidekiq's built-in extensions (IMPORTANT)
|
|
35
|
+
-----------------
|
|
36
|
+
|
|
37
|
+
Jobs already in Redis were serialized with the old class names. Add these aliases so they can still be processed:
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
Sidekiq::Extensions::DelayedClass = Sidekiq::Defer::DelayedClass
|
|
41
|
+
Sidekiq::Extensions::DelayedModel = Sidekiq::Defer::DelayedModel
|
|
42
|
+
Sidekiq::Extensions::DelayedMailer = Sidekiq::Defer::DelayedMailer
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Upgrading from `sidekiq-delay_extensions`
|
|
46
|
+
-----------------
|
|
47
|
+
|
|
48
|
+
`Sidekiq::DelayExtensions` and `Sidekiq::Delay` are aliased to `Sidekiq::Defer` — existing code continues to work without changes.
|
|
49
|
+
|
|
50
|
+
Testing
|
|
51
|
+
-----------------
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
require 'sidekiq/defer/testing'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This hooks `DelayedMailer` and `DelayedModel` into Sidekiq's fake/inline testing modes.
|
|
58
|
+
|
|
59
|
+
Contributing
|
|
60
|
+
-----------------
|
|
61
|
+
|
|
62
|
+
Please open issues or pull requests at https://github.com/moskvin/sidekiq-delay_extensions.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
License
|
|
66
|
+
-----------------
|
|
67
|
+
|
|
68
|
+
Please see [LICENSE](https://github.com/moskvin/sidekiq-delay_extensions/blob/sidekiq8/LICENSE) for licensing details.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
Original Author
|
|
72
|
+
-----------------
|
|
73
|
+
|
|
74
|
+
Mike Perham, [@getajobmike](https://twitter.com/getajobmike) / [@sidekiq](https://twitter.com/sidekiq), [https://www.mikeperham.com](https://www.mikeperham.com) / [https://www.contribsys.com](https://www.contribsys.com)
|
data/bin/scan-usages
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Scan a project directory for all sidekiq-delay_extensions usages.
|
|
3
|
+
# Usage: bin/scan-usages [PATH] (defaults to current directory)
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
TARGET="${1:-.}"
|
|
8
|
+
|
|
9
|
+
RUBY_GLOB=("--include=*.rb" "--include=*.gemspec" "--include=Gemfile" "--include=Gemfile.lock")
|
|
10
|
+
|
|
11
|
+
echo "==> Scanning: $TARGET"
|
|
12
|
+
echo ""
|
|
13
|
+
|
|
14
|
+
section() { echo "--- $1 ---"; }
|
|
15
|
+
|
|
16
|
+
# ── Gemfile / gemspec references ───────────────────────────────────────────
|
|
17
|
+
section "Gem dependency references (Gemfile / gemspec)"
|
|
18
|
+
grep -rn "sidekiq-delay_extensions\|sidekiq-delay[^/]" \
|
|
19
|
+
--include="*.rb" --include="*.gemspec" --include="Gemfile" --include="Gemfile.lock" \
|
|
20
|
+
"$TARGET" 2>/dev/null || echo "(none found)"
|
|
21
|
+
echo ""
|
|
22
|
+
|
|
23
|
+
# ── enable_delay! call sites ────────────────────────────────────────────────
|
|
24
|
+
section "enable_delay! initializer calls"
|
|
25
|
+
grep -rn "enable_delay!" "${RUBY_GLOB[@]}" "$TARGET" 2>/dev/null || echo "(none found)"
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
# ── require paths ───────────────────────────────────────────────────────────
|
|
29
|
+
section "require 'sidekiq/delay_extensions' paths"
|
|
30
|
+
grep -rn "sidekiq/delay_extensions" "${RUBY_GLOB[@]}" "$TARGET" 2>/dev/null || echo "(none found)"
|
|
31
|
+
echo ""
|
|
32
|
+
|
|
33
|
+
# ── Proxy prepends / subclasses ─────────────────────────────────────────────
|
|
34
|
+
section "Proxy customisations (prepend / subclass)"
|
|
35
|
+
grep -rn "DelayExtensions::Proxy\|Delay::Proxy" "${RUBY_GLOB[@]}" "$TARGET" 2>/dev/null || echo "(none found)"
|
|
36
|
+
echo ""
|
|
37
|
+
|
|
38
|
+
# ── All remaining DelayExtensions references ────────────────────────────────
|
|
39
|
+
section "All other DelayExtensions references"
|
|
40
|
+
grep -rn "DelayExtensions" "${RUBY_GLOB[@]}" "$TARGET" 2>/dev/null \
|
|
41
|
+
| grep -v "enable_delay!\|delay_extensions\|DelayExtensions::Proxy" \
|
|
42
|
+
|| echo "(none found)"
|
|
43
|
+
echo ""
|
|
44
|
+
|
|
45
|
+
# ── Summary ─────────────────────────────────────────────────────────────────
|
|
46
|
+
section "Summary: unique files"
|
|
47
|
+
grep -rl "DelayExtensions\|sidekiq.delay_extensions\|sidekiq/delay_extensions" \
|
|
48
|
+
"${RUBY_GLOB[@]}" "$TARGET" 2>/dev/null \
|
|
49
|
+
| grep -v "vendor/\|node_modules/" \
|
|
50
|
+
| sort \
|
|
51
|
+
| uniq \
|
|
52
|
+
| while read -r f; do
|
|
53
|
+
count=$(grep -c "DelayExtensions\|sidekiq.delay_extensions\|sidekiq/delay_extensions" "$f" 2>/dev/null || true)
|
|
54
|
+
printf " %-60s %s hit(s)\n" "$f" "$count"
|
|
55
|
+
done
|
|
56
|
+
echo ""
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sidekiq/defer/generic_proxy'
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
module Defer
|
|
7
|
+
##
|
|
8
|
+
# Adds +delay+, +delay_for+ and +delay_until+ methods to ActionMailer to offload arbitrary email
|
|
9
|
+
# delivery to Sidekiq.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# UserMailer.delay.send_welcome_email(new_user)
|
|
13
|
+
# UserMailer.delay_for(5.days).send_welcome_email(new_user)
|
|
14
|
+
# UserMailer.delay_until(5.days.from_now).send_welcome_email(new_user)
|
|
15
|
+
class DelayedMailer
|
|
16
|
+
include Sidekiq::Job
|
|
17
|
+
|
|
18
|
+
def perform(yml)
|
|
19
|
+
(target, method_name, args) = YAML.safe_load(yml, permitted_classes: [Symbol])
|
|
20
|
+
msg = target.public_send(method_name, *args)
|
|
21
|
+
# The email method can return nil, which causes ActionMailer to return
|
|
22
|
+
# an undeliverable empty message.
|
|
23
|
+
raise "#{target.name}##{method_name} returned an undeliverable mail object" unless msg
|
|
24
|
+
|
|
25
|
+
msg.deliver_now
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module ActionMailer
|
|
30
|
+
def sidekiq_delay(**options)
|
|
31
|
+
Proxy.new(_sidekiq_delayed_job_class, self, **options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def sidekiq_delay_for(interval, **options)
|
|
35
|
+
Proxy.new(_sidekiq_delayed_job_class, self, **options.merge(at: Time.now.to_f + interval.to_f))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def sidekiq_delay_until(timestamp, **options)
|
|
39
|
+
Proxy.new(_sidekiq_delayed_job_class, self, **options.merge(at: timestamp.to_f))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
alias delay sidekiq_delay
|
|
43
|
+
alias delay_for sidekiq_delay_for
|
|
44
|
+
alias delay_until sidekiq_delay_until
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def _sidekiq_delayed_job_class
|
|
49
|
+
const_set(:DeferredJob, Class.new(DelayedMailer)) unless const_defined?(:DeferredJob, false)
|
|
50
|
+
const_get(:DeferredJob, false)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sidekiq/defer/generic_proxy'
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
module Defer
|
|
7
|
+
##
|
|
8
|
+
# Adds +delay+, +delay_for+ and +delay_until+ methods to ActiveRecord to offload instance method
|
|
9
|
+
# execution to Sidekiq.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# User.recent_signups.each { |user| user.delay.mark_as_awesome }
|
|
13
|
+
#
|
|
14
|
+
# Please note, this is not recommended as this will serialize the entire
|
|
15
|
+
# object to Redis. Your Sidekiq jobs should pass IDs, not entire instances.
|
|
16
|
+
# This is here for backwards compatibility with Delayed::Job only.
|
|
17
|
+
class DelayedModel
|
|
18
|
+
include Sidekiq::Job
|
|
19
|
+
|
|
20
|
+
def perform(yml)
|
|
21
|
+
(target, method_name, args, kwargs) = YAML.safe_load(yml, permitted_classes: [Symbol])
|
|
22
|
+
target.__send__(method_name, *args, **kwargs.to_h)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module ActiveRecord
|
|
27
|
+
def self.included(base)
|
|
28
|
+
base.extend(ClassMethods)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module ClassMethods
|
|
32
|
+
def _sidekiq_delayed_job_class
|
|
33
|
+
const_set(:DeferredJob, Class.new(DelayedModel)) unless const_defined?(:DeferredJob, false)
|
|
34
|
+
const_get(:DeferredJob, false)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def sidekiq_delay(**options)
|
|
39
|
+
Proxy.new(self.class._sidekiq_delayed_job_class, self, **options)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def sidekiq_delay_for(interval, **options)
|
|
43
|
+
Proxy.new(self.class._sidekiq_delayed_job_class, self, **options.merge(at: Time.now.to_f + interval.to_f))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def sidekiq_delay_until(timestamp, **options)
|
|
47
|
+
Proxy.new(self.class._sidekiq_delayed_job_class, self, **options.merge(at: timestamp.to_f))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
alias delay sidekiq_delay
|
|
51
|
+
alias delay_for sidekiq_delay_for
|
|
52
|
+
alias delay_until sidekiq_delay_until
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sidekiq/api'
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
module Defer
|
|
7
|
+
DELAYED_JOB_PATTERN = /\ASidekiq::Delay(?:Extensions)?::Delayed|::DeferredJob\z/
|
|
8
|
+
|
|
9
|
+
module JobRecord
|
|
10
|
+
def display_class
|
|
11
|
+
# Unwrap known wrappers so they show up in a human-friendly manner in the Web UI
|
|
12
|
+
@display_class ||= self['display_class'] || begin
|
|
13
|
+
case klass
|
|
14
|
+
when DELAYED_JOB_PATTERN
|
|
15
|
+
safe_load(args[0], klass) do |target, method, _|
|
|
16
|
+
"#{target}.#{method}"
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def display_args
|
|
25
|
+
# Unwrap known wrappers so they show up in a human-friendly manner in the Web UI
|
|
26
|
+
@display_args ||= case klass
|
|
27
|
+
when DELAYED_JOB_PATTERN
|
|
28
|
+
safe_load(args[0], args) do |_, _, arg, kwargs|
|
|
29
|
+
if !kwargs || kwargs.empty?
|
|
30
|
+
arg
|
|
31
|
+
else
|
|
32
|
+
[arg, kwargs]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
else
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def safe_load(content, _default)
|
|
43
|
+
yield(*YAML.safe_load(content, permitted_classes: [Symbol]))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "sidekiq/defer/generic_proxy"
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
module Defer
|
|
7
|
+
##
|
|
8
|
+
# Adds `delay`, `delay_for` and `delay_until` methods to all Classes to offload class method
|
|
9
|
+
# execution to Sidekiq.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# User.delay.delete_inactive
|
|
13
|
+
# Wikipedia.delay.download_changes_for(Date.today)
|
|
14
|
+
#
|
|
15
|
+
class DelayedClass
|
|
16
|
+
include Sidekiq::Job
|
|
17
|
+
|
|
18
|
+
def perform(yml)
|
|
19
|
+
(target, method_name, args, kwargs) = YAML.safe_load(yml, permitted_classes: [Symbol])
|
|
20
|
+
target.__send__(method_name, *args, **kwargs)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module Klass
|
|
25
|
+
def sidekiq_delay(**options)
|
|
26
|
+
Proxy.new(_sidekiq_delayed_job_class, self, **options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def sidekiq_delay_for(interval, **options)
|
|
30
|
+
Proxy.new(_sidekiq_delayed_job_class, self, **options.merge(at: Time.now.to_f + interval.to_f))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def sidekiq_delay_until(timestamp, **options)
|
|
34
|
+
Proxy.new(_sidekiq_delayed_job_class, self, **options.merge(at: timestamp.to_f))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
alias_method :delay, :sidekiq_delay
|
|
38
|
+
alias_method :delay_for, :sidekiq_delay_for
|
|
39
|
+
alias_method :delay_until, :sidekiq_delay_until
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def _sidekiq_delayed_job_class
|
|
44
|
+
const_set(:DeferredJob, Class.new(DelayedClass)) unless const_defined?(:DeferredJob, false)
|
|
45
|
+
const_get(:DeferredJob, false)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
Module.include Sidekiq::Defer::Klass unless defined?(::Rails)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
module Defer
|
|
7
|
+
DEFAULT_SIZE_LIMIT = 8_192
|
|
8
|
+
|
|
9
|
+
class Proxy < BasicObject
|
|
10
|
+
def initialize(performable, target, **options)
|
|
11
|
+
@performable = performable
|
|
12
|
+
@target = target
|
|
13
|
+
@opts = options.transform_keys(&:to_s)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def respond_to_missing?
|
|
17
|
+
true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def method_missing(name, *, **)
|
|
21
|
+
# Sidekiq has a limitation in that its message must be JSON.
|
|
22
|
+
# JSON can't round trip real Ruby objects so we use YAML to
|
|
23
|
+
# serialize the objects to a String. The YAML will be converted
|
|
24
|
+
# to JSON and then deserialized on the other side back into a
|
|
25
|
+
# Ruby object.
|
|
26
|
+
obj = [@target, name, [*], {**}]
|
|
27
|
+
marshalled = ::YAML.dump(obj)
|
|
28
|
+
print_warning(name, marshalled)
|
|
29
|
+
|
|
30
|
+
@performable.client_push({"class" => @performable,
|
|
31
|
+
"args" => [marshalled],
|
|
32
|
+
"display_class" => "#{@target}.#{name}"}.merge(@opts))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def print_warning(name, dump)
|
|
36
|
+
limited_payload_size = Defer.limit_payload_size
|
|
37
|
+
return unless limited_payload_size
|
|
38
|
+
|
|
39
|
+
size = (limited_payload_size != true) ? limited_payload_size : DEFAULT_SIZE_LIMIT
|
|
40
|
+
return if dump.size <= size
|
|
41
|
+
|
|
42
|
+
::Sidekiq.logger.warn do
|
|
43
|
+
"#{@target}.#{name} job argument is #{dump.bytesize} bytes, you should refactor it to reduce the size"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sidekiq/testing'
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
module TestingDefer
|
|
7
|
+
def jobs_for(klass)
|
|
8
|
+
jobs.select do |job|
|
|
9
|
+
marshalled = job['args'][0]
|
|
10
|
+
marshalled.index(klass.to_s) && YAML.safe_load(marshalled, permitted_classes: [Symbol])[0] == klass
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.enable_delay_testing!
|
|
15
|
+
Sidekiq::Defer::DelayedMailer.extend(TestingDefer) if defined?(Sidekiq::Defer::DelayedMailer)
|
|
16
|
+
return unless defined?(Sidekiq::Defer::DelayedModel)
|
|
17
|
+
|
|
18
|
+
Sidekiq::Defer::DelayedModel.extend(TestingDefer)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
TestingDefer.enable_delay_testing!
|
|
23
|
+
|
|
24
|
+
TestingDelayExtensions = TestingDefer
|
|
25
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sidekiq'
|
|
4
|
+
|
|
5
|
+
module Sidekiq
|
|
6
|
+
module Defer
|
|
7
|
+
class << self; attr_accessor :limit_payload_size; end
|
|
8
|
+
|
|
9
|
+
def self.enable_delay!(limit_payload_size: false)
|
|
10
|
+
self.limit_payload_size = limit_payload_size
|
|
11
|
+
if defined?(::ActiveSupport)
|
|
12
|
+
require 'sidekiq/defer/active_record'
|
|
13
|
+
require 'sidekiq/defer/action_mailer'
|
|
14
|
+
|
|
15
|
+
# Need to patch Psych so it can autoload classes whose names are serialized
|
|
16
|
+
# in the delayed YAML.
|
|
17
|
+
Psych::Visitors::ToRuby.prepend(Sidekiq::Defer::PsychAutoload)
|
|
18
|
+
|
|
19
|
+
ActiveSupport.on_load(:active_record) do
|
|
20
|
+
include Sidekiq::Defer::ActiveRecord
|
|
21
|
+
end
|
|
22
|
+
ActiveSupport.on_load(:action_mailer) do
|
|
23
|
+
extend Sidekiq::Defer::ActionMailer
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
require 'sidekiq/defer/class_methods'
|
|
28
|
+
Module.include Sidekiq::Defer::Klass
|
|
29
|
+
|
|
30
|
+
require 'sidekiq/defer/api'
|
|
31
|
+
Sidekiq::JobRecord.prepend(Sidekiq::Defer::JobRecord)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
module PsychAutoload
|
|
35
|
+
def resolve_class(klass_name)
|
|
36
|
+
return nil if !klass_name || klass_name.empty?
|
|
37
|
+
|
|
38
|
+
# constantize
|
|
39
|
+
names = klass_name.split('::')
|
|
40
|
+
names.shift if names.empty? || names.first.empty?
|
|
41
|
+
|
|
42
|
+
names.inject(Object) do |constant, name|
|
|
43
|
+
constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
|
44
|
+
end
|
|
45
|
+
rescue NameError
|
|
46
|
+
super
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
DelayExtensions = Defer
|
|
52
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/sidekiq/defer/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'sidekiq-defer'
|
|
7
|
+
spec.version = Sidekiq::Defer::VERSION
|
|
8
|
+
spec.authors = ['Mike Perham', 'Benjamin Fleischer']
|
|
9
|
+
spec.email = %w[mperham@gmail.com github@benjaminfleischer.com]
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Sidekiq Defer Extensions'
|
|
12
|
+
spec.description = 'Delay extensions for Sidekiq 7+'
|
|
13
|
+
spec.homepage = 'https://github.com/moskvin/sidekiq-delay_extensions'
|
|
14
|
+
spec.license = 'LGPL-3.0-or-later'
|
|
15
|
+
|
|
16
|
+
spec.files = Dir.glob('{bin,lib,config}/**/*') + %w[
|
|
17
|
+
Changes.md
|
|
18
|
+
Gemfile
|
|
19
|
+
LICENSE
|
|
20
|
+
README.md
|
|
21
|
+
sidekiq-defer.gemspec
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
spec.bindir = 'exe'
|
|
25
|
+
spec.executables = []
|
|
26
|
+
spec.require_paths = ['lib']
|
|
27
|
+
spec.required_ruby_version = '>= 3.2.0'
|
|
28
|
+
|
|
29
|
+
spec.metadata = {
|
|
30
|
+
'homepage_uri' => 'https://github.com/moskvin/sidekiq-delay_extensions',
|
|
31
|
+
'bug_tracker_uri' => 'https://github.com/moskvin/sidekiq-delay_extensions/issues',
|
|
32
|
+
'changelog_uri' => 'https://github.com/moskvin/sidekiq-delay_extensions/blob/sidekiq8/Changes.md',
|
|
33
|
+
'source_code_uri' => 'https://github.com/moskvin/sidekiq-delay_extensions'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
spec.add_dependency 'sidekiq', '< 9'
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sidekiq-defer
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 9.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Mike Perham
|
|
8
|
+
- Benjamin Fleischer
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: sidekiq
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "<"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '9'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "<"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '9'
|
|
27
|
+
description: Delay extensions for Sidekiq 7+
|
|
28
|
+
email:
|
|
29
|
+
- mperham@gmail.com
|
|
30
|
+
- github@benjaminfleischer.com
|
|
31
|
+
executables: []
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
files:
|
|
35
|
+
- Changes.md
|
|
36
|
+
- Gemfile
|
|
37
|
+
- LICENSE
|
|
38
|
+
- README.md
|
|
39
|
+
- bin/scan-usages
|
|
40
|
+
- lib/sidekiq/defer.rb
|
|
41
|
+
- lib/sidekiq/defer/action_mailer.rb
|
|
42
|
+
- lib/sidekiq/defer/active_record.rb
|
|
43
|
+
- lib/sidekiq/defer/api.rb
|
|
44
|
+
- lib/sidekiq/defer/class_methods.rb
|
|
45
|
+
- lib/sidekiq/defer/generic_proxy.rb
|
|
46
|
+
- lib/sidekiq/defer/testing.rb
|
|
47
|
+
- lib/sidekiq/defer/version.rb
|
|
48
|
+
- lib/sidekiq/delay_extensions.rb
|
|
49
|
+
- sidekiq-defer.gemspec
|
|
50
|
+
homepage: https://github.com/moskvin/sidekiq-delay_extensions
|
|
51
|
+
licenses:
|
|
52
|
+
- LGPL-3.0-or-later
|
|
53
|
+
metadata:
|
|
54
|
+
homepage_uri: https://github.com/moskvin/sidekiq-delay_extensions
|
|
55
|
+
bug_tracker_uri: https://github.com/moskvin/sidekiq-delay_extensions/issues
|
|
56
|
+
changelog_uri: https://github.com/moskvin/sidekiq-delay_extensions/blob/sidekiq8/Changes.md
|
|
57
|
+
source_code_uri: https://github.com/moskvin/sidekiq-delay_extensions
|
|
58
|
+
rdoc_options: []
|
|
59
|
+
require_paths:
|
|
60
|
+
- lib
|
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 3.2.0
|
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '0'
|
|
71
|
+
requirements: []
|
|
72
|
+
rubygems_version: 3.6.9
|
|
73
|
+
specification_version: 4
|
|
74
|
+
summary: Sidekiq Defer Extensions
|
|
75
|
+
test_files: []
|