que-scheduler 5.1.1 → 6.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/README.md +3 -5
- data/lib/que/scheduler/audit.rb +2 -2
- data/lib/que/scheduler/configuration.rb +5 -3
- data/lib/que/scheduler/db.rb +2 -2
- data/lib/que/scheduler/db_support.rb +41 -0
- data/lib/que/scheduler/defined_job.rb +1 -1
- data/lib/que/scheduler/jobs/que_scheduler_audit_clear_down_job.rb +3 -3
- data/lib/que/scheduler/migrations.rb +25 -12
- data/lib/que/scheduler/scheduler_job.rb +12 -7
- data/lib/que/scheduler/state_checks.rb +3 -2
- data/lib/que/scheduler/to_enqueue.rb +3 -3
- data/lib/que/scheduler/version.rb +1 -1
- data/lib/que/scheduler.rb +1 -1
- metadata +55 -13
- data/lib/que/scheduler/version_support.rb +0 -109
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e3f6c1fe44aef0d369e7d6dc56a55ed53669e8946cf21204ca763224ecb83fc
|
4
|
+
data.tar.gz: 5595afbfb978657ab535b8b80cebbec532c2cff72abfa235718778a883d65ef3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4fcfc3d2835cbf22f9f6b8f9f98f5d2efa9d721687161fd5cffc482601eca4622051999d9fb280427fd8f1fa6a979273ff15448e5c78024b76bb1771c98327c
|
7
|
+
data.tar.gz: 2b122ec009cbb79325bd791fec250010f4e5f0d5daac9d50b327403267d36d9041d6a0eadb70ebae120b8bea48373a80b02969f0bbe0d852dcf607ab93a3020c
|
data/README.md
CHANGED
@@ -23,13 +23,14 @@ needs to be run, enqueueing those jobs, then enqueueing itself to check again la
|
|
23
23
|
que-scheduler will look for it is `config/que_schedule.yml`. The format is essentially the same as
|
24
24
|
resque-scheduler files, but with additional features.
|
25
25
|
|
26
|
-
1. Add a migration to
|
26
|
+
1. Add a migration to prepare the audit table and start the job scheduler. Note that this migration
|
27
27
|
will fail if Que is set to execute jobs synchronously, i.e. `Que::Job.run_synchronously = true`.
|
28
28
|
|
29
29
|
```ruby
|
30
30
|
class CreateQueSchedulerSchema < ActiveRecord::Migration[6.0]
|
31
31
|
def change
|
32
32
|
Que::Scheduler::Migrations.migrate!(version: 8)
|
33
|
+
Que::Scheduler::Migrations.reenqueue_scheduler_if_missing
|
33
34
|
end
|
34
35
|
end
|
35
36
|
```
|
@@ -215,6 +216,7 @@ performed.
|
|
215
216
|
class CreateQueSchedulerSchema < ActiveRecord::Migration[6.0]
|
216
217
|
def change
|
217
218
|
Que::Scheduler::Migrations.migrate!(version: 8)
|
219
|
+
Que::Scheduler::Migrations.reenqueue_scheduler_if_missing
|
218
220
|
end
|
219
221
|
end
|
220
222
|
```
|
@@ -319,10 +321,6 @@ The latest version of que-scheduler supports Ruby 3.0 and above.
|
|
319
321
|
que-scheduler versions below 4.4.0 work with Ruby 2.7.
|
320
322
|
que-scheduler versions below 4.2.3 work with Ruby 2.5 and Ruby 2.6.
|
321
323
|
|
322
|
-
Using que 0.x with Rails 6 needs a patch to support it.
|
323
|
-
See the patch and how to use it here: https://github.com/que-rb/que/issues/247#issuecomment-595258236
|
324
|
-
If that patch is included then que-scheduler will work. This setup is tested, but is not supported.
|
325
|
-
|
326
324
|
## Inspiration
|
327
325
|
|
328
326
|
This gem was inspired by the makers of the excellent [Que](https://github.com/chanks/que) job scheduler gem.
|
data/lib/que/scheduler/audit.rb
CHANGED
@@ -24,9 +24,9 @@ module Que
|
|
24
24
|
|
25
25
|
class << self
|
26
26
|
def append(scheduler_job_id, executed_at, enqueued_jobs)
|
27
|
-
::Que::Scheduler::
|
27
|
+
::Que::Scheduler::DbSupport.execute(INSERT_AUDIT, [scheduler_job_id, executed_at])
|
28
28
|
enqueued_jobs.each do |j|
|
29
|
-
inserted = ::Que::Scheduler::
|
29
|
+
inserted = ::Que::Scheduler::DbSupport.execute(
|
30
30
|
INSERT_AUDIT_ENQUEUED,
|
31
31
|
[scheduler_job_id] +
|
32
32
|
j.values_at(:job_class, :queue, :priority, :args, :job_id, :run_at)
|
@@ -1,15 +1,17 @@
|
|
1
1
|
require "que"
|
2
|
-
require_relative "
|
2
|
+
require_relative "db_support"
|
3
3
|
|
4
4
|
module Que
|
5
5
|
module Scheduler
|
6
|
+
# :reek:Attribute
|
6
7
|
class Configuration
|
7
8
|
attr_accessor :schedule_location, :schedule, :transaction_adapter, :que_scheduler_queue,
|
8
9
|
:time_zone
|
9
10
|
end
|
10
11
|
|
11
12
|
class << self
|
12
|
-
|
13
|
+
# :reek:Attribute
|
14
|
+
attr_accessor :configuration # rubocop:disable ThreadSafety/ClassAndModuleAttributes
|
13
15
|
|
14
16
|
def configure
|
15
17
|
self.configuration ||= Configuration.new
|
@@ -22,7 +24,7 @@ module Que
|
|
22
24
|
ENV.fetch("QUE_SCHEDULER_CONFIG_LOCATION", "config/que_schedule.yml")
|
23
25
|
config.transaction_adapter = ::Que.method(:transaction)
|
24
26
|
config.que_scheduler_queue =
|
25
|
-
ENV.fetch("QUE_SCHEDULER_QUEUE", Que::
|
27
|
+
ENV.fetch("QUE_SCHEDULER_QUEUE", Que::DEFAULT_QUEUE)
|
26
28
|
config.schedule = nil
|
27
29
|
config.time_zone = nil
|
28
30
|
end
|
data/lib/que/scheduler/db.rb
CHANGED
@@ -11,11 +11,11 @@ module Que
|
|
11
11
|
|
12
12
|
class << self
|
13
13
|
def count_schedulers
|
14
|
-
Que::Scheduler::
|
14
|
+
Que::Scheduler::DbSupport.execute(SCHEDULER_COUNT_SQL).first.values.first.to_i
|
15
15
|
end
|
16
16
|
|
17
17
|
def now
|
18
|
-
Que::Scheduler::
|
18
|
+
Que::Scheduler::DbSupport.execute(NOW_SQL).first.values.first
|
19
19
|
end
|
20
20
|
|
21
21
|
# rubocop:disable Style/ExplicitBlockArgument
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "que"
|
2
|
+
|
3
|
+
module Que
|
4
|
+
module Scheduler
|
5
|
+
module DbSupport
|
6
|
+
class << self
|
7
|
+
def job_attributes(enqueued_job)
|
8
|
+
enqueued_job.que_attrs.to_h.transform_keys(&:to_sym).tap do |hash|
|
9
|
+
hash[:job_id] = hash.delete(:id)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Between Que versions the result of Que execute changed keys from strings to symbols.
|
14
|
+
# Here we wrap the concept and make sure either way produces symbols
|
15
|
+
def execute(str, args = [])
|
16
|
+
normalise_array_of_hashes(Que.execute(str, args))
|
17
|
+
end
|
18
|
+
|
19
|
+
def enqueue_a_job(clazz, job_options = {}, job_args = [])
|
20
|
+
if job_args.is_a?(Hash)
|
21
|
+
clazz.enqueue(job_args, job_options: job_options)
|
22
|
+
else
|
23
|
+
clazz.enqueue(*job_args, job_options: job_options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def que_version
|
28
|
+
@que_version ||= que_version_object.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
private def que_version_object
|
32
|
+
@que_version_object ||= Gem.loaded_specs["que"].version
|
33
|
+
end
|
34
|
+
|
35
|
+
private def normalise_array_of_hashes(array)
|
36
|
+
array.map { |row| row.to_h.transform_keys(&:to_sym) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -54,7 +54,7 @@ module Que
|
|
54
54
|
validate_job_class_related(options)
|
55
55
|
end
|
56
56
|
|
57
|
-
# rubocop:disable Style/GuardClause This reads better as a conditional
|
57
|
+
# rubocop:disable Style/GuardClause -- This reads better as a conditional
|
58
58
|
private def validate_fields_types(options)
|
59
59
|
unless queue.nil? || queue.is_a?(String)
|
60
60
|
err_field(:queue, options, "queue must be a string")
|
@@ -25,16 +25,16 @@ module Que
|
|
25
25
|
DELETE_AUDIT_SQL = build_sql("que_scheduler_audit").freeze
|
26
26
|
|
27
27
|
# Very low priority
|
28
|
-
|
28
|
+
self.priority = 100
|
29
29
|
|
30
30
|
def run(options)
|
31
31
|
retain_row_count = options.symbolize_keys.fetch(:retain_row_count)
|
32
32
|
Que::Scheduler::Db.transaction do
|
33
33
|
# This may delete zero or more than `retain_row_count` depending on if anything was
|
34
34
|
# scheduled in each of the past schedule runs
|
35
|
-
Que::Scheduler::
|
35
|
+
Que::Scheduler::DbSupport.execute(DELETE_AUDIT_ENQUEUED_SQL, [retain_row_count])
|
36
36
|
# This will delete all but `retain_row_count` oldest rows
|
37
|
-
count = Que::Scheduler::
|
37
|
+
count = Que::Scheduler::DbSupport.execute(DELETE_AUDIT_SQL, [retain_row_count])
|
38
38
|
log = "#{self.class} cleared down #{count.first.fetch(:count)} rows"
|
39
39
|
::Que.log(event: :"que-scheduler", message: log)
|
40
40
|
end
|
@@ -26,46 +26,59 @@ module Que
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
# rubocop:disable MagicNumbers/NoReturn
|
29
30
|
def db_version
|
30
31
|
if audit_table_exists?
|
31
|
-
return Que::Scheduler::
|
32
|
+
return Que::Scheduler::DbSupport.execute(TABLE_COMMENT).first[:description].to_i
|
32
33
|
end
|
33
34
|
|
34
|
-
|
35
|
+
# At this point we used to be able to tell if it was 0 or 1 by the presence of the
|
36
|
+
# que_scheduler job, but that isn't auto enqueued anymore, so we assume it is 0.
|
37
|
+
0
|
35
38
|
end
|
39
|
+
# rubocop:enable MagicNumbers/NoReturn
|
36
40
|
|
37
41
|
def audit_table_exists?
|
38
|
-
result = Que::Scheduler::
|
42
|
+
result = Que::Scheduler::DbSupport.execute(<<-SQL)
|
39
43
|
SELECT * FROM information_schema.tables WHERE table_name = '#{AUDIT_TABLE_NAME}';
|
40
44
|
SQL
|
41
45
|
result.any?
|
42
46
|
end
|
43
47
|
|
44
|
-
# This method
|
48
|
+
# This method must be used during initial installation of que-scheduler and if the
|
49
|
+
# project migrations are squashed.
|
45
50
|
def reenqueue_scheduler_if_missing
|
51
|
+
raise <<~MSG unless Que::Migrations.db_version >= 6
|
52
|
+
Cannot (re)enqueue the que-scheduler worker unless the Que migrations have been run to at least version 6.
|
53
|
+
This probably means you have an old migration that installed que-scheduler, and have then since
|
54
|
+
run in another migration that has upgraded que, and are now running the migrations from scratch into a new database.
|
55
|
+
|
56
|
+
To fix this, you should remove the "Que::Scheduler::Migrations.reenqueue_scheduler_if_missing" line from any
|
57
|
+
of the older migrations and add it after the last migration that updates Que to at least version 6. eg:
|
58
|
+
|
59
|
+
Que.migrate!(version: 6)
|
60
|
+
Que::Scheduler::Migrations.reenqueue_scheduler_if_missing
|
61
|
+
MSG
|
46
62
|
return unless Que::Scheduler::Db.count_schedulers.zero?
|
47
63
|
|
48
|
-
Que::Scheduler::
|
64
|
+
Que::Scheduler::DbSupport.enqueue_a_job(Que::Scheduler::SchedulerJob)
|
49
65
|
end
|
50
66
|
|
51
67
|
private def migrate_up(current, version)
|
52
|
-
|
53
|
-
Que::Scheduler::VersionSupport.enqueue_a_job(Que::Scheduler::SchedulerJob)
|
54
|
-
end
|
55
|
-
execute_step((current += 1), :up) until current == version
|
68
|
+
execute_step(current += 1, :up) until current == version
|
56
69
|
end
|
57
70
|
|
58
71
|
private def migrate_down(current, version)
|
59
72
|
current += 1
|
60
|
-
execute_step(
|
73
|
+
execute_step(current -= 1, :down) until current == version + 1
|
61
74
|
end
|
62
75
|
|
63
76
|
private def execute_step(number, direction)
|
64
77
|
sql = File.read("#{__dir__}/migrations/#{number}/#{direction}.sql")
|
65
|
-
Que::Scheduler::
|
78
|
+
Que::Scheduler::DbSupport.execute(sql)
|
66
79
|
return unless audit_table_exists?
|
67
80
|
|
68
|
-
Que::Scheduler::
|
81
|
+
Que::Scheduler::DbSupport.execute(
|
69
82
|
"COMMENT ON TABLE que_scheduler_audit IS '#{direction == :up ? number : number - 1}'"
|
70
83
|
)
|
71
84
|
end
|
@@ -7,7 +7,7 @@ require_relative "enqueueing_calculator"
|
|
7
7
|
require_relative "scheduler_job_args"
|
8
8
|
require_relative "state_checks"
|
9
9
|
require_relative "to_enqueue"
|
10
|
-
require_relative "
|
10
|
+
require_relative "db_support"
|
11
11
|
|
12
12
|
# The main job that runs every minute, determining what needs to be enqueued, enqueues the required
|
13
13
|
# jobs, then re-enqueues itself.
|
@@ -15,9 +15,14 @@ module Que
|
|
15
15
|
module Scheduler
|
16
16
|
class SchedulerJob < Que::Job
|
17
17
|
SCHEDULER_FREQUENCY = 60
|
18
|
+
RETRY_PROC = proc { |count|
|
19
|
+
# Maximum one hour, otherwise use the default backoff
|
20
|
+
count > 7 ? (60 * 60) : ((count**4) + 3)
|
21
|
+
}
|
18
22
|
|
19
|
-
|
20
|
-
|
23
|
+
self.priority = 0 # Highest
|
24
|
+
self.maximum_retry_count = 1 << 128 # Heat death of universe
|
25
|
+
self.retry_interval = RETRY_PROC
|
21
26
|
|
22
27
|
def run(options = nil)
|
23
28
|
Que::Scheduler::Db.transaction do
|
@@ -59,12 +64,12 @@ module Que
|
|
59
64
|
private def enqueue_self_again(scheduler_job_args, last_full_execution, job_dictionary,
|
60
65
|
enqueued_jobs)
|
61
66
|
# Log last run...
|
62
|
-
job_id =
|
67
|
+
job_id = DbSupport.job_attributes(self).fetch(:job_id)
|
63
68
|
Audit.append(job_id, scheduler_job_args.as_time, enqueued_jobs)
|
64
69
|
|
65
70
|
# And rerun...
|
66
71
|
next_run_at = scheduler_job_args.as_time.beginning_of_minute + SCHEDULER_FREQUENCY
|
67
|
-
enqueued_job = Que::Scheduler::
|
72
|
+
enqueued_job = Que::Scheduler::DbSupport.enqueue_a_job(
|
68
73
|
SchedulerJob,
|
69
74
|
{
|
70
75
|
queue: Que::Scheduler.configuration.que_scheduler_queue,
|
@@ -76,8 +81,8 @@ module Que
|
|
76
81
|
}
|
77
82
|
)
|
78
83
|
|
79
|
-
# rubocop:disable Style/GuardClause This reads better as a conditional
|
80
|
-
unless enqueued_job &&
|
84
|
+
# rubocop:disable Style/GuardClause -- This reads better as a conditional
|
85
|
+
unless enqueued_job && DbSupport.job_attributes(enqueued_job).fetch(:job_id)
|
81
86
|
raise "SchedulerJob could not self-schedule. Has `.enqueue` been monkey patched?"
|
82
87
|
end
|
83
88
|
# rubocop:enable Style/GuardClause
|
@@ -16,8 +16,8 @@ module Que
|
|
16
16
|
return if db_version == Que::Scheduler::Migrations::MAX_VERSION
|
17
17
|
|
18
18
|
sync_err =
|
19
|
-
if Que
|
20
|
-
code = Que
|
19
|
+
if Que.run_synchronously && db_version.zero?
|
20
|
+
code = "Que.run_synchronously = true"
|
21
21
|
<<~ERR_SYNC
|
22
22
|
You currently have Que to run in synchronous mode using
|
23
23
|
#{code}, so it is most likely this error
|
@@ -51,6 +51,7 @@ module Que
|
|
51
51
|
class UpdateQueSchedulerSchema < ActiveRecord::Migration[6.0]
|
52
52
|
def change
|
53
53
|
Que::Scheduler::Migrations.migrate!(version: #{Que::Scheduler::Migrations::MAX_VERSION})
|
54
|
+
Que::Scheduler::Migrations.reenqueue_scheduler_if_missing
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
@@ -63,7 +63,7 @@ module Que
|
|
63
63
|
class QueJobType < ToEnqueue
|
64
64
|
def enqueue
|
65
65
|
job_settings = to_h.slice(:queue, :priority, :run_at).compact
|
66
|
-
job = Que::Scheduler::
|
66
|
+
job = Que::Scheduler::DbSupport.enqueue_a_job(
|
67
67
|
job_class,
|
68
68
|
job_settings,
|
69
69
|
args
|
@@ -73,7 +73,7 @@ module Que
|
|
73
73
|
|
74
74
|
# Now read the just inserted job back out of the DB to get the actual values that will
|
75
75
|
# be used when the job is worked.
|
76
|
-
values = Que::Scheduler::
|
76
|
+
values = Que::Scheduler::DbSupport.job_attributes(job).slice(
|
77
77
|
:args, :queue, :priority, :run_at, :job_class, :job_id
|
78
78
|
)
|
79
79
|
EnqueuedJobType.new(values)
|
@@ -121,7 +121,7 @@ module Que
|
|
121
121
|
job_settings = {
|
122
122
|
priority: priority,
|
123
123
|
wait_until: run_at,
|
124
|
-
queue: queue || Que::
|
124
|
+
queue: queue || Que::DEFAULT_QUEUE,
|
125
125
|
}.compact
|
126
126
|
|
127
127
|
job_class_set = job_class.set(**job_settings)
|
data/lib/que/scheduler.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: que-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Lascelles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -70,20 +70,20 @@ dependencies:
|
|
70
70
|
requirements:
|
71
71
|
- - ">="
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: '0
|
73
|
+
version: '2.0'
|
74
74
|
- - "<"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: 3.0
|
76
|
+
version: '3.0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '0
|
83
|
+
version: '2.0'
|
84
84
|
- - "<"
|
85
85
|
- !ruby/object:Gem::Version
|
86
|
-
version: 3.0
|
86
|
+
version: '3.0'
|
87
87
|
- !ruby/object:Gem::Dependency
|
88
88
|
name: activerecord
|
89
89
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,6 +118,20 @@ dependencies:
|
|
118
118
|
- - ">="
|
119
119
|
- !ruby/object:Gem::Version
|
120
120
|
version: '0'
|
121
|
+
- !ruby/object:Gem::Dependency
|
122
|
+
name: base64
|
123
|
+
requirement: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
type: :development
|
129
|
+
prerelease: false
|
130
|
+
version_requirements: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
121
135
|
- !ruby/object:Gem::Dependency
|
122
136
|
name: climate_control
|
123
137
|
requirement: !ruby/object:Gem::Requirement
|
@@ -202,6 +216,20 @@ dependencies:
|
|
202
216
|
- - ">="
|
203
217
|
- !ruby/object:Gem::Version
|
204
218
|
version: '0'
|
219
|
+
- !ruby/object:Gem::Dependency
|
220
|
+
name: mutex_m
|
221
|
+
requirement: !ruby/object:Gem::Requirement
|
222
|
+
requirements:
|
223
|
+
- - ">="
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: '0'
|
226
|
+
type: :development
|
227
|
+
prerelease: false
|
228
|
+
version_requirements: !ruby/object:Gem::Requirement
|
229
|
+
requirements:
|
230
|
+
- - ">="
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
version: '0'
|
205
233
|
- !ruby/object:Gem::Dependency
|
206
234
|
name: pg
|
207
235
|
requirement: !ruby/object:Gem::Requirement
|
@@ -314,20 +342,34 @@ dependencies:
|
|
314
342
|
- - ">="
|
315
343
|
- !ruby/object:Gem::Version
|
316
344
|
version: '0'
|
345
|
+
- !ruby/object:Gem::Dependency
|
346
|
+
name: rubocop-rake
|
347
|
+
requirement: !ruby/object:Gem::Requirement
|
348
|
+
requirements:
|
349
|
+
- - ">"
|
350
|
+
- !ruby/object:Gem::Version
|
351
|
+
version: 0.7.0
|
352
|
+
type: :development
|
353
|
+
prerelease: false
|
354
|
+
version_requirements: !ruby/object:Gem::Requirement
|
355
|
+
requirements:
|
356
|
+
- - ">"
|
357
|
+
- !ruby/object:Gem::Version
|
358
|
+
version: 0.7.0
|
317
359
|
- !ruby/object:Gem::Dependency
|
318
360
|
name: rubocop-rspec
|
319
361
|
requirement: !ruby/object:Gem::Requirement
|
320
362
|
requirements:
|
321
|
-
- - "
|
363
|
+
- - ">"
|
322
364
|
- !ruby/object:Gem::Version
|
323
|
-
version:
|
365
|
+
version: 3.5.0
|
324
366
|
type: :development
|
325
367
|
prerelease: false
|
326
368
|
version_requirements: !ruby/object:Gem::Requirement
|
327
369
|
requirements:
|
328
|
-
- - "
|
370
|
+
- - ">"
|
329
371
|
- !ruby/object:Gem::Version
|
330
|
-
version:
|
372
|
+
version: 3.5.0
|
331
373
|
- !ruby/object:Gem::Dependency
|
332
374
|
name: sqlite3
|
333
375
|
requirement: !ruby/object:Gem::Requirement
|
@@ -383,6 +425,7 @@ files:
|
|
383
425
|
- lib/que/scheduler/audit.rb
|
384
426
|
- lib/que/scheduler/configuration.rb
|
385
427
|
- lib/que/scheduler/db.rb
|
428
|
+
- lib/que/scheduler/db_support.rb
|
386
429
|
- lib/que/scheduler/defined_job.rb
|
387
430
|
- lib/que/scheduler/enqueueing_calculator.rb
|
388
431
|
- lib/que/scheduler/jobs/que_scheduler_audit_clear_down_job.rb
|
@@ -410,7 +453,6 @@ files:
|
|
410
453
|
- lib/que/scheduler/time_zone.rb
|
411
454
|
- lib/que/scheduler/to_enqueue.rb
|
412
455
|
- lib/que/scheduler/version.rb
|
413
|
-
- lib/que/scheduler/version_support.rb
|
414
456
|
homepage: https://github.com/hlascelles/que-scheduler
|
415
457
|
licenses:
|
416
458
|
- MIT
|
@@ -429,14 +471,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
429
471
|
requirements:
|
430
472
|
- - ">="
|
431
473
|
- !ruby/object:Gem::Version
|
432
|
-
version: '3.
|
474
|
+
version: '3.1'
|
433
475
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
434
476
|
requirements:
|
435
477
|
- - ">="
|
436
478
|
- !ruby/object:Gem::Version
|
437
479
|
version: '0'
|
438
480
|
requirements: []
|
439
|
-
rubygems_version: 3.5.
|
481
|
+
rubygems_version: 3.5.22
|
440
482
|
signing_key:
|
441
483
|
specification_version: 4
|
442
484
|
summary: A cron scheduler for Que
|
@@ -1,109 +0,0 @@
|
|
1
|
-
require "que"
|
2
|
-
|
3
|
-
# The purpose of this module is to centralise the differences when supporting both que 0.x and
|
4
|
-
# 1.x with the same gem.
|
5
|
-
module Que
|
6
|
-
module Scheduler
|
7
|
-
module VersionSupport
|
8
|
-
RETRY_PROC = proc { |count|
|
9
|
-
# Maximum one hour, otherwise use the default backoff
|
10
|
-
count > 7 ? (60 * 60) : ((count**4) + 3)
|
11
|
-
}
|
12
|
-
|
13
|
-
class << self
|
14
|
-
# Ensure que-scheduler runs at the highest priority. This is because its priority is a
|
15
|
-
# the top of all jobs it enqueues.
|
16
|
-
def set_priority(context, priority)
|
17
|
-
if zero_major?
|
18
|
-
context.instance_variable_set(:@priority, priority)
|
19
|
-
else
|
20
|
-
context.priority = priority
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Ensure the job runs at least once an hour when it is backing off due to errors
|
25
|
-
def apply_retry_semantics(context)
|
26
|
-
if zero_major?
|
27
|
-
context.instance_variable_set(:@retry_interval, RETRY_PROC)
|
28
|
-
else
|
29
|
-
context.maximum_retry_count = 1 << 128 # Heat death of universe
|
30
|
-
context.retry_interval = RETRY_PROC
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def job_attributes(enqueued_job)
|
35
|
-
if zero_major?
|
36
|
-
enqueued_job.attrs.to_h.transform_keys(&:to_sym)
|
37
|
-
else
|
38
|
-
enqueued_job.que_attrs.to_h.transform_keys(&:to_sym).tap do |hash|
|
39
|
-
hash[:job_id] = hash.delete(:id)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Between Que 0.x and 1.x the result of Que execute changed keys from strings to symbols.
|
45
|
-
# Here we wrap the concept and make sure either way produces symbols
|
46
|
-
def execute(str, args = [])
|
47
|
-
normalise_array_of_hashes(Que.execute(str, args))
|
48
|
-
end
|
49
|
-
|
50
|
-
# rubocop:disable Style/IfInsideElse
|
51
|
-
def enqueue_a_job(clazz, job_options = {}, job_args = [])
|
52
|
-
if supports_job_options_keyword?
|
53
|
-
# More recent versions have separated the way job arguments and options are passed in
|
54
|
-
if job_args.is_a?(Hash)
|
55
|
-
clazz.enqueue(job_args, job_options: job_options)
|
56
|
-
else
|
57
|
-
clazz.enqueue(*job_args, job_options: job_options)
|
58
|
-
end
|
59
|
-
else
|
60
|
-
if job_args.is_a?(Hash)
|
61
|
-
clazz.enqueue(**job_args.merge(job_options))
|
62
|
-
else
|
63
|
-
clazz.enqueue(*job_args, **job_options)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# rubocop:enable Style/IfInsideElse
|
69
|
-
def default_scheduler_queue
|
70
|
-
zero_major? ? "" : Que::DEFAULT_QUEUE
|
71
|
-
end
|
72
|
-
|
73
|
-
def running_synchronously?
|
74
|
-
zero_major? ? (Que.mode == :sync) : Que.run_synchronously
|
75
|
-
end
|
76
|
-
|
77
|
-
def running_synchronously_code?
|
78
|
-
zero_major? ? "Que.mode == :sync" : "Que.run_synchronously = true"
|
79
|
-
end
|
80
|
-
|
81
|
-
def zero_major?
|
82
|
-
# This is the only way to handle beta releases too
|
83
|
-
@zero_major ||= que_version.split(".").first.to_i.zero?
|
84
|
-
end
|
85
|
-
|
86
|
-
def one_major?
|
87
|
-
# This is the only way to handle beta releases too
|
88
|
-
@one_major ||= que_version.split(".").first.to_i == 1
|
89
|
-
end
|
90
|
-
|
91
|
-
def que_version
|
92
|
-
@que_version ||= que_version_object.to_s
|
93
|
-
end
|
94
|
-
|
95
|
-
private def supports_job_options_keyword?
|
96
|
-
@supports_job_options_keyword ||= que_version_object >= Gem::Version.new("1.2.0")
|
97
|
-
end
|
98
|
-
|
99
|
-
private def que_version_object
|
100
|
-
@que_version_object ||= Gem.loaded_specs["que"].version
|
101
|
-
end
|
102
|
-
|
103
|
-
private def normalise_array_of_hashes(array)
|
104
|
-
array.map { |row| row.to_h.transform_keys(&:to_sym) }
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|