resque-scheduler 4.5.0 → 4.6.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.
Potentially problematic release.
This version of resque-scheduler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/funding.yml +4 -0
- data/.github/workflows/codeql-analysis.yml +59 -0
- data/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/ruby.yml +26 -8
- data/AUTHORS.md +2 -0
- data/CHANGELOG.md +12 -3
- data/Gemfile +9 -3
- data/README.md +83 -10
- data/Rakefile +1 -0
- data/lib/resque/scheduler/configuration.rb +31 -8
- data/lib/resque/scheduler/delaying_extensions.rb +27 -12
- data/lib/resque/scheduler/env.rb +0 -4
- data/lib/resque/scheduler/locking.rb +1 -1
- data/lib/resque/scheduler/server/views/delayed.erb +4 -4
- data/lib/resque/scheduler/server/views/delayed_timestamp.erb +1 -1
- data/lib/resque/scheduler/server/views/scheduler.erb +2 -2
- data/lib/resque/scheduler/server/views/search.erb +0 -3
- data/lib/resque/scheduler/server/views/search_form.erb +0 -4
- data/lib/resque/scheduler/signal_handling.rb +2 -2
- data/lib/resque/scheduler/util.rb +1 -1
- data/lib/resque/scheduler/version.rb +1 -1
- data/lib/resque/scheduler.rb +1 -2
- data/resque-scheduler.gemspec +7 -5
- metadata +16 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf266ccd935c9464051349f32169248c7fab52aa84304a98f0d05e5e91ccec22
|
4
|
+
data.tar.gz: 517e84a33953fa3bf695ae26f23912d436fc86b7dc0ac9502fb09ca1cc02f1c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91b8916a16ad2a6a20860001f137fb558d6dbfa7aca3c67abb022acc298a3f2afac7c1527a043b2d5ed3fa582d0203cc988b101cc45819ae3832145328cdea7d
|
7
|
+
data.tar.gz: 90669eb2a75e71612b1505c87a6ed704e70b80b34aa89023ce84e8a256c1d3e0e4eb2a7931c8e480ff99524ed489bb97ed2d98f512f6646f19d50751613ac97c
|
data/.github/funding.yml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
name: "CodeQL"
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master, '*-stable' ]
|
6
|
+
pull_request:
|
7
|
+
# The branches below must be a subset of the branches above
|
8
|
+
branches: [ master ]
|
9
|
+
schedule:
|
10
|
+
- cron: '44 16 * * 6'
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
analyze:
|
14
|
+
name: Analyze
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
permissions:
|
17
|
+
actions: read
|
18
|
+
contents: read
|
19
|
+
security-events: write
|
20
|
+
|
21
|
+
strategy:
|
22
|
+
fail-fast: false
|
23
|
+
matrix:
|
24
|
+
language: [ 'ruby' ]
|
25
|
+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
26
|
+
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
27
|
+
|
28
|
+
steps:
|
29
|
+
- name: Checkout repository
|
30
|
+
uses: actions/checkout@v3
|
31
|
+
|
32
|
+
# Initializes the CodeQL tools for scanning.
|
33
|
+
- name: Initialize CodeQL
|
34
|
+
uses: github/codeql-action/init@v2
|
35
|
+
with:
|
36
|
+
languages: ${{ matrix.language }}
|
37
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
38
|
+
# By default, queries listed here will override any specified in a config file.
|
39
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
40
|
+
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
41
|
+
|
42
|
+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
43
|
+
# If this step fails, then you should remove it and run the build manually (see below)
|
44
|
+
- name: Autobuild
|
45
|
+
uses: github/codeql-action/autobuild@v2
|
46
|
+
|
47
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
48
|
+
# 📚 https://git.io/JvXDl
|
49
|
+
|
50
|
+
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
51
|
+
# and modify them (or add more) to build your code if your project
|
52
|
+
# uses a compiled language
|
53
|
+
|
54
|
+
#- run: |
|
55
|
+
# make bootstrap
|
56
|
+
# make release
|
57
|
+
|
58
|
+
- name: Perform CodeQL Analysis
|
59
|
+
uses: github/codeql-action/analyze@v2
|
data/.github/workflows/ruby.yml
CHANGED
@@ -8,6 +8,7 @@ on:
|
|
8
8
|
|
9
9
|
jobs:
|
10
10
|
test:
|
11
|
+
continue-on-error: true
|
11
12
|
runs-on: ubuntu-latest
|
12
13
|
services:
|
13
14
|
redis:
|
@@ -24,22 +25,39 @@ jobs:
|
|
24
25
|
- 2.6
|
25
26
|
- 2.7
|
26
27
|
- "3.0"
|
27
|
-
-
|
28
|
-
- jruby-9.1.17.0
|
29
|
-
- jruby-9.2.9.0
|
30
|
-
- jruby-9.2.19.0
|
28
|
+
- 3.1
|
31
29
|
resque-version:
|
32
30
|
- "master"
|
33
|
-
- "~> 2.
|
31
|
+
- "~> 2.2.0"
|
34
32
|
- "~> 1.27"
|
33
|
+
rufus-scheduler:
|
34
|
+
- "3.2"
|
35
|
+
- "3.4"
|
36
|
+
- "3.5"
|
37
|
+
- "3.6"
|
38
|
+
exclude:
|
39
|
+
- ruby-version: head
|
40
|
+
rufus-scheduler: 3.2
|
41
|
+
|
42
|
+
- ruby-version: 2.3
|
43
|
+
resque-version: 1.27
|
44
|
+
rufus-scheduler: 3.4
|
45
|
+
- ruby-version: 2.3
|
46
|
+
resque-version: 1.27
|
47
|
+
rufus-scheduler: 3.5
|
48
|
+
- ruby-version: 2.5
|
49
|
+
resque-version: 2.2.0
|
50
|
+
rufus-scheduler: 3.5
|
51
|
+
- ruby-version: 2.5
|
52
|
+
resque-version: master
|
53
|
+
rufus-scheduler: 3.2
|
35
54
|
env:
|
36
55
|
RESQUE: "${{ matrix.resque-version }}"
|
56
|
+
RUFUS_SCHEDULER: "${{ matrix.rufus-scheduler }}"
|
37
57
|
COVERAGE: 1
|
38
|
-
JRUBY_OPTS: ""
|
39
|
-
RUBYOPT: "-W0"
|
40
58
|
|
41
59
|
steps:
|
42
|
-
- uses: actions/checkout@
|
60
|
+
- uses: actions/checkout@v3
|
43
61
|
- uses: ruby/setup-ruby@v1
|
44
62
|
with:
|
45
63
|
ruby-version: "${{ matrix.ruby-version }}"
|
data/AUTHORS.md
CHANGED
@@ -10,6 +10,7 @@ Resque Scheduler authors
|
|
10
10
|
- Brian Landau
|
11
11
|
- Brian P O'Rourke
|
12
12
|
- Carlos Antonio da Silva
|
13
|
+
- Chris Bisnett
|
13
14
|
- Chris Kampmeier
|
14
15
|
- DJ Hartman
|
15
16
|
- Damon P. Cortesi
|
@@ -42,6 +43,7 @@ Resque Scheduler authors
|
|
42
43
|
- Justin Weiss
|
43
44
|
- Les Hill
|
44
45
|
- Luke Rodgers
|
46
|
+
- Maksymilian Chwałek
|
45
47
|
- Manuel Meurer
|
46
48
|
- Matt Aimonetti
|
47
49
|
- Matt Simpson
|
data/CHANGELOG.md
CHANGED
@@ -2,9 +2,17 @@
|
|
2
2
|
|
3
3
|
**ATTN**: This project uses [semantic versioning](http://semver.org/).
|
4
4
|
|
5
|
-
##
|
5
|
+
## [4.6.0] - 2022-08-04
|
6
|
+
### Changed
|
7
|
+
- Remove support for Ruby < 2.3
|
8
|
+
- Configuration to use a set of truthy values to enable boolean settings instead of simply existence
|
9
|
+
- Add `delay_or_enqueue_at` for delaying existing jobs or creating a new job(#645)
|
10
|
+
- Fix deprecated uses of Redis#pipelined
|
11
|
+
- Fix reading configuration from environment for boolean values (#735)
|
12
|
+
- Unblock rufus-scheduler lock on lower than 3.7 by fixing scheduler shutdown (#736)
|
13
|
+
- Removed testing against jruby (resque doesn't test against jruby)
|
6
14
|
|
7
|
-
## [4.5.0]
|
15
|
+
## [4.5.0] - 2021-09-25
|
8
16
|
### Added
|
9
17
|
- Support Ruby 3
|
10
18
|
- Add optional argument to `remove_schedule` to control reloading of the schedule
|
@@ -443,7 +451,8 @@
|
|
443
451
|
### Added
|
444
452
|
- Initial release
|
445
453
|
|
446
|
-
[Unreleased]: https://github.com/resque/resque-scheduler/compare/v4.
|
454
|
+
[Unreleased]: https://github.com/resque/resque-scheduler/compare/v4.5.0...HEAD
|
455
|
+
[4.5.0]: https://github.com/resque/resque-scheduler/compare/v4.4.0...v4.5.0
|
447
456
|
[4.4.0]: https://github.com/resque/resque-scheduler/compare/v4.3.1...v4.4.0
|
448
457
|
[4.3.1]: https://github.com/resque/resque-scheduler/compare/v4.3.0...v4.3.1
|
449
458
|
[4.3.0]: https://github.com/resque/resque-scheduler/compare/v4.2.1...v4.3.0
|
data/Gemfile
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
# vim:fileencoding=utf-8
|
2
2
|
source 'https://rubygems.org'
|
3
3
|
|
4
|
-
case
|
5
|
-
when nil
|
4
|
+
case resque_version = ENV.fetch('RESQUE', 'master')
|
6
5
|
when 'master'
|
7
6
|
gem 'resque', git: 'https://github.com/resque/resque'
|
8
7
|
else
|
9
|
-
gem 'resque',
|
8
|
+
gem 'resque', resque_version
|
9
|
+
end
|
10
|
+
|
11
|
+
case rufus_scheduler_version = ENV.fetch('RUFUS_SCHEDULER', '3.6')
|
12
|
+
when 'master'
|
13
|
+
gem 'rufus-scheduler', git: 'https://github.com/jmettraux/rufus-scheduler'
|
14
|
+
else
|
15
|
+
gem 'rufus-scheduler', rufus_scheduler_version
|
10
16
|
end
|
11
17
|
|
12
18
|
gemspec
|
data/README.md
CHANGED
@@ -211,7 +211,7 @@ since the jobs are stored in a redis sorted set (zset). I can't imagine this
|
|
211
211
|
being an issue for someone since redis is stupidly fast even at log(n), but full
|
212
212
|
disclosure is always best.
|
213
213
|
|
214
|
-
#### Removing Delayed
|
214
|
+
#### Removing Delayed Jobs
|
215
215
|
|
216
216
|
If you have the need to cancel a delayed job, you can do like so:
|
217
217
|
|
@@ -255,6 +255,49 @@ Resque.enqueue_delayed_selection { |args| args[0]['account_id'] == current_accou
|
|
255
255
|
Resque.enqueue_delayed_selection { |args| args[0]['user_id'] == current_user.id }
|
256
256
|
```
|
257
257
|
|
258
|
+
#### Updating Delayed Jobs
|
259
|
+
|
260
|
+
Previously delayed jobs may be delayed even further into the future like so:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
# after you've enqueued a job like:
|
264
|
+
Resque.enqueue_at(1.minute.from_now, SendNotifications, :user_id => current_user.id)
|
265
|
+
# delay running the job until two minutes from now
|
266
|
+
Resque.delay_or_enqueue_at(2.minutes.from_now, SendNotifications, :user_id => current_user.id)
|
267
|
+
```
|
268
|
+
|
269
|
+
You don't need to worry if a matching job has already been queued, because if no matching jobs are found a new job is created and enqueued as if you had called `enqueue_at`. This means you don't need any special conditionals to know if a job has already been queued. You simply create the job like so:
|
270
|
+
|
271
|
+
```ruby
|
272
|
+
Resque.delay_or_enqueue_at(1.minute.from_now, SendNotifications, :user_id => current_user.id)
|
273
|
+
```
|
274
|
+
|
275
|
+
If multiple matching jobs are found, all of the matching jobs will be updated to have the same timestamp even if their original timestamps were not the same.
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
# enqueue multiple jobs with different delay timestamps
|
279
|
+
Resque.enqueue_at(1.minute.from_now, SendNotifications, :user_id => current_user.id)
|
280
|
+
Resque.enqueue_at(2.minutes.from_now, SendNotifications, :user_id => current_user.id)
|
281
|
+
|
282
|
+
# delay running the two jobs until 5 minutes from now
|
283
|
+
Resque.delay_or_enqueue_at(5.minutes.from_now, SendNotifications, :user_id => current_user.id)
|
284
|
+
```
|
285
|
+
|
286
|
+
The most useful case for increasing the delay of an already delayed job is to batch together work based on multiple events. For example, if you wanted to send a notification email to a user when an event triggers but didn't want to send 10 emails if many events happened within a short period, you could use this technique to delay the noficication email until no events have triggered for a period of time. This way you could send 1 email containing the 10 notifications once no events have triggered for 2 minutes. You could implement this like so:
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
# Send a notification when an event is created.
|
290
|
+
# app/models/event.rb
|
291
|
+
after_commit on: :create do
|
292
|
+
Resque.delay_or_enqueue_in(2.minutes, SendNotifications, :user_id => user.id)
|
293
|
+
end
|
294
|
+
```
|
295
|
+
|
296
|
+
When the first event is created a job will be scheduled to send unsent notifications to the associated user. If another event is created within the 2 minute window, the timer will be reset to 2 minutes. This will continue as long as new events are created for the specific user before the 2 minute timer expires. Once the timer expires and the job is scheduled any new events that are created will schedule a new job and start the process over. By adjusting the window you can tweak the trade-off between sending notification emails quickly after an event happens and sending fewer emails.
|
297
|
+
|
298
|
+
Read more in the [original PR](https://github.com/resque/resque-scheduler/pull/645)
|
299
|
+
|
300
|
+
|
258
301
|
### Scheduled Jobs (Recurring Jobs)
|
259
302
|
|
260
303
|
Scheduled (or recurring) jobs are logically no different than a standard cron
|
@@ -304,7 +347,6 @@ If you would like to setup a job that is executed manually you can configure lik
|
|
304
347
|
|
305
348
|
```yaml
|
306
349
|
ImportOrdersManual:
|
307
|
-
description: 'Import Amazon Orders Manual'
|
308
350
|
custom_job_class: 'AmazonMws::ImportOrdersJob'
|
309
351
|
never: "* * * * *"
|
310
352
|
queue: high
|
@@ -344,6 +386,38 @@ seconds past the minute).
|
|
344
386
|
A big shout out to [rufus-scheduler](http://github.com/jmettraux/rufus-scheduler)
|
345
387
|
for handling the heavy lifting of the actual scheduling engine.
|
346
388
|
|
389
|
+
##### Queue with parameters
|
390
|
+
|
391
|
+
It's possible to specify parameters, that must be given by the user when they manually queue the job. To enable this feature add `parameters` key to scheduled job definition.
|
392
|
+
|
393
|
+
```yaml
|
394
|
+
queue_documents_for_indexing:
|
395
|
+
cron: "0 0 * * *"
|
396
|
+
class: "QueueDocuments"
|
397
|
+
queue: high
|
398
|
+
args:
|
399
|
+
foo: "bar"
|
400
|
+
a: "b"
|
401
|
+
parameters:
|
402
|
+
foo:
|
403
|
+
description: "value of foo"
|
404
|
+
default: "baz"
|
405
|
+
|
406
|
+
description: "This job queues all content for indexing in solr"
|
407
|
+
```
|
408
|
+
|
409
|
+
One can use following options for each parameter:
|
410
|
+
* description - tooltip to be shown next to the parameter input
|
411
|
+
* default - prefilled value in the parameter input
|
412
|
+
|
413
|
+
**NOTE**: When sheduling the job, parameters are merged into job args. Assuming the example above and default parametr value, the job will be run with the following args:
|
414
|
+
|
415
|
+
```ruby
|
416
|
+
{"foo"=>"baz", "a"=>"b"}
|
417
|
+
```
|
418
|
+
|
419
|
+
**NOTE**: If user leaves the parameter value empty, it'll be sent as empty string.
|
420
|
+
|
347
421
|
#### Dynamic schedules
|
348
422
|
|
349
423
|
Dynamic schedules are programmatically set on a running `resque-scheduler`.
|
@@ -405,18 +479,17 @@ Resque.set_schedule(name, config)
|
|
405
479
|
|
406
480
|
#### Time zones
|
407
481
|
|
408
|
-
|
409
|
-
rather than the `config.time_zone` specified in Rails.
|
410
|
-
|
482
|
+
If you use the cron syntax, by default it is interpreted in the server time zone.
|
411
483
|
You can explicitly specify the time zone that rufus-scheduler will use:
|
412
|
-
|
413
484
|
```yaml
|
414
485
|
cron: "30 6 * * 1 Europe/Stockholm"
|
415
486
|
```
|
416
487
|
|
417
|
-
|
418
|
-
|
419
|
-
|
488
|
+
##### Rails
|
489
|
+
In Rails, `config.time_zone` will be used to determine the time zone for `resque-scheduler`.
|
490
|
+
|
491
|
+
Note that `config.time_zone` allows for a shorthand (e.g. "Stockholm")
|
492
|
+
that rufus-scheduler does not accept, so make sure it's the right format, e.g. with:
|
420
493
|
|
421
494
|
```ruby
|
422
495
|
ActiveSupport::TimeZone.find_tzinfo(Rails.configuration.time_zone).name
|
@@ -573,7 +646,7 @@ Now make sure you're passing that file to resque-web like so:
|
|
573
646
|
|
574
647
|
### Running in the background
|
575
648
|
|
576
|
-
|
649
|
+
There are scenarios where it's helpful for
|
577
650
|
the resque worker to run itself in the background (usually in combination with
|
578
651
|
PIDFILE). Use the BACKGROUND option so that rake will return as soon as the
|
579
652
|
worker is started.
|
data/Rakefile
CHANGED
@@ -8,13 +8,18 @@ module Resque
|
|
8
8
|
yield self
|
9
9
|
end
|
10
10
|
|
11
|
+
attr_writer :environment
|
12
|
+
def environment
|
13
|
+
@environment ||= ENV
|
14
|
+
end
|
15
|
+
|
11
16
|
# Used in `#load_schedule_job`
|
12
17
|
attr_writer :env
|
13
18
|
|
14
19
|
def env
|
15
20
|
return @env if @env
|
16
21
|
@env ||= Rails.env if defined?(Rails) && Rails.respond_to?(:env)
|
17
|
-
@env ||=
|
22
|
+
@env ||= environment['RAILS_ENV']
|
18
23
|
@env
|
19
24
|
end
|
20
25
|
|
@@ -22,42 +27,42 @@ module Resque
|
|
22
27
|
attr_writer :verbose
|
23
28
|
|
24
29
|
def verbose
|
25
|
-
@verbose ||=
|
30
|
+
@verbose ||= to_bool(environment['VERBOSE'])
|
26
31
|
end
|
27
32
|
|
28
33
|
# If set, produces no output
|
29
34
|
attr_writer :quiet
|
30
35
|
|
31
36
|
def quiet
|
32
|
-
@quiet ||=
|
37
|
+
@quiet ||= to_bool(environment['QUIET'])
|
33
38
|
end
|
34
39
|
|
35
40
|
# If set, will write messages to the file
|
36
41
|
attr_writer :logfile
|
37
42
|
|
38
43
|
def logfile
|
39
|
-
@logfile ||=
|
44
|
+
@logfile ||= environment['LOGFILE']
|
40
45
|
end
|
41
46
|
|
42
47
|
# Sets whether to log in 'text' or 'json'
|
43
48
|
attr_writer :logformat
|
44
49
|
|
45
50
|
def logformat
|
46
|
-
@logformat ||=
|
51
|
+
@logformat ||= environment['LOGFORMAT']
|
47
52
|
end
|
48
53
|
|
49
54
|
# If set, will try to update the schedule in the loop
|
50
55
|
attr_writer :dynamic
|
51
56
|
|
52
57
|
def dynamic
|
53
|
-
@dynamic ||=
|
58
|
+
@dynamic ||= to_bool(environment['DYNAMIC_SCHEDULE'])
|
54
59
|
end
|
55
60
|
|
56
61
|
# If set, will append the app name to procline
|
57
62
|
attr_writer :app_name
|
58
63
|
|
59
64
|
def app_name
|
60
|
-
@app_name ||=
|
65
|
+
@app_name ||= environment['APP_NAME']
|
61
66
|
end
|
62
67
|
|
63
68
|
# Amount of time in seconds to sleep between polls of the delayed
|
@@ -66,7 +71,25 @@ module Resque
|
|
66
71
|
|
67
72
|
def poll_sleep_amount
|
68
73
|
@poll_sleep_amount ||=
|
69
|
-
Float(
|
74
|
+
Float(environment.fetch('RESQUE_SCHEDULER_INTERVAL', '5'))
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# Copied from https://github.com/rails/rails/blob/main/activemodel/lib/active_model/type/boolean.rb#L17
|
80
|
+
TRUE_VALUES = [
|
81
|
+
true, 1,
|
82
|
+
'1', :'1',
|
83
|
+
't', :t,
|
84
|
+
'T', :T,
|
85
|
+
'true', :true,
|
86
|
+
'TRUE', :TRUE,
|
87
|
+
'on', :on,
|
88
|
+
'ON', :ON
|
89
|
+
].to_set.freeze
|
90
|
+
|
91
|
+
def to_bool(value)
|
92
|
+
TRUE_VALUES.include?(value)
|
70
93
|
end
|
71
94
|
end
|
72
95
|
end
|
@@ -63,6 +63,24 @@ module Resque
|
|
63
63
|
klass, *args)
|
64
64
|
end
|
65
65
|
|
66
|
+
# Update the delayed timestamp of any matching delayed jobs or enqueue a
|
67
|
+
# new job if no matching jobs are found. Returns the number of delayed or
|
68
|
+
# enqueued jobs.
|
69
|
+
def delay_or_enqueue_at(timestamp, klass, *args)
|
70
|
+
count = remove_delayed(klass, *args)
|
71
|
+
count = 1 if count == 0
|
72
|
+
|
73
|
+
count.times do
|
74
|
+
enqueue_at(timestamp, klass, *args)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Identical to +delay_or_enqueue_at+, except it takes
|
79
|
+
# number_of_seconds_from_now instead of a timestamp
|
80
|
+
def delay_or_enqueue_in(number_of_seconds_from_now, klass, *args)
|
81
|
+
delay_or_enqueue_at(Time.now + number_of_seconds_from_now, klass, *args)
|
82
|
+
end
|
83
|
+
|
66
84
|
# Used internally to stuff the item into the schedule sorted list.
|
67
85
|
# +timestamp+ can be either in seconds or a datetime object. The
|
68
86
|
# insertion time complexity is O(log(n)). Returns true if it's
|
@@ -135,10 +153,7 @@ module Resque
|
|
135
153
|
Array(redis.zrange(:delayed_queue_schedule, 0, -1)).each do |item|
|
136
154
|
key = "delayed:#{item}"
|
137
155
|
items = redis.lrange(key, 0, -1)
|
138
|
-
redis.
|
139
|
-
items.each { |ts_item| redis.del("timestamps:#{ts_item}") }
|
140
|
-
end
|
141
|
-
redis.del key
|
156
|
+
redis.del(key, items.map { |ts_item| "timestamps:#{ts_item}" })
|
142
157
|
end
|
143
158
|
|
144
159
|
redis.del :delayed_queue_schedule
|
@@ -217,9 +232,9 @@ module Resque
|
|
217
232
|
|
218
233
|
# Beyond 100 there's almost no improvement in speed
|
219
234
|
found = timestamps.each_slice(100).map do |ts_group|
|
220
|
-
jobs = redis.pipelined do |
|
235
|
+
jobs = redis.pipelined do |pipeline|
|
221
236
|
ts_group.each do |ts|
|
222
|
-
|
237
|
+
pipeline.lrange("delayed:#{ts}", 0, -1)
|
223
238
|
end
|
224
239
|
end
|
225
240
|
|
@@ -299,10 +314,10 @@ module Resque
|
|
299
314
|
|
300
315
|
timestamps = redis.smembers("timestamps:#{encoded_job}")
|
301
316
|
|
302
|
-
replies = redis.pipelined do
|
317
|
+
replies = redis.pipelined do |pipeline|
|
303
318
|
timestamps.each do |key|
|
304
|
-
|
305
|
-
|
319
|
+
pipeline.lrem(key, 0, encoded_job)
|
320
|
+
pipeline.srem("timestamps:#{encoded_job}", key)
|
306
321
|
end
|
307
322
|
end
|
308
323
|
|
@@ -319,9 +334,9 @@ module Resque
|
|
319
334
|
redis.watch(key) do
|
320
335
|
if redis.llen(key).to_i == 0
|
321
336
|
# If the list is empty, remove it.
|
322
|
-
redis.multi do
|
323
|
-
|
324
|
-
|
337
|
+
redis.multi do |transaction|
|
338
|
+
transaction.del(key)
|
339
|
+
transaction.zrem(:delayed_queue_schedule, timestamp.to_i)
|
325
340
|
end
|
326
341
|
else
|
327
342
|
redis.redis.unwatch
|
data/lib/resque/scheduler/env.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# ### Locking the scheduler process
|
4
4
|
#
|
5
|
-
# There are two places in resque-scheduler that need to be
|
5
|
+
# There are two places in resque-scheduler that need to be synchronized in order
|
6
6
|
# to be able to run redundant scheduler processes while ensuring jobs don't get
|
7
7
|
# queued multiple times when the master process changes.
|
8
8
|
#
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<h1>Delayed Jobs</h1>
|
2
|
-
|
2
|
+
<% size = resque.delayed_queue_schedule_size %>
|
3
3
|
|
4
4
|
<%= scheduler_view :search_form, layout: false %>
|
5
5
|
|
6
|
-
<p style="
|
6
|
+
<p style="color: red; font-weight: bold;">
|
7
7
|
<%= @error_message %>
|
8
8
|
</p>
|
9
9
|
|
@@ -46,7 +46,7 @@
|
|
46
46
|
<td><%= h(show_job_arguments(job['args'])) if job && delayed_timestamp_size == 1 %></td>
|
47
47
|
<td>
|
48
48
|
<% if job %>
|
49
|
-
<a href="<%=u URI("/delayed/jobs/#{CGI.escape(job['class'])}?args=" + CGI.escape(job['args'].to_json)) %>">All schedules</a>
|
49
|
+
<a href="<%= u URI("/delayed/jobs/#{CGI.escape(job['class'])}?args=" + CGI.escape(job['args'].to_json)) %>">All schedules</a>
|
50
50
|
<% end %>
|
51
51
|
</td>
|
52
52
|
</tr>
|
@@ -55,7 +55,7 @@
|
|
55
55
|
|
56
56
|
<% if size > 0 %>
|
57
57
|
<br>
|
58
|
-
<form method="POST" action="<%=u 'delayed/clear'%>" class='clear-delayed'>
|
58
|
+
<form method="POST" action="<%= u 'delayed/clear' %>" class='clear-delayed'>
|
59
59
|
<input type='submit' name='' value='Clear Delayed Jobs' />
|
60
60
|
</form>
|
61
61
|
<% end %>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<br/> Current master: <%= Resque.redis.get(Resque::Scheduler.master_lock.key) %>
|
9
9
|
</p>
|
10
10
|
<p class='intro'>
|
11
|
-
|
11
|
+
The highlighted jobs are skipped for current environment.
|
12
12
|
</p>
|
13
13
|
<div style="overflow-y: auto; width:100%; padding: 0px 5px;">
|
14
14
|
<table>
|
@@ -29,7 +29,7 @@
|
|
29
29
|
<% Resque.schedule.keys.sort.each_with_index do |name, index| %>
|
30
30
|
<% config = Resque.schedule[name] %>
|
31
31
|
<tr style="<%= scheduled_in_this_env?(name) ? '' : 'color: #9F6000;background: #FEEFB3;' %>">
|
32
|
-
|
32
|
+
<td style="padding-left: 15px;"><%= index + 1 %>.</td>
|
33
33
|
<% if Resque::Scheduler.dynamic %>
|
34
34
|
<td style="padding-top: 12px; padding-bottom: 2px; width: 10px">
|
35
35
|
<form action="<%= u "/schedule" %>" method="post" style="margin-left: 0">
|
@@ -10,13 +10,13 @@ module Resque
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# For all signals, set the shutdown flag and wait for current
|
13
|
-
# poll/
|
13
|
+
# poll/enqueuing to finish (should be almost instant). In the
|
14
14
|
# case of sleeping, exit immediately.
|
15
15
|
def register_signal_handlers
|
16
16
|
(Signal.list.keys & %w(INT TERM USR1 USR2 QUIT)).each do |sig|
|
17
17
|
trap(sig) do
|
18
18
|
signal_queue << sig
|
19
|
-
# break sleep in the primary scheduler thread,
|
19
|
+
# break sleep in the primary scheduler thread, allowing
|
20
20
|
# the signal queue to get processed as soon as possible.
|
21
21
|
@th.wakeup if @th && @th.alive?
|
22
22
|
end
|
@@ -4,7 +4,7 @@ module Resque
|
|
4
4
|
module Scheduler
|
5
5
|
class Util
|
6
6
|
# In order to upgrade to resque(1.25) which has deprecated following
|
7
|
-
# methods, we just added these
|
7
|
+
# methods, we just added these useful helpers back to use in Resque
|
8
8
|
# Scheduler. refer to:
|
9
9
|
# https://github.com/resque/resque-scheduler/pull/273
|
10
10
|
|
data/lib/resque/scheduler.rb
CHANGED
@@ -251,7 +251,7 @@ module Resque
|
|
251
251
|
if job_klass && job_klass != 'Resque::Job'
|
252
252
|
# The custom job class API must offer a static "scheduled" method. If
|
253
253
|
# the custom job class can not be constantized (via a requeue call
|
254
|
-
# from the web perhaps), fall back to
|
254
|
+
# from the web perhaps), fall back to enqueuing normally via
|
255
255
|
# Resque::Job.create.
|
256
256
|
begin
|
257
257
|
Resque::Scheduler::Util.constantize(job_klass).scheduled(
|
@@ -377,7 +377,6 @@ module Resque
|
|
377
377
|
|
378
378
|
def stop_rufus_scheduler
|
379
379
|
rufus_scheduler.shutdown(:wait)
|
380
|
-
rufus_scheduler.join
|
381
380
|
end
|
382
381
|
|
383
382
|
def before_shutdown
|
data/resque-scheduler.gemspec
CHANGED
@@ -26,13 +26,16 @@ Gem::Specification.new do |spec|
|
|
26
26
|
Adds methods enqueue_at/enqueue_in to schedule jobs in the future.
|
27
27
|
Also supports queueing jobs on a fixed, cron-like schedule.
|
28
28
|
DESCRIPTION
|
29
|
-
spec.homepage = '
|
29
|
+
spec.homepage = 'https://github.com/resque/resque-scheduler'
|
30
30
|
spec.license = 'MIT'
|
31
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
32
|
+
|
33
|
+
spec.required_ruby_version = '>= 2.3.0'
|
31
34
|
|
32
35
|
spec.files = `git ls-files -z`.split("\0").reject do |f|
|
33
36
|
f.match(%r{^(test|spec|features|examples|bin|tasks)/}) ||
|
34
37
|
f.match(/^(Vagrantfile|Gemfile\.lock)/) ||
|
35
|
-
f.match(/^\.(rubocop|simplecov|
|
38
|
+
f.match(/^\.(rubocop|simplecov|vagrant|gitignore)/)
|
36
39
|
end
|
37
40
|
spec.bindir = 'exe'
|
38
41
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
@@ -40,7 +43,6 @@ Gem::Specification.new do |spec|
|
|
40
43
|
|
41
44
|
spec.add_development_dependency 'bundler'
|
42
45
|
spec.add_development_dependency 'json'
|
43
|
-
spec.add_development_dependency 'kramdown'
|
44
46
|
spec.add_development_dependency 'minitest'
|
45
47
|
spec.add_development_dependency 'mocha'
|
46
48
|
spec.add_development_dependency 'pry'
|
@@ -49,7 +51,6 @@ Gem::Specification.new do |spec|
|
|
49
51
|
spec.add_development_dependency 'simplecov'
|
50
52
|
spec.add_development_dependency 'test-unit'
|
51
53
|
spec.add_development_dependency 'yard'
|
52
|
-
spec.add_development_dependency 'tzinfo-data'
|
53
54
|
spec.add_development_dependency 'timecop'
|
54
55
|
|
55
56
|
# We pin rubocop because new cops have a tendency to result in false-y
|
@@ -60,5 +61,6 @@ Gem::Specification.new do |spec|
|
|
60
61
|
spec.add_runtime_dependency 'redis', '>= 3.3'
|
61
62
|
spec.add_runtime_dependency 'resque', '>= 1.27'
|
62
63
|
# rufus-scheduler v3.7 causes a failure in test/multi_process_test.rb
|
63
|
-
|
64
|
+
# rufus-scheduler v3.3 is missing a to_local method which fails tests
|
65
|
+
spec.add_runtime_dependency 'rufus-scheduler', '~> 3.2', '!= 3.3'
|
64
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben VandenBos
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
- Ryan Biesemeyer
|
10
10
|
- Dan Buch
|
11
11
|
- Michael Bianco
|
12
|
-
autorequire:
|
12
|
+
autorequire:
|
13
13
|
bindir: exe
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2022-08-20 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: bundler
|
@@ -42,20 +42,6 @@ dependencies:
|
|
42
42
|
- - ">="
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '0'
|
45
|
-
- !ruby/object:Gem::Dependency
|
46
|
-
name: kramdown
|
47
|
-
requirement: !ruby/object:Gem::Requirement
|
48
|
-
requirements:
|
49
|
-
- - ">="
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
version: '0'
|
52
|
-
type: :development
|
53
|
-
prerelease: false
|
54
|
-
version_requirements: !ruby/object:Gem::Requirement
|
55
|
-
requirements:
|
56
|
-
- - ">="
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
version: '0'
|
59
45
|
- !ruby/object:Gem::Dependency
|
60
46
|
name: minitest
|
61
47
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,20 +154,6 @@ dependencies:
|
|
168
154
|
- - ">="
|
169
155
|
- !ruby/object:Gem::Version
|
170
156
|
version: '0'
|
171
|
-
- !ruby/object:Gem::Dependency
|
172
|
-
name: tzinfo-data
|
173
|
-
requirement: !ruby/object:Gem::Requirement
|
174
|
-
requirements:
|
175
|
-
- - ">="
|
176
|
-
- !ruby/object:Gem::Version
|
177
|
-
version: '0'
|
178
|
-
type: :development
|
179
|
-
prerelease: false
|
180
|
-
version_requirements: !ruby/object:Gem::Requirement
|
181
|
-
requirements:
|
182
|
-
- - ">="
|
183
|
-
- !ruby/object:Gem::Version
|
184
|
-
version: '0'
|
185
157
|
- !ruby/object:Gem::Dependency
|
186
158
|
name: timecop
|
187
159
|
requirement: !ruby/object:Gem::Requirement
|
@@ -259,9 +231,9 @@ dependencies:
|
|
259
231
|
- - "~>"
|
260
232
|
- !ruby/object:Gem::Version
|
261
233
|
version: '3.2'
|
262
|
-
- - "
|
234
|
+
- - "!="
|
263
235
|
- !ruby/object:Gem::Version
|
264
|
-
version: '3.
|
236
|
+
version: '3.3'
|
265
237
|
type: :runtime
|
266
238
|
prerelease: false
|
267
239
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -269,9 +241,9 @@ dependencies:
|
|
269
241
|
- - "~>"
|
270
242
|
- !ruby/object:Gem::Version
|
271
243
|
version: '3.2'
|
272
|
-
- - "
|
244
|
+
- - "!="
|
273
245
|
- !ruby/object:Gem::Version
|
274
|
-
version: '3.
|
246
|
+
version: '3.3'
|
275
247
|
description: |2
|
276
248
|
Light weight job scheduling on top of Resque.
|
277
249
|
Adds methods enqueue_at/enqueue_in to schedule jobs in the future.
|
@@ -288,6 +260,8 @@ extensions: []
|
|
288
260
|
extra_rdoc_files: []
|
289
261
|
files:
|
290
262
|
- ".github/dependabot.yml"
|
263
|
+
- ".github/funding.yml"
|
264
|
+
- ".github/workflows/codeql-analysis.yml"
|
291
265
|
- ".github/workflows/rubocop.yml"
|
292
266
|
- ".github/workflows/ruby.yml"
|
293
267
|
- AUTHORS.md
|
@@ -328,11 +302,12 @@ files:
|
|
328
302
|
- lib/resque/scheduler/util.rb
|
329
303
|
- lib/resque/scheduler/version.rb
|
330
304
|
- resque-scheduler.gemspec
|
331
|
-
homepage:
|
305
|
+
homepage: https://github.com/resque/resque-scheduler
|
332
306
|
licenses:
|
333
307
|
- MIT
|
334
|
-
metadata:
|
335
|
-
|
308
|
+
metadata:
|
309
|
+
rubygems_mfa_required: 'true'
|
310
|
+
post_install_message:
|
336
311
|
rdoc_options: []
|
337
312
|
require_paths:
|
338
313
|
- lib
|
@@ -340,15 +315,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
340
315
|
requirements:
|
341
316
|
- - ">="
|
342
317
|
- !ruby/object:Gem::Version
|
343
|
-
version:
|
318
|
+
version: 2.3.0
|
344
319
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
345
320
|
requirements:
|
346
321
|
- - ">="
|
347
322
|
- !ruby/object:Gem::Version
|
348
323
|
version: '0'
|
349
324
|
requirements: []
|
350
|
-
rubygems_version: 3.
|
351
|
-
signing_key:
|
325
|
+
rubygems_version: 3.3.5
|
326
|
+
signing_key:
|
352
327
|
specification_version: 4
|
353
328
|
summary: Light weight job scheduling on top of Resque
|
354
329
|
test_files: []
|