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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8e6eface6f64e6dd63dfcd340528a0624e13fc0dc5d38e7c0aeaf9a233bf870
4
- data.tar.gz: b89fe9c4ed0bf5e0897307b695e7ff614df9b4a3cd8187e78038ff50a7bab22b
3
+ metadata.gz: 6e3f6c1fe44aef0d369e7d6dc56a55ed53669e8946cf21204ca763224ecb83fc
4
+ data.tar.gz: 5595afbfb978657ab535b8b80cebbec532c2cff72abfa235718778a883d65ef3
5
5
  SHA512:
6
- metadata.gz: 33d83f27fdf2f22beabcea208bb6f19dce018c8b60b9f29a82771a4e7b2fbd5ad25abd9e42559c2967db6bec26d89b67464a3f59ff4fa806685549ca45d4d5d5
7
- data.tar.gz: 2b0239e99adac86c1dd5d2324e9bd120ecb36a46b35b7411682c40c57a5e8767d2aff44e1ecbe32cdf613b064b5f14455bf786343ca3969f1fadb2b54bae3896
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 start the job scheduler and prepare the audit table. Note that this migration
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.
@@ -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::VersionSupport.execute(INSERT_AUDIT, [scheduler_job_id, executed_at])
27
+ ::Que::Scheduler::DbSupport.execute(INSERT_AUDIT, [scheduler_job_id, executed_at])
28
28
  enqueued_jobs.each do |j|
29
- inserted = ::Que::Scheduler::VersionSupport.execute(
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 "version_support"
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
- attr_accessor :configuration
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::Scheduler::VersionSupport.default_scheduler_queue)
27
+ ENV.fetch("QUE_SCHEDULER_QUEUE", Que::DEFAULT_QUEUE)
26
28
  config.schedule = nil
27
29
  config.time_zone = nil
28
30
  end
@@ -11,11 +11,11 @@ module Que
11
11
 
12
12
  class << self
13
13
  def count_schedulers
14
- Que::Scheduler::VersionSupport.execute(SCHEDULER_COUNT_SQL).first.values.first.to_i
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::VersionSupport.execute(NOW_SQL).first.values.first
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
- Que::Scheduler::VersionSupport.set_priority(self, 100)
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::VersionSupport.execute(DELETE_AUDIT_ENQUEUED_SQL, [retain_row_count])
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::VersionSupport.execute(DELETE_AUDIT_SQL, [retain_row_count])
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::VersionSupport.execute(TABLE_COMMENT).first[:description].to_i
32
+ return Que::Scheduler::DbSupport.execute(TABLE_COMMENT).first[:description].to_i
32
33
  end
33
34
 
34
- Que::Scheduler::Db.count_schedulers.zero? ? 0 : 1
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::VersionSupport.execute(<<-SQL)
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 is only intended for use in squashed migrations
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::VersionSupport.enqueue_a_job(Que::Scheduler::SchedulerJob)
64
+ Que::Scheduler::DbSupport.enqueue_a_job(Que::Scheduler::SchedulerJob)
49
65
  end
50
66
 
51
67
  private def migrate_up(current, version)
52
- if current.zero? # Version 1 does not use SQL
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((current -= 1), :down) until current == version + 1
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::VersionSupport.execute(sql)
78
+ Que::Scheduler::DbSupport.execute(sql)
66
79
  return unless audit_table_exists?
67
80
 
68
- Que::Scheduler::VersionSupport.execute(
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 "version_support"
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
- VersionSupport.set_priority(self, 0)
20
- VersionSupport.apply_retry_semantics(self)
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 = VersionSupport.job_attributes(self).fetch(: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::VersionSupport.enqueue_a_job(
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 && VersionSupport.job_attributes(enqueued_job).fetch(:job_id)
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::Scheduler::VersionSupport.running_synchronously? && db_version.zero?
20
- code = Que::Scheduler::VersionSupport.running_synchronously_code?
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::VersionSupport.enqueue_a_job(
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::VersionSupport.job_attributes(job).slice(
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::Scheduler::VersionSupport.default_scheduler_queue,
124
+ queue: queue || Que::DEFAULT_QUEUE,
125
125
  }.compact
126
126
 
127
127
  job_class_set = job_class.set(**job_settings)
@@ -1,5 +1,5 @@
1
1
  module Que
2
2
  module Scheduler
3
- VERSION = "5.1.1".freeze
3
+ VERSION = "6.0.0".freeze # New major
4
4
  end
5
5
  end
data/lib/que/scheduler.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "que/scheduler/version"
2
- require "que/scheduler/version_support"
2
+ require "que/scheduler/db_support"
3
3
  require "que/scheduler/configuration"
4
4
  require "que/scheduler/time_zone"
5
5
  require "que/scheduler/scheduler_job"
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: 5.1.1
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: 2024-08-21 00:00:00.000000000 Z
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.14'
73
+ version: '2.0'
74
74
  - - "<"
75
75
  - !ruby/object:Gem::Version
76
- version: 3.0.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.14'
83
+ version: '2.0'
84
84
  - - "<"
85
85
  - !ruby/object:Gem::Version
86
- version: 3.0.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: '0'
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: '0'
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.0'
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.11
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