delayable 0.4.1 → 0.4.2
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.md +427 -5
- data/lib/delayable/version.rb +1 -1
- data/lib/delayable.rb +17 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c17ddd3e91c54be2b587b653633a034aec19f240a0a15439b80aa5ed88a9c11f
|
|
4
|
+
data.tar.gz: e589da2392206c0f1574199fd1bc3b3c2c59161886a2f11effeb32b79fb5ecfd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c22ae61f2b817ac71bd85f96bb9d65f3d0d985a58b5fdf9dd67e10ec7654afc71943c09aa5710ac367a2a1bc9d5579b45eccdf365b486168f9df01ca0af5cbb
|
|
7
|
+
data.tar.gz: 6c73c6c141da927a236674c774ec8ad3124128b3f0017e6d05ac40ae4a72a04eaf2fb9ac4d22076cd5f241b68b9c9b19cac42e5ab2cbe9bc35c6093b18b333e1
|
data/README.md
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
# Delayable
|
|
2
|
-
Short description and motivation.
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
A Ruby gem that makes it easy to convert any method call into a background job using ActiveJob. Simply include the `Delayable` module and use the `delay` class method to mark methods that should be available for background execution.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Easy Background Jobs**: Convert any instance or class method into a background job with minimal setup
|
|
8
|
+
- **Current Attributes Preservation**: Automatically preserves Rails `Current` attributes across job boundaries
|
|
9
|
+
- **Flexible Configuration**: Configure queue names, delays, and concurrency limits per method
|
|
10
|
+
- **Method Parameter Support**: Full support for regular arguments, keyword arguments, and blocks
|
|
11
|
+
- **Bang Method Handling**: Automatic support for methods ending with `!`
|
|
12
|
+
- **ActiveJob Integration**: Seamlessly integrates with your existing ActiveJob setup
|
|
6
13
|
|
|
7
14
|
## Installation
|
|
15
|
+
|
|
8
16
|
Add this line to your application's Gemfile:
|
|
9
17
|
|
|
10
18
|
```ruby
|
|
@@ -13,7 +21,7 @@ gem "delayable"
|
|
|
13
21
|
|
|
14
22
|
And then execute:
|
|
15
23
|
```bash
|
|
16
|
-
$ bundle
|
|
24
|
+
$ bundle install
|
|
17
25
|
```
|
|
18
26
|
|
|
19
27
|
Or install it yourself as:
|
|
@@ -21,8 +29,422 @@ Or install it yourself as:
|
|
|
21
29
|
$ gem install delayable
|
|
22
30
|
```
|
|
23
31
|
|
|
32
|
+
## Prerequisites
|
|
33
|
+
|
|
34
|
+
Before using Delayable, ensure you have the following defined in your Rails application:
|
|
35
|
+
|
|
36
|
+
1. **ApplicationJob**: Your base job class
|
|
37
|
+
2. **Current**: A CurrentAttributes class for maintaining context
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
# app/jobs/application_job.rb
|
|
41
|
+
class ApplicationJob < ActiveJob::Base
|
|
42
|
+
# Your job configuration
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# app/models/current.rb
|
|
46
|
+
class Current < ActiveSupport::CurrentAttributes
|
|
47
|
+
attribute :user, :request_id, :user_agent
|
|
48
|
+
# Add other attributes as needed
|
|
49
|
+
end
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Basic Usage
|
|
53
|
+
|
|
54
|
+
### Instance Methods
|
|
55
|
+
|
|
56
|
+
Include `Delayable` in your class and use the `delay` method to mark methods for background execution:
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
class DataProcessor
|
|
60
|
+
include Delayable
|
|
61
|
+
|
|
62
|
+
def process_csv_import(file_path, user_id)
|
|
63
|
+
user = User.find(user_id)
|
|
64
|
+
CSV.foreach(file_path, headers: true) do |row|
|
|
65
|
+
user.records.create!(row.to_h)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
delay :process_csv_import
|
|
69
|
+
|
|
70
|
+
def sync_external_data(api_endpoint, last_sync_time)
|
|
71
|
+
# Fetch and process data from external API
|
|
72
|
+
ExternalApiClient.new(api_endpoint).sync_data_since(last_sync_time)
|
|
73
|
+
end
|
|
74
|
+
delay :sync_external_data
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Usage
|
|
78
|
+
processor = DataProcessor.new
|
|
79
|
+
processor.process_csv_import_later("/tmp/users.csv", 123)
|
|
80
|
+
processor.sync_external_data_later("https://api.example.com/data", 1.hour.ago)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Class Methods
|
|
84
|
+
|
|
85
|
+
You can also delay class methods by setting the `class_method: true` option:
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
class ReportGenerator
|
|
89
|
+
include Delayable
|
|
90
|
+
|
|
91
|
+
def self.generate_monthly_report(month, year)
|
|
92
|
+
# Generate report logic
|
|
93
|
+
end
|
|
94
|
+
delay :generate_monthly_report, class_method: true
|
|
95
|
+
|
|
96
|
+
def self.cleanup_old_reports!
|
|
97
|
+
# Cleanup logic
|
|
98
|
+
end
|
|
99
|
+
delay :cleanup_old_reports!, class_method: true
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Usage
|
|
103
|
+
ReportGenerator.generate_monthly_report_later(12, 2023)
|
|
104
|
+
ReportGenerator.cleanup_old_reports_later!
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Methods with Bang (!)
|
|
108
|
+
|
|
109
|
+
Delayable automatically handles methods ending with `!`:
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
class DataProcessor
|
|
113
|
+
include Delayable
|
|
114
|
+
|
|
115
|
+
def process_data!
|
|
116
|
+
# Processing logic
|
|
117
|
+
end
|
|
118
|
+
delay :process_data!
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Usage - note the bang is preserved in the delayed method name
|
|
122
|
+
processor = DataProcessor.new
|
|
123
|
+
processor.process_data_later! # Creates ProcessDataBangJob
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Advanced Configuration
|
|
127
|
+
|
|
128
|
+
### Queue Configuration
|
|
129
|
+
|
|
130
|
+
Specify which queue to use for the background job:
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
class DataProcessor
|
|
134
|
+
include Delayable
|
|
135
|
+
|
|
136
|
+
def process_csv_import(file_path)
|
|
137
|
+
# Large CSV processing logic
|
|
138
|
+
end
|
|
139
|
+
delay :process_csv_import, queue: :data_processing
|
|
140
|
+
|
|
141
|
+
def sync_external_api(endpoint)
|
|
142
|
+
# API synchronization logic
|
|
143
|
+
end
|
|
144
|
+
delay :sync_external_api, queue: :integrations
|
|
145
|
+
end
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Delay Execution
|
|
149
|
+
|
|
150
|
+
Set a default delay for job execution:
|
|
151
|
+
|
|
152
|
+
```ruby
|
|
153
|
+
class CacheManager
|
|
154
|
+
include Delayable
|
|
155
|
+
|
|
156
|
+
def warm_cache(cache_key)
|
|
157
|
+
# Pre-populate cache logic
|
|
158
|
+
end
|
|
159
|
+
delay :warm_cache, wait: 5.minutes
|
|
160
|
+
|
|
161
|
+
def cleanup_expired_entries
|
|
162
|
+
# Cache cleanup logic
|
|
163
|
+
end
|
|
164
|
+
delay :cleanup_expired_entries, wait: 1.hour
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# You can also override the delay at call time
|
|
168
|
+
manager = CacheManager.new
|
|
169
|
+
manager.warm_cache_later("user_stats", wait: 30.seconds) # Overrides the 5.minutes default
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Concurrency Limits
|
|
173
|
+
|
|
174
|
+
Limit how many jobs of this type can run concurrently using SolidQueue's concurrency controls:
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
class ResourceIntensiveTask
|
|
178
|
+
include Delayable
|
|
179
|
+
|
|
180
|
+
def process_large_file(file_path)
|
|
181
|
+
# Heavy processing that should be limited
|
|
182
|
+
end
|
|
183
|
+
delay :process_large_file, limits_concurrency: { to: 2 }
|
|
184
|
+
|
|
185
|
+
def generate_report(report_type)
|
|
186
|
+
# Report generation that should run one at a time per report type
|
|
187
|
+
end
|
|
188
|
+
delay :generate_report, limits_concurrency: {
|
|
189
|
+
to: 1,
|
|
190
|
+
key: ->(run_data, report_type) { "report_#{report_type}" }
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
def process_batch(batch_id, options = {})
|
|
194
|
+
# Process a batch with concurrency control per batch
|
|
195
|
+
end
|
|
196
|
+
delay :process_batch, limits_concurrency: {
|
|
197
|
+
to: 3,
|
|
198
|
+
key: ->(_run_data, batch_id) { "batch_#{batch_id}" }
|
|
199
|
+
}
|
|
200
|
+
end
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Important:** When using the `key` proc with `limits_concurrency`, the proc receives the delayed job arguments. The first argument is Delayable's internal `run_data` hash (`current_attributes` and `record`), followed by the arguments passed to your delayed method.
|
|
204
|
+
|
|
205
|
+
**Note:** The `limits_concurrency` feature requires SolidQueue as your ActiveJob backend. Other job backends (Sidekiq, Resque, etc.) do not support this feature and will ignore the setting.
|
|
206
|
+
|
|
207
|
+
## Current Attributes
|
|
208
|
+
|
|
209
|
+
Delayable automatically preserves Rails `Current` attributes across job boundaries:
|
|
210
|
+
|
|
211
|
+
```ruby
|
|
212
|
+
class AuditLogger
|
|
213
|
+
include Delayable
|
|
214
|
+
|
|
215
|
+
def log_action(action, resource_id)
|
|
216
|
+
AuditLog.create!(
|
|
217
|
+
action: action,
|
|
218
|
+
resource_id: resource_id,
|
|
219
|
+
user: Current.user, # This will be preserved from the original request
|
|
220
|
+
request_id: Current.request_id
|
|
221
|
+
)
|
|
222
|
+
end
|
|
223
|
+
delay :log_action
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# In a controller
|
|
227
|
+
class PostsController < ApplicationController
|
|
228
|
+
def create
|
|
229
|
+
Current.user = current_user
|
|
230
|
+
Current.request_id = request.id
|
|
231
|
+
|
|
232
|
+
post = Post.create!(post_params)
|
|
233
|
+
|
|
234
|
+
# The job will have access to Current.user and Current.request_id
|
|
235
|
+
AuditLogger.new.log_action_later("create", post.id)
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Working with ActiveRecord Models
|
|
241
|
+
|
|
242
|
+
Delayable works seamlessly with ActiveRecord models:
|
|
243
|
+
|
|
244
|
+
```ruby
|
|
245
|
+
class User < ApplicationRecord
|
|
246
|
+
include Delayable
|
|
247
|
+
|
|
248
|
+
def update_profile_completeness
|
|
249
|
+
score = calculate_completeness_score
|
|
250
|
+
update!(profile_completeness: score)
|
|
251
|
+
end
|
|
252
|
+
delay :update_profile_completeness
|
|
253
|
+
|
|
254
|
+
def calculate_metrics!
|
|
255
|
+
update!(
|
|
256
|
+
total_posts: posts.count,
|
|
257
|
+
total_comments: comments.count,
|
|
258
|
+
last_activity: Time.current
|
|
259
|
+
)
|
|
260
|
+
end
|
|
261
|
+
delay :calculate_metrics!
|
|
262
|
+
|
|
263
|
+
def archive_old_data!
|
|
264
|
+
# Archive user's old posts, comments, etc.
|
|
265
|
+
posts.where('created_at < ?', 1.year.ago).update_all(archived: true)
|
|
266
|
+
comments.where('created_at < ?', 1.year.ago).delete_all
|
|
267
|
+
end
|
|
268
|
+
delay :archive_old_data!
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Usage
|
|
272
|
+
user = User.find(123)
|
|
273
|
+
user.update_profile_completeness_later
|
|
274
|
+
user.calculate_metrics_later!
|
|
275
|
+
user.archive_old_data_later!
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Job Naming Convention
|
|
279
|
+
|
|
280
|
+
Delayable automatically generates job class names based on your method names to ensure logging and debugging remain clear and meaningful:
|
|
281
|
+
|
|
282
|
+
| Method Name | Method Type | Generated Job Class |
|
|
283
|
+
|-------------|-------------|-------------------|
|
|
284
|
+
| `process_data` | instance | `YourClass::ProcessDataJob` |
|
|
285
|
+
| `process_data!` | instance | `YourClass::ProcessDataBangJob` |
|
|
286
|
+
| `generate_report` | class | `YourClass::ClassGenerateReportJob` |
|
|
287
|
+
| `cleanup!` | class | `YourClass::ClassCleanupBangJob` |
|
|
288
|
+
|
|
289
|
+
This naming convention ensures that when you're monitoring job queues, reading logs, or debugging failed jobs, you can immediately understand what method was being executed and in what context. The job name directly corresponds to your original method, making it easy to trace issues back to your application code.
|
|
290
|
+
|
|
291
|
+
## Error Handling
|
|
292
|
+
|
|
293
|
+
Since Delayable creates standard ActiveJob jobs, you can use all the standard ActiveJob error handling mechanisms. Put defaults on `ApplicationJob`, or pass a block to `delay` to configure the generated job class:
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
# In your ApplicationJob
|
|
297
|
+
class ApplicationJob < ActiveJob::Base
|
|
298
|
+
retry_on StandardError, wait: :exponentially_longer, attempts: 5
|
|
299
|
+
discard_on ActiveRecord::RecordNotFound
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
class BookingSync
|
|
303
|
+
include Delayable
|
|
304
|
+
|
|
305
|
+
def sync_channex_bookings
|
|
306
|
+
# Sync bookings
|
|
307
|
+
end
|
|
308
|
+
delay :sync_channex_bookings,
|
|
309
|
+
limits_concurrency: {
|
|
310
|
+
to: 1,
|
|
311
|
+
key: ->(run_data) { "#{run_data[:record].to_global_id}-channex-bookings" }
|
|
312
|
+
} do
|
|
313
|
+
retry_on Channex::Api::ConnectionError,
|
|
314
|
+
wait: :polynomially_longer,
|
|
315
|
+
attempts: 5
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Testing
|
|
321
|
+
|
|
322
|
+
Delayable integrates with ActiveJob's testing helpers:
|
|
323
|
+
|
|
324
|
+
```ruby
|
|
325
|
+
require 'test_helper'
|
|
326
|
+
|
|
327
|
+
class DataProcessorTest < ActiveSupport::TestCase
|
|
328
|
+
include ActiveJob::TestHelper
|
|
329
|
+
|
|
330
|
+
test "CSV import is enqueued" do
|
|
331
|
+
processor = DataProcessor.new
|
|
332
|
+
|
|
333
|
+
assert_enqueued_jobs 1, only: DataProcessor::ProcessCsvImportJob do
|
|
334
|
+
processor.process_csv_import_later("/tmp/data.csv", 123)
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
test "CSV data is imported" do
|
|
339
|
+
processor = DataProcessor.new
|
|
340
|
+
|
|
341
|
+
perform_enqueued_jobs do
|
|
342
|
+
processor.process_csv_import_later("/tmp/data.csv", 123)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# Assert data was imported
|
|
346
|
+
user = User.find(123)
|
|
347
|
+
assert user.records.count > 0
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
test "current attributes are preserved" do
|
|
351
|
+
Current.user = users(:admin)
|
|
352
|
+
|
|
353
|
+
perform_enqueued_jobs do
|
|
354
|
+
AuditLogger.new.log_action_later("test", 123)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
log = AuditLog.last
|
|
358
|
+
assert_equal users(:admin), log.user
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Best Practices
|
|
364
|
+
|
|
365
|
+
1. **Keep Jobs Idempotent**: Design your delayed methods to be safely retried
|
|
366
|
+
2. **Use Appropriate Queues**: Separate different types of work into different queues
|
|
367
|
+
3. **Handle Failures Gracefully**: Use ActiveJob's retry and error handling features
|
|
368
|
+
4. **Monitor Job Performance**: Use tools like Sidekiq's web UI or similar for your job backend
|
|
369
|
+
5. **Test Background Behavior**: Always test both the enqueuing and execution of your jobs
|
|
370
|
+
|
|
371
|
+
## Configuration Examples
|
|
372
|
+
|
|
373
|
+
### Multiple Options Combined
|
|
374
|
+
|
|
375
|
+
```ruby
|
|
376
|
+
class ComplexProcessor
|
|
377
|
+
include Delayable
|
|
378
|
+
|
|
379
|
+
def process_batch(batch_id, options = {})
|
|
380
|
+
# Complex processing logic
|
|
381
|
+
end
|
|
382
|
+
delay :process_batch,
|
|
383
|
+
queue: :batch_processing,
|
|
384
|
+
wait: 30.seconds,
|
|
385
|
+
limits_concurrency: { to: 3, key: ->(_run_data, batch_id) { "batch_#{batch_id}" } }
|
|
386
|
+
end
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Dynamic Delays
|
|
390
|
+
|
|
391
|
+
```ruby
|
|
392
|
+
class NotificationSender
|
|
393
|
+
include Delayable
|
|
394
|
+
|
|
395
|
+
def send_reminder(user_id, urgency = :normal)
|
|
396
|
+
# Send reminder logic
|
|
397
|
+
end
|
|
398
|
+
delay :send_reminder
|
|
399
|
+
|
|
400
|
+
def send_reminder_with_delay(user_id, urgency = :normal)
|
|
401
|
+
delay_time = case urgency
|
|
402
|
+
when :urgent then 0.seconds
|
|
403
|
+
when :normal then 1.hour
|
|
404
|
+
when :low then 1.day
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
send_reminder_later(user_id, urgency, wait: delay_time)
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Troubleshooting
|
|
413
|
+
|
|
414
|
+
### Debugging
|
|
415
|
+
|
|
416
|
+
To see what jobs are being created, you can inspect the generated job classes:
|
|
417
|
+
|
|
418
|
+
```ruby
|
|
419
|
+
# In rails console
|
|
420
|
+
DataProcessor::ProcessCsvImportJob.new.class.name
|
|
421
|
+
# => "DataProcessor::ProcessCsvImportJob"
|
|
422
|
+
|
|
423
|
+
DataProcessor::ProcessCsvImportJob.queue_name
|
|
424
|
+
# => "default"
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Requirements
|
|
428
|
+
|
|
429
|
+
- Ruby >= 3.4.0
|
|
430
|
+
- Rails >= 7.0.4.3
|
|
431
|
+
- ActiveJob configured with a backend (Sidekiq, Resque, etc.)
|
|
432
|
+
- **SolidQueue** (optional) - Required only if using `limits_concurrency` feature
|
|
433
|
+
|
|
24
434
|
## Contributing
|
|
25
|
-
|
|
435
|
+
|
|
436
|
+
1. Fork the repository
|
|
437
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
438
|
+
3. Add tests for your changes
|
|
439
|
+
4. Make sure all tests pass (`bundle exec rake test`)
|
|
440
|
+
5. Commit your changes (`git commit -am 'Add some feature'`)
|
|
441
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
|
442
|
+
7. Create a new Pull Request
|
|
26
443
|
|
|
27
444
|
## License
|
|
445
|
+
|
|
28
446
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
447
|
+
|
|
448
|
+
## Changelog
|
|
449
|
+
|
|
450
|
+
See [CHANGELOG.md](https://github.com/trobrock/delayable/CHANGELOG.md) for details about changes in each version.
|
data/lib/delayable/version.rb
CHANGED
data/lib/delayable.rb
CHANGED
|
@@ -12,10 +12,16 @@ module Delayable
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
class_methods do
|
|
15
|
-
def delay(method_name, class_method: false, wait: nil, limits_concurrency: nil, queue: :default)
|
|
15
|
+
def delay(method_name, class_method: false, wait: nil, limits_concurrency: nil, queue: :default, &job_configuration)
|
|
16
16
|
job = const_set(
|
|
17
17
|
delayable_job_name(method_name, class_method:),
|
|
18
|
-
delayable_job_class(
|
|
18
|
+
delayable_job_class(
|
|
19
|
+
method_name,
|
|
20
|
+
class_method:,
|
|
21
|
+
concurrency_limits: limits_concurrency,
|
|
22
|
+
queue:,
|
|
23
|
+
&job_configuration
|
|
24
|
+
)
|
|
19
25
|
)
|
|
20
26
|
|
|
21
27
|
defined_wait = wait
|
|
@@ -28,12 +34,19 @@ module Delayable
|
|
|
28
34
|
|
|
29
35
|
private
|
|
30
36
|
|
|
31
|
-
def delayable_job_class(
|
|
37
|
+
def delayable_job_class(
|
|
38
|
+
method_name,
|
|
39
|
+
class_method: false,
|
|
40
|
+
concurrency_limits: nil,
|
|
41
|
+
queue: :default,
|
|
42
|
+
&job_configuration
|
|
43
|
+
)
|
|
32
44
|
klass = self
|
|
33
45
|
Class.new(ApplicationJob) do
|
|
34
46
|
queue_as queue
|
|
35
47
|
|
|
36
|
-
limits_concurrency(**concurrency_limits) if concurrency_limits.is_a?(Hash)
|
|
48
|
+
limits_concurrency(**concurrency_limits) if concurrency_limits.is_a?(Hash) && respond_to?(:limits_concurrency)
|
|
49
|
+
class_eval(&job_configuration) if job_configuration
|
|
37
50
|
|
|
38
51
|
define_method(:perform) do |run_data = {}, *arguments, **kwargs|
|
|
39
52
|
Current.set(run_data[:current_attributes] || {}) do
|
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.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Trae Robrock
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-07-08 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|