que-scheduler 1.0.3 → 1.1.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: b868cd1f3196296444a8927ad9c12f9e006b6c643033f96b93b61bf62ae871c3
4
- data.tar.gz: 7367e82954c938a1ff1408dc65b8fd23042a88f0adbd9716e4763d43b6322bd4
3
+ metadata.gz: aa36f08ca0ae716d68fe7e97532c232a4e7740a625869962f433591ea034a987
4
+ data.tar.gz: c36e219b43f7b8a84fce908f21c32f5289512b2f9cf681fbb063046773165d72
5
5
  SHA512:
6
- metadata.gz: aaf6d2512f701f1eb526eb7a89b60108b80b355581a37d3b4b5bae1cbccd6829006cadd9dff45a692d51aba79530fd0d13af05f67c4afd46b35411f7ebce552d
7
- data.tar.gz: 75901d2616803d878c81317b7d6b70919fef77303264d80ad264d7f362e0664df9772607c563c922380cd27792e7e38493d3b586e6479dac25e7f7aea00ed8ca
6
+ metadata.gz: 767db06347c8be4daa350a1b38df514ac7ae58c124a5c022cf284b6bb32ba2794cf58df053ecce4ecd00c2e8532bd6de3f432fa4a5f6bbc05890aea818fc4138
7
+ data.tar.gz: 340c0d10f00ccfdeae9791d48e0112b227c92a1c9e00774a9b8d7bdb632a96587fac1be6fef59e597569491c5da6b39f21cfc89ce26fc8ad9c40104c2a668ae8
data/README.md CHANGED
@@ -37,7 +37,8 @@ integers, and job classes must be migrated from Resque to Que. Cron syntax can b
37
37
  understood by [fugit](https://github.com/floraison/fugit#fugitcron).
38
38
 
39
39
  It has one additional feature, `schedule_type: every_event`. This is set on a job that must be run for every
40
- single matching cron time that goes by, even if the system is offline over more than one match. To better process these `every_event` jobs, they are always enqueued with the first
40
+ single matching cron time that goes by, even if the system is offline over more than one match.
41
+ To better process these `every_event` jobs, they are always enqueued with the first
41
42
  argument being the time that they were supposed to be processed.
42
43
 
43
44
  For example:
@@ -137,3 +138,4 @@ This gem was inspired by the makers of the excellent [Que](https://github.com/ch
137
138
  ## Contributors
138
139
 
139
140
  * @jish
141
+ * @joehorsnell
@@ -6,6 +6,7 @@ module Que
6
6
  SCHEDULER_COUNT_SQL =
7
7
  'SELECT COUNT(*) FROM que_jobs WHERE job_class = ' \
8
8
  "'#{Que::Scheduler::SchedulerJob.name}'".freeze
9
+ NOW_SQL = 'SELECT now()'.freeze
9
10
 
10
11
  def transaction
11
12
  transaction_base.transaction do
@@ -16,6 +17,10 @@ module Que
16
17
  def count_schedulers
17
18
  dml(SCHEDULER_COUNT_SQL).first.values.first.to_i
18
19
  end
20
+
21
+ def now
22
+ Time.zone.parse(dml(NOW_SQL).first.values.first)
23
+ end
19
24
  end
20
25
 
21
26
  class ActiveRecordAdapter < AdapterBase
@@ -68,7 +68,7 @@ module Que
68
68
  cron: v['cron'],
69
69
  schedule_type: v['schedule_type'] || DefinedJob::SCHEDULE_TYPE_DEFAULT
70
70
  }.compact
71
- )
71
+ ).freeze
72
72
  end
73
73
  end
74
74
  end
@@ -94,6 +94,7 @@ module Que
94
94
  else
95
95
  jobs_for_class << options
96
96
  end
97
+ options.freeze
97
98
  end
98
99
  jobs_for_class
99
100
  end
@@ -18,10 +18,12 @@ module Que
18
18
  scheduler_job_args = SchedulerJobArgs.build(options)
19
19
  logs = ["que-scheduler last ran at #{scheduler_job_args.last_run_time}."]
20
20
 
21
- # It's possible one worker node has severe clock skew, and reports a time earlier than
22
- # the last run. If so, log, and rescheduled with the same last run at.
21
+ # It's possible the DB time has been changed manaully to an earlier time than it was
22
+ # before. Whether this was a small amount of time (eg clock drift correction), or a major
23
+ # change like timezone, the business schedule semantics of this are unknowable, so log and
24
+ # rescheduled with the same last run at.
23
25
  if scheduler_job_args.as_time < scheduler_job_args.last_run_time
24
- handle_clock_skew(scheduler_job_args, logs)
26
+ handle_db_clock_change_backwards(scheduler_job_args, logs)
25
27
  else
26
28
  # Otherwise, run as normal
27
29
  handle_normal_call(scheduler_job_args, logs)
@@ -33,6 +35,15 @@ module Que
33
35
  end
34
36
  end
35
37
 
38
+ def enqueue_required_jobs(result, logs)
39
+ result.missed_jobs.each do |job_class, options_array|
40
+ options_array.each do |options|
41
+ enqueue_new_job(job_class, options.dup, logs)
42
+ end
43
+ end
44
+ result.schedule_dictionary
45
+ end
46
+
36
47
  private
37
48
 
38
49
  def assert_one_scheduler_job
@@ -42,30 +53,30 @@ module Que
42
53
  end
43
54
 
44
55
  def handle_normal_call(scheduler_job_args, logs)
45
- result = enqueue_required_jobs(scheduler_job_args, logs)
56
+ # Obtain the hash of missed jobs. Keys are the job classes, and the values are arrays
57
+ # each containing params to enqueue.
58
+ result = EnqueueingCalculator.parse(DefinedJob.defined_jobs, scheduler_job_args)
59
+ new_job_dictionary = enqueue_required_jobs(result, logs)
46
60
  enqueue_self_again(
47
61
  scheduler_job_args.as_time,
48
62
  scheduler_job_args.as_time,
49
- result.schedule_dictionary
63
+ new_job_dictionary
50
64
  )
51
65
  end
52
66
 
53
- def enqueue_required_jobs(scheduler_job_args, logs)
54
- # Obtain the hash of missed jobs. Keys are the job classes, and the values are arrays
55
- # each containing more arrays for the arguments of that instance.
56
- result = EnqueueingCalculator.parse(DefinedJob.defined_jobs, scheduler_job_args)
57
- result.missed_jobs.each do |job_class, args_arrays|
58
- args_arrays.each do |args|
59
- logs << "que-scheduler enqueueing #{job_class} with args: #{args}"
60
- job_class.enqueue(*args)
61
- end
67
+ def enqueue_new_job(job_class, options, logs)
68
+ logs << "que-scheduler enqueueing #{job_class} with options: #{options}"
69
+ args = options.delete(:args)
70
+ if args.is_a?(Hash)
71
+ job_class.enqueue(args.merge(options))
72
+ else
73
+ job_class.enqueue(*args, options)
62
74
  end
63
- result
64
75
  end
65
76
 
66
- def handle_clock_skew(scheduler_job_args, logs)
67
- logs << 'que-scheduler detected worker with time older than last run. ' \
68
- 'Rescheduling without enqueueing jobs.'
77
+ def handle_db_clock_change_backwards(scheduler_job_args, logs)
78
+ logs << 'que-scheduler detected the DB time is further back than the last run. ' \
79
+ 'Rescheduling self again without enqueueing jobs to wait for the clock to catch up.'
69
80
  enqueue_self_again(
70
81
  scheduler_job_args.last_run_time,
71
82
  scheduler_job_args.as_time,
@@ -11,11 +11,12 @@ module Que
11
11
  property :as_time, required: true
12
12
 
13
13
  def self.build(options)
14
+ now = ::Que::Scheduler::Adapters::Orm.instance.now
14
15
  parsed =
15
16
  if options.nil?
16
- # First ever run
17
+ # First ever run, there is nothing to do but reschedule self.
17
18
  {
18
- last_run_time: Time.zone.now,
19
+ last_run_time: now,
19
20
  job_dictionary: []
20
21
  }
21
22
  else
@@ -25,7 +26,7 @@ module Que
25
26
  job_dictionary: options.fetch(:job_dictionary)
26
27
  }
27
28
  end
28
- SchedulerJobArgs.new(parsed.merge(as_time: Time.zone.now))
29
+ SchedulerJobArgs.new(parsed.merge(as_time: now))
29
30
  end
30
31
  end
31
32
  end
@@ -1,5 +1,5 @@
1
1
  module Que
2
2
  module Scheduler
3
- VERSION = '1.0.3'.freeze
3
+ VERSION = '1.1.0'.freeze
4
4
  end
5
5
  end
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: 1.0.3
4
+ version: 1.1.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: 2018-03-15 00:00:00.000000000 Z
11
+ date: 2018-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport