simple_scheduler 1.0.0 → 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
  SHA1:
3
- metadata.gz: 778a394ce23dfc08f29201e0d0734a5521c42747
4
- data.tar.gz: f35fccb6c74a0a5d5e73c39736b09db21bf1f030
3
+ metadata.gz: 2216e4b3a7b296545fc87bf4ec4509c6e54cf80c
4
+ data.tar.gz: 3f7b99ddda05bbf8d97d320351e6bed5a617dea9
5
5
  SHA512:
6
- metadata.gz: 58b59b0e13d746d27ddbf0261972337957bf912f172ff13fbefa5a0d0186da03446212ce9a105182539043fcf49d2786ab8bf0d926527879660fe54c5103bc29
7
- data.tar.gz: 77a7202de9dd23ad87e16c850eb93fe4bf090bd6adf1476ea32300971e622b9118df4fc0b30ac3597e1aca8ec8f46ba8166687c2eade8f49de837fa91f698252
6
+ metadata.gz: 3ea3d1b9fb643828f411b3b260e4684188d3115ea65a2f409720b4fc199092645d86fd4ac841043c2d6c2375cbf17d2dd3c1e62eb677144715a9adb0a32113a5
7
+ data.tar.gz: 2b02cd203eb5bf2f16a6e469bc2cbab794445840bd95c6ce4af666a87628644a1c557f1d5bb9649ce55ca0aece0fe43837b1c886d8002a321dc5ff8ca339e249
data/README.md CHANGED
@@ -62,10 +62,11 @@ queue_ahead: 360 # Number of minutes to queue jobs into the future
62
62
  queue_name: "default" # The Sidekiq queue name used by SimpleScheduler::FutureJob
63
63
  tz: "America/Chicago" # The application time zone will be used by default if not set
64
64
 
65
- # Runs once every 2 minutes
65
+ # Runs once every 2 minutes starting at the top of the hour
66
66
  simple_task:
67
67
  class: "SomeActiveJob"
68
68
  every: "2.minutes"
69
+ at: "*:00"
69
70
 
70
71
  # Runs once every day at 4:00 AM. The job will expire after 23 hours, which means the
71
72
  # job will not run if 23 hours passes (server downtime) before the job is actually run
@@ -126,11 +127,10 @@ How frequently the task should be performed as an ActiveSupport duration definit
126
127
  "1.week"
127
128
  ```
128
129
 
129
- #### :at (optional)
130
+ #### :at
130
131
 
131
- This is the starting point\* for the `:every` duration. If not given, the job will
132
- run immediately when the configuration file is loaded for the first time and will
133
- follow the `:every` duration to determine future execution times.
132
+ This is the starting point\* for the `:every` duration. This must be set so the expected
133
+ run times in the future can be determined without duplicating jobs already in the queue.
134
134
 
135
135
  Valid string formats/examples:
136
136
 
@@ -9,8 +9,8 @@ module SimpleScheduler
9
9
  # SimpleScheduler::At.new("Sun 0:00")
10
10
  # # => 2016-12-11 00:00:00 -0600
11
11
  class At < Time
12
- AT_PATTERN = /\A(Sun|Mon|Tue|Wed|Thu|Fri|Sat)?\s?(?:\*{1,2}|((?:\b[0-1]?[0-9]|2[0-3]))):([0-5]\d)\z/
13
- DAYS = %w(Sun Mon Tue Wed Thu Fri Sat).freeze
12
+ AT_PATTERN = /\A(Sun|Mon|Tue|Wed|Thu|Fri|Sat)?\s?(?:\*{1,2}|((?:\b[0-1]?[0-9]|2[0-3]))):([0-5]\d)\z/.freeze
13
+ DAYS = %w[Sun Mon Tue Wed Thu Fri Sat].freeze
14
14
 
15
15
  # Error class raised when an invalid string is given for the time.
16
16
  class InvalidTime < StandardError; end
@@ -25,12 +25,14 @@ module SimpleScheduler
25
25
  # "[Sun|Mon|Tue|Wed|Thu|Fri|Sat] 00:00"
26
26
  # @param at [String] The formatted string for a task's run time
27
27
  # @param time_zone [ActiveSupport::TimeZone] The time zone to parse the at time in
28
+ # rubocop:disable Metrics/AbcSize
28
29
  def initialize(at, time_zone = nil)
29
30
  @at = at
30
31
  @time_zone = time_zone || Time.zone
31
32
  super(parsed_time.year, parsed_time.month, parsed_time.day,
32
33
  parsed_time.hour, parsed_time.min, parsed_time.sec, parsed_time.utc_offset)
33
34
  end
35
+ # rubocop:enable Metrics/AbcSize
34
36
 
35
37
  # Always returns the specified hour if the hour was given, otherwise
36
38
  # it returns the hour calculated based on other specified options.
@@ -49,8 +51,10 @@ module SimpleScheduler
49
51
 
50
52
  def at_match
51
53
  @at_match ||= begin
52
- match = @at.nil? ? [] : AT_PATTERN.match(@at)
54
+ match = AT_PATTERN.match(@at)
55
+ raise InvalidTime, "The `at` option is required." if @at.nil?
53
56
  raise InvalidTime, "The `at` option '#{@at}' is invalid." if match.nil?
57
+
54
58
  match
55
59
  end
56
60
  end
@@ -64,7 +68,7 @@ module SimpleScheduler
64
68
  end
65
69
 
66
70
  def at_wday
67
- @wday ||= DAYS.index(at_match[1])
71
+ @at_wday ||= DAYS.index(at_match[1])
68
72
  end
69
73
 
70
74
  def at_wday?
@@ -23,6 +23,7 @@ module SimpleScheduler
23
23
  @task = Task.new(task_params)
24
24
  @scheduled_time = Time.at(scheduled_time).in_time_zone(@task.time_zone)
25
25
  raise Expired if expired?
26
+
26
27
  queue_task
27
28
  end
28
29
 
@@ -50,6 +51,7 @@ module SimpleScheduler
50
51
  # @return [Boolean]
51
52
  def expired?
52
53
  return false if @task.expires_after.blank?
54
+
53
55
  expire_duration.from_now(@scheduled_time) < Time.now.in_time_zone(@task.time_zone)
54
56
  end
55
57
 
@@ -29,8 +29,7 @@ module SimpleScheduler
29
29
  def queue_future_jobs
30
30
  tasks.each do |task|
31
31
  # Schedule the new run times using the future job wrapper.
32
- new_run_times = task.future_run_times - task.existing_run_times
33
- new_run_times.each do |time|
32
+ task.future_run_times.each do |time|
34
33
  SimpleScheduler::FutureJob.set(queue: @queue_name, wait_until: time)
35
34
  .perform_later(task.params, time.to_i)
36
35
  end
@@ -16,7 +16,7 @@ module SimpleScheduler
16
16
  # @option params [String] :class The class of the Active Job or Sidekiq Worker
17
17
  # @option params [String] :every How frequently the job will be performed
18
18
  # @option params [String] :at The starting time for the interval
19
- # @option params [String] :expires_after The time between the scheduled and actual run time that should cause the job not to run
19
+ # @option params [String] :expires_after The interval used to determine how late the job is allowed to run
20
20
  # @option params [Integer] :queue_ahead The number of minutes that jobs should be queued in the future
21
21
  # @option params [String] :task_name The name of the task as defined in the YAML config
22
22
  # @option params [String] :tz The time zone to use when parsing the `at` option
@@ -42,6 +42,7 @@ module SimpleScheduler
42
42
  def existing_jobs
43
43
  @existing_jobs ||= SimpleScheduler::Task.scheduled_set.select do |job|
44
44
  next unless job.display_class == "SimpleScheduler::FutureJob"
45
+
45
46
  task_params = job.display_args[0].symbolize_keys
46
47
  task_params[:class] == job_class_name && task_params[:name] == name
47
48
  end.to_a
@@ -62,22 +63,24 @@ module SimpleScheduler
62
63
  # Returns an array Time objects for future run times based on
63
64
  # the current time and the given minutes to look ahead.
64
65
  # @return [Array<Time>]
66
+ # rubocop:disable Metrics/AbcSize
65
67
  def future_run_times
66
- future_run_times = existing_run_times.dup
67
- last_run_time = future_run_times.last || at - frequency
68
+ last_run_time = at - frequency
68
69
  last_run_time = last_run_time.in_time_zone(time_zone)
70
+ future_run_times = []
69
71
 
70
72
  # Ensure there are at least two future jobs scheduled and that the queue ahead time is filled
71
- while future_run_times.length < 2 || minutes_queued_ahead(last_run_time) < queue_ahead
73
+ while (future_run_times + existing_run_times).length < 2 || minutes_queued_ahead(last_run_time) < queue_ahead
72
74
  last_run_time = frequency.from_now(last_run_time)
73
75
  # The hour may not match because of a shift caused by DST in previous run times,
74
76
  # so we need to ensure that the hour matches the specified hour if given.
75
77
  last_run_time = last_run_time.change(hour: at.hour, min: at.min) if at.hour?
76
- future_run_times << last_run_time
78
+ future_run_times << last_run_time unless existing_run_times.include?(last_run_time)
77
79
  end
78
80
 
79
81
  future_run_times
80
82
  end
83
+ # rubocop:enable Metrics/AbcSize
81
84
 
82
85
  # The class name of the job or worker.
83
86
  # @return [String]
@@ -126,6 +129,7 @@ module SimpleScheduler
126
129
  def validate_params!(params)
127
130
  raise ArgumentError, "Missing param `class` specifying the class of the job to run." unless params.key?(:class)
128
131
  raise ArgumentError, "Missing param `every` specifying how often the job should run." unless params.key?(:every)
132
+
129
133
  @job_class = params[:class].constantize
130
134
  params[:name] ||= params[:class]
131
135
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleScheduler
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Pattison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-17 00:00:00.000000000 Z
11
+ date: 2019-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: codeclimate-test-reporter
56
+ name: rainbow
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rainbow
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 2.1.0
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 2.1.0
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: rspec-rails
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -98,16 +84,16 @@ dependencies:
98
84
  name: rubocop
99
85
  requirement: !ruby/object:Gem::Requirement
100
86
  requirements:
101
- - - ">="
87
+ - - "~>"
102
88
  - !ruby/object:Gem::Version
103
- version: '0'
89
+ version: 0.66.0
104
90
  type: :development
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
- - - ">="
94
+ - - "~>"
109
95
  - !ruby/object:Gem::Version
110
- version: '0'
96
+ version: 0.66.0
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: simplecov
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -177,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
163
  version: '0'
178
164
  requirements: []
179
165
  rubyforge_project:
180
- rubygems_version: 2.5.2
166
+ rubygems_version: 2.5.2.3
181
167
  signing_key:
182
168
  specification_version: 4
183
169
  summary: An enhancement for Heroku Scheduler + Sidekiq for scheduling jobs at specific