delayable 0.4.2 → 0.5.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 +10 -0
- data/README.md +42 -0
- data/lib/delayable/version.rb +1 -1
- data/lib/delayable.rb +44 -5
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fbc0e3130501e50157a5dd2807576126022d145f89a3a005eb596b41c3456ecf
|
|
4
|
+
data.tar.gz: 729e2cf6548e11b220d7f8f19da46e55c1e520de3046ced844c5b858e4b1b2e5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3bd0b541a0d948c9c320a0ed7caf4e8f5585a147ed551c7e1b1c397c119cf4a23969ac510888c0f985e1d7c00997fac896fbdc3aa850d9ba0dc0865670336bf2
|
|
7
|
+
data.tar.gz: c81b5c272398ea577e9030852410a7813a8abcad24d7ec3ea3843e36b1529a0dfd79647d80cfe12edc093dc298ea2963c45680894376405ee15d4c8a94e58fa0
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.5.0 - 2026-08-03
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added class-level `_all_later` helpers for delayed instance methods.
|
|
10
|
+
- Added bulk enqueue support through `ActiveJob.perform_all_later`, with individual enqueue fallback for Rails 7.0 and adapters without bulk support.
|
data/README.md
CHANGED
|
@@ -9,6 +9,7 @@ A Ruby gem that makes it easy to convert any method call into a background job u
|
|
|
9
9
|
- **Flexible Configuration**: Configure queue names, delays, and concurrency limits per method
|
|
10
10
|
- **Method Parameter Support**: Full support for regular arguments, keyword arguments, and blocks
|
|
11
11
|
- **Bang Method Handling**: Automatic support for methods ending with `!`
|
|
12
|
+
- **Bulk Enqueuing**: Enqueue the same instance method for many receivers at once
|
|
12
13
|
- **ActiveJob Integration**: Seamlessly integrates with your existing ActiveJob setup
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
@@ -80,6 +81,46 @@ processor.process_csv_import_later("/tmp/users.csv", 123)
|
|
|
80
81
|
processor.sync_external_data_later("https://api.example.com/data", 1.hour.ago)
|
|
81
82
|
```
|
|
82
83
|
|
|
84
|
+
### Bulk Instance Methods
|
|
85
|
+
|
|
86
|
+
Every delayed instance method also gets a class-level `_all_later` helper. It creates one job per receiver and passes the same positional and keyword arguments to each:
|
|
87
|
+
|
|
88
|
+
```ruby
|
|
89
|
+
class Unit
|
|
90
|
+
include Delayable
|
|
91
|
+
|
|
92
|
+
def sync_channex_availability(date_from, date_to, channel:)
|
|
93
|
+
# Sync availability for this unit
|
|
94
|
+
end
|
|
95
|
+
delay :sync_channex_availability, queue: :integrations
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
Unit.sync_channex_availability_all_later(
|
|
99
|
+
units,
|
|
100
|
+
Date.current,
|
|
101
|
+
1.year.from_now.to_date,
|
|
102
|
+
channel: :channex
|
|
103
|
+
)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The helper preserves `Current.attributes` and all generated job configuration. A configured wait applies to every job and can be overridden per bulk call:
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
Unit.sync_channex_availability_all_later(
|
|
110
|
+
units,
|
|
111
|
+
date_from,
|
|
112
|
+
date_to,
|
|
113
|
+
channel: :channex,
|
|
114
|
+
wait: 30.seconds
|
|
115
|
+
)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Bang methods use `_all_later!`, such as `Unit.refresh_all_later!(units)`. Delayable does not remove duplicate receivers; use `units.uniq` when needed. An empty collection returns without enqueuing anything.
|
|
119
|
+
|
|
120
|
+
Bulk helpers are only generated for instance methods. Delayed class methods still use their regular `_later` helper.
|
|
121
|
+
|
|
122
|
+
Delayable uses `ActiveJob.perform_all_later` when available (Rails 7.1+). A true bulk queue operation requires an ActiveJob adapter that implements `enqueue_all`; otherwise ActiveJob enqueues each job individually. On Rails 7.0, Delayable also falls back to individual enqueues.
|
|
123
|
+
|
|
83
124
|
### Class Methods
|
|
84
125
|
|
|
85
126
|
You can also delay class methods by setting the `class_method: true` option:
|
|
@@ -429,6 +470,7 @@ DataProcessor::ProcessCsvImportJob.queue_name
|
|
|
429
470
|
- Ruby >= 3.4.0
|
|
430
471
|
- Rails >= 7.0.4.3
|
|
431
472
|
- ActiveJob configured with a backend (Sidekiq, Resque, etc.)
|
|
473
|
+
- An ActiveJob adapter with `enqueue_all` support for a true bulk queue operation (optional)
|
|
432
474
|
- **SolidQueue** (optional) - Required only if using `limits_concurrency` feature
|
|
433
475
|
|
|
434
476
|
## Contributing
|
data/lib/delayable/version.rb
CHANGED
data/lib/delayable.rb
CHANGED
|
@@ -25,10 +25,23 @@ module Delayable
|
|
|
25
25
|
)
|
|
26
26
|
|
|
27
27
|
defined_wait = wait
|
|
28
|
+
build_job = method(:delayable_build_job)
|
|
29
|
+
extract_wait = method(:delayable_extract_wait)
|
|
30
|
+
enqueue_jobs = method(:delayable_enqueue_jobs)
|
|
28
31
|
delayable_define_method(class_method:, method_name:) do |*arguments, **kwargs|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
job_wait = extract_wait.call(kwargs, defined_wait)
|
|
33
|
+
build_job.call(job, self, job_wait, arguments, kwargs, enqueue: true)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return if class_method
|
|
37
|
+
|
|
38
|
+
delayable_define_bulk_method(method_name) do |receivers, *arguments, **kwargs|
|
|
39
|
+
receivers = receivers.to_a
|
|
40
|
+
next if receivers.empty?
|
|
41
|
+
|
|
42
|
+
job_wait = extract_wait.call(kwargs, defined_wait)
|
|
43
|
+
jobs = receivers.map { |receiver| build_job.call(job, receiver, job_wait, arguments, kwargs) }
|
|
44
|
+
enqueue_jobs.call(jobs)
|
|
32
45
|
end
|
|
33
46
|
end
|
|
34
47
|
|
|
@@ -56,6 +69,24 @@ module Delayable
|
|
|
56
69
|
end
|
|
57
70
|
end
|
|
58
71
|
|
|
72
|
+
def delayable_build_job(job, receiver, wait, arguments, kwargs, enqueue: false)
|
|
73
|
+
run_data = { current_attributes: Current.attributes, record: receiver }
|
|
74
|
+
return job.set(wait:).perform_later(run_data, *arguments, **kwargs) if enqueue
|
|
75
|
+
|
|
76
|
+
job.new(run_data, *arguments, **kwargs).set(wait:)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def delayable_extract_wait(kwargs, defined_wait)
|
|
80
|
+
kwargs.key?(:wait) ? kwargs.delete(:wait) : defined_wait
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def delayable_enqueue_jobs(jobs)
|
|
84
|
+
return ActiveJob.perform_all_later(*jobs) if ActiveJob.respond_to?(:perform_all_later)
|
|
85
|
+
|
|
86
|
+
jobs.each(&:enqueue)
|
|
87
|
+
nil
|
|
88
|
+
end
|
|
89
|
+
|
|
59
90
|
def delayable_job_name(method_name, class_method: false)
|
|
60
91
|
class_name = bang_method?(method_name) ? "#{method_name.to_s.chomp('!').camelize}Bang" : method_name.to_s.camelize
|
|
61
92
|
:"#{'Class' if class_method}#{class_name}Job"
|
|
@@ -63,8 +94,16 @@ module Delayable
|
|
|
63
94
|
|
|
64
95
|
def delayable_define_method(class_method:, method_name:, &)
|
|
65
96
|
define_method_type = class_method ? :define_singleton_method : :define_method
|
|
66
|
-
|
|
67
|
-
|
|
97
|
+
public_send(define_method_type, delayable_method_name(method_name), &)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def delayable_define_bulk_method(method_name, &)
|
|
101
|
+
define_singleton_method(delayable_method_name(method_name, bulk: true), &)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def delayable_method_name(method_name, bulk: false)
|
|
105
|
+
suffix = bulk ? '_all_later' : '_later'
|
|
106
|
+
bang_method?(method_name) ? "#{method_name.to_s.chomp('!')}#{suffix}!" : "#{method_name}#{suffix}"
|
|
68
107
|
end
|
|
69
108
|
|
|
70
109
|
def bang_method?(method_name)
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: delayable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Trae Robrock
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-08-03 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|
|
@@ -33,6 +33,7 @@ extra_rdoc_files: []
|
|
|
33
33
|
files:
|
|
34
34
|
- ".rubocop.yml"
|
|
35
35
|
- ".ruby-version"
|
|
36
|
+
- CHANGELOG.md
|
|
36
37
|
- MIT-LICENSE
|
|
37
38
|
- README.md
|
|
38
39
|
- Rakefile
|