que-scheduler 0.5.0 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e9d071dc4b8b0357483a4a8aa5aa0b48b95e9d5
4
- data.tar.gz: 8b8090e1eb7d1106a3a861d6c3ae2361a58a3eaf
3
+ metadata.gz: 0e2783e68e146ba7ba266c283c887e256963b451
4
+ data.tar.gz: 55c52e08b23cab6ef75e3b9c8e8d0cc368f123c2
5
5
  SHA512:
6
- metadata.gz: 222d36133bf344092ad2ddff06031eecab82ee522f0da8da89d9f659f604b0770601acf676ba895003336a8076ef853538c554743f99db7571ac392e56548b92
7
- data.tar.gz: 7cc612d46143d4fe9338e4d534c2b796c85692e2be77ed9204e02e8063e1430b6e07c5d40ee9624d93da2bcb5aa9f379911fd6fb52ae76aa70e264a6b01bddae
6
+ metadata.gz: 551365361fc0f13a520c396243577d972fed0b8b3dfe798fb92990f2d1b2779bf79544b9dfb6a258439bcd5bc17a773c45bb142fa39f3b9930eec8b7487fba5d
7
+ data.tar.gz: 363661214b0d6375a813ecc68b9dbd04e1cf367dca2ff978a9047a7e2aa99825df1ae64ebda7f533919a628845f804cea4f8ea9c32a6cb805754c61a80e10f8e
data/README.md CHANGED
@@ -45,20 +45,35 @@ For example:
45
45
  CancelAbandonedOrders:
46
46
  cron: "*/5 * * * *"
47
47
 
48
+ # Specify the job_class, using any name for the key.
48
49
  queue_documents_for_indexing:
49
50
  cron: "0 0 * * *"
50
- # By default the job name (hash key) will be taken as worker class name.
51
- # If you want to have a different job name and class name, provide the 'class' option
52
- class: "QueueDocuments"
53
- queue: high
54
- args: ['reports', 'expenses']
55
-
56
- clear_leaderboards_contributors:
57
- cron: "30 6 * * 1"
58
- class: "ClearLeaderboards"
59
- queue: low
60
- args: contributors
51
+ class: QueueDocuments
61
52
 
53
+ # Specify job queues
54
+ ReportOrders:
55
+ cron: "0 0 * * *"
56
+ queue: reporting
57
+
58
+ # Specify job priority using Que's number system
59
+ BatchOrders:
60
+ cron: "0 0 * * *"
61
+ priority: 25
62
+
63
+ # Specify job queues
64
+ SendOrders:
65
+ cron: "0 0 * * *"
66
+ args: ['open']
67
+
68
+ # Altogether now
69
+ all_args_job:
70
+ cron: "0 0 * * *"
71
+ class: QueueDocuments
72
+ queue: reporting
73
+ priority: 25
74
+ args: ['open']
75
+
76
+ # Ensure you never miss a job, even after downtime
62
77
  DailyBatchReport:
63
78
  cron: "0 3 * * *"
64
79
  # This job will be run every day, and if workers are offline for several days, then the backlog
@@ -0,0 +1,32 @@
1
+ require 'hashie'
2
+ require 'fugit'
3
+
4
+ # This is the definition of one scheduled job in the yml file.
5
+ module Que
6
+ module Scheduler
7
+ class DefinedJob < Hashie::Dash
8
+ include Hashie::Extensions::Dash::PropertyTranslation
9
+
10
+ def self.err_field(f, v)
11
+ suffix = "in que-scheduler config #{QUE_SCHEDULER_CONFIG_LOCATION}"
12
+ raise "Invalid #{f} '#{v}' #{suffix}"
13
+ end
14
+
15
+ property :name, required: true
16
+ property :job_class, required: true
17
+ property :cron, transform_with: ->(v) { Fugit::Cron.new(v) || err_field(:cron, v) }
18
+ property :queue, transform_with: ->(v) { v.is_a?(String) ? v : err_field(:queue, v) }
19
+ property :priority, transform_with: ->(v) { v.is_a?(Integer) ? v : err_field(:priority, v) }
20
+ property :args
21
+ property :unmissable, default: false
22
+
23
+ # Given a "last time", return the next Time the event will occur, or nil if it
24
+ # is after "to".
25
+ def next_run_time(from, to)
26
+ next_time = cron.next_time(from)
27
+ next_run = next_time.to_local_time.in_time_zone(next_time.zone)
28
+ next_run <= to ? next_run : nil
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,4 +1,5 @@
1
1
  require 'fugit'
2
+ require 'backports/2.4.0/hash/compact'
2
3
 
3
4
  module Que
4
5
  module Scheduler
@@ -15,7 +16,7 @@ module Que
15
16
  # If it is "unmissable" then we schedule all of them, with the missed time as an arg,
16
17
  # otherwise just schedule it once.
17
18
  scheduler_config.each do |desc|
18
- job_name = desc[:name]
19
+ job_name = desc.name
19
20
  schedule_dictionary << job_name
20
21
 
21
22
  # If we have never seen this job before, we don't want to scheduled any jobs for it.
@@ -26,7 +27,7 @@ module Que
26
27
  missed = calculate_missed_runs(
27
28
  desc, scheduler_job_args.last_run_time, scheduler_job_args.as_time
28
29
  )
29
- missed_jobs[desc[:clazz]] = missed unless missed.empty?
30
+ missed_jobs[desc.job_class] = missed unless missed.empty?
30
31
  end
31
32
 
32
33
  ScheduleParserResult.new(missed_jobs, schedule_dictionary)
@@ -39,7 +40,7 @@ module Que
39
40
  def calculate_missed_runs(desc, last_run_time, as_time)
40
41
  missed_times = []
41
42
  last_time = last_run_time
42
- while (next_run = next_run_time(desc[:cron], last_time, as_time))
43
+ while (next_run = desc.next_run_time(last_time, as_time))
43
44
  missed_times << next_run
44
45
  last_time = next_run
45
46
  end
@@ -47,28 +48,24 @@ module Que
47
48
  generate_required_jobs_list(desc, missed_times)
48
49
  end
49
50
 
50
- # Given a cron, and a "last time", return the next Time the event will occur, or nil if it
51
- # is after "to".
52
- def next_run_time(cron, from, to)
53
- fugit_cron = Fugit::Cron.parse(cron)
54
- next_time = fugit_cron.next_time(from)
55
- next_run = next_time.to_local_time.in_time_zone(next_time.zone)
56
- next_run <= to ? next_run : nil
57
- end
58
-
59
51
  # Given a job description, and the timestamps of the missed events, generate a list of jobs
60
52
  # that can be enqueued as an array of arrays of args.
61
53
  def generate_required_jobs_list(desc, missed_times)
62
54
  jobs_for_class = []
55
+
63
56
  unless missed_times.empty?
64
- job_args = desc[:args]
57
+ options = {
58
+ args: desc.args,
59
+ queue: desc.queue,
60
+ priority: desc.priority
61
+ }.compact
65
62
 
66
- if desc[:unmissable]
63
+ if desc.unmissable
67
64
  missed_times.each do |time_missed|
68
- jobs_for_class << [time_missed] + job_args
65
+ jobs_for_class << options.merge(args: [time_missed] + (desc.args || []))
69
66
  end
70
67
  else
71
- jobs_for_class << job_args
68
+ jobs_for_class << options
72
69
  end
73
70
  end
74
71
  jobs_for_class
@@ -1,10 +1,16 @@
1
1
  require 'que'
2
2
  require 'yaml'
3
+ require 'backports/2.4.0/hash/compact'
4
+
5
+ require_relative 'defined_job'
3
6
  require_relative 'schedule_parser'
4
7
  require_relative 'scheduler_job_args'
5
8
 
6
9
  module Que
7
10
  module Scheduler
11
+ QUE_SCHEDULER_CONFIG_LOCATION =
12
+ ENV.fetch('QUE_SCHEDULER_CONFIG_LOCATION', 'config/que_schedule.yml')
13
+
8
14
  class SchedulerJob < Que::Job
9
15
  SCHEDULER_FREQUENCY = 60
10
16
 
@@ -17,22 +23,25 @@ module Que
17
23
 
18
24
  ::ActiveRecord::Base.transaction do
19
25
  scheduler_job_args = SchedulerJobArgs.prepare_scheduler_job_args(options)
20
- Que.log(message: "que-scheduler last ran at #{scheduler_job_args.last_run_time}.")
21
- result = enqueue_required_jobs(scheduler_job_args)
26
+ logs = ["que-scheduler last ran at #{scheduler_job_args.last_run_time}."]
27
+ result = enqueue_required_jobs(scheduler_job_args, logs)
22
28
  enqueue_self_again(scheduler_job_args, result.schedule_dictionary)
29
+
30
+ # Only now we're sure nothing errored, log the results
31
+ logs.each { |str| Que.log(message: str) }
23
32
  destroy
24
33
  end
25
34
  end
26
35
 
27
36
  private
28
37
 
29
- def enqueue_required_jobs(scheduler_job_args)
38
+ def enqueue_required_jobs(scheduler_job_args, logs)
30
39
  # Obtain the hash of missed jobs. Keys are the job classes, and the values are arrays
31
40
  # each containing more arrays for the arguments of that instance.
32
41
  result = ScheduleParser.parse(SchedulerJob.scheduler_config, scheduler_job_args)
33
42
  result.missed_jobs.each do |job_class, args_arrays|
34
43
  args_arrays.each do |args|
35
- Que.log(message: "que-scheduler enqueueing #{job_class} with args: #{args}")
44
+ logs << "que-scheduler enqueueing #{job_class} with options: #{args}"
36
45
  job_class.enqueue(*args)
37
46
  end
38
47
  end
@@ -50,8 +59,7 @@ module Que
50
59
  class << self
51
60
  def scheduler_config
52
61
  @scheduler_config ||= begin
53
- location = ENV.fetch('QUE_SCHEDULER_CONFIG_LOCATION', 'config/que_schedule.yml')
54
- jobs_list(YAML.load_file(location))
62
+ jobs_list(YAML.load_file(QUE_SCHEDULER_CONFIG_LOCATION))
55
63
  end
56
64
  end
57
65
 
@@ -59,16 +67,17 @@ module Que
59
67
  # "unmissable" parameters.
60
68
  def jobs_list(schedule)
61
69
  schedule.map do |k, v|
62
- clazz = Object.const_get(v['class'] || k)
63
- args = v.key?('args') ? v.fetch('args') : []
64
- unmissable = v['unmissable'] == true
65
- {
66
- name: k,
67
- clazz: clazz,
68
- args: args,
69
- cron: v.fetch('cron'),
70
- unmissable: unmissable
71
- }
70
+ Que::Scheduler::DefinedJob.new(
71
+ {
72
+ name: k,
73
+ job_class: Object.const_get(v['class'] || k),
74
+ queue: v['queue'],
75
+ args: v['args'],
76
+ priority: v['priority'],
77
+ cron: v['cron'],
78
+ unmissable: v['unmissable']
79
+ }.compact
80
+ )
72
81
  end
73
82
  end
74
83
  end
@@ -1,5 +1,6 @@
1
1
  require 'hashie'
2
2
 
3
+ # These are the args that are used for this particular run of the scheduler.
3
4
  module Que
4
5
  module Scheduler
5
6
  class SchedulerJobArgs < Hashie::Dash
@@ -1,5 +1,5 @@
1
1
  module Que
2
2
  module Scheduler
3
- VERSION = '0.5.0'.freeze
3
+ VERSION = '0.6.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: que-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harry Lascelles
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.10'
69
+ - !ruby/object:Gem::Dependency
70
+ name: backports
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.10'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.10'
69
83
  description: A lightweight cron scheduler for the async job worker Que
70
84
  email:
71
85
  - harry@harrylascelles.com
@@ -75,6 +89,7 @@ extra_rdoc_files: []
75
89
  files:
76
90
  - README.md
77
91
  - lib/que/scheduler.rb
92
+ - lib/que/scheduler/defined_job.rb
78
93
  - lib/que/scheduler/schedule_parser.rb
79
94
  - lib/que/scheduler/scheduler_job.rb
80
95
  - lib/que/scheduler/scheduler_job_args.rb