rocketjob 3.3.4 → 3.4.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: d6c4cf70983793dd982cefbc5b58b7ae33d6b8f1
4
- data.tar.gz: 2c593219205c7ff16dbd02dce31c57b8c67dcfa9
3
+ metadata.gz: faa325cab5ef48e8da02dc8310ab2a2098670b7b
4
+ data.tar.gz: 273ee417e36f6e69123c345d967d92e1efd77c1c
5
5
  SHA512:
6
- metadata.gz: 6dd940e8008cc81dd36085bc12f705c87a12a348e1edf29c3dbf34c1b6000bcfaf3ed085505968c35f94072f862cd13f524371836b5fe0eb7b0697da7181ca47
7
- data.tar.gz: b2e616a1ef53886ea4a5c2fef6c097d3fc640ce9a71971f1ebdb9ee4d1fc1bcd57372773af8e81003d873b4e30eb2497c2708755067b51d3994d8d74104cc288
6
+ metadata.gz: c833153f3eb38d8e7c5bcdb1c691dc5edc51fbde013e07a0f7a5c488cee848c77b573218c4cb1f04da2b06a6feadb8e30bd435dcbc3516e0291330eff459cd2a
7
+ data.tar.gz: 70cfc47e8b4383d2d61fc6ed99d4672784a4128ebb03f270a7ef667a1f6217a754d2a6a937e92caf909e9850ca78c85f4bb688aa89e970b3b32369abcfc68863
@@ -158,7 +158,7 @@ module RocketJob
158
158
  warn '-t and --threads are deprecated, use -w or --workers'
159
159
  @workers = arg.to_i
160
160
  end
161
- o.on('-F', '--filter REGEXP', 'Limit this worker to only those job classes that match this regular expression (case-insensitive)') do |arg|
161
+ o.on('-F', '--filter REGEXP', 'Limit this worker to only those job classes that match this regular expression (case-insensitive). Example: "DirmonJob|WeeklyReportJob"') do |arg|
162
162
  @filter = Regexp.new(arg, true)
163
163
  end
164
164
  o.on('-q', '--quiet', 'Do not write to stdout, only to logfile. Necessary when running as a daemon') do
@@ -28,14 +28,21 @@ module RocketJob
28
28
  # will only run once those jobs have completed, or their priority lowered. Additionally, while the
29
29
  # job is queued no additional instances will be enqueued, even if the next cron interval has been reached.
30
30
  #
31
- # Note:
31
+ # Notes:
32
32
  # - The job will not be restarted if:
33
33
  # - A validation fails after cloning this job.
34
34
  # - The job has expired.
35
35
  # - Any time the `cron_schedule` is changed, the `run_at` is automatically set before saving the changes.
36
- # - However, if the `run_at` is explicitly set then it will not be overriden.
36
+ # - However, if the `run_at` is explicitly set then it will not be overridden.
37
+ # - `cron_schedule` is not a required field so that the same job class
38
+ # - can be scheduled to run at regular intervals,
39
+ # - and run on an ad-hoc basis with custom values.
40
+ # - On job failure
41
+ # - a new future instance is created immediately.
42
+ # - the current instance is marked as failed and its cron schedule is set to nil.
43
+ # - Prevents the failed instance from creating a new future instance when it completes.
37
44
  #
38
- # Example:
45
+ # Example, schedule the job to run at regular intervals:
39
46
  #
40
47
  # class MyCronJob < RocketJob::Job
41
48
  # include RocketJob::Plugins::Cron
@@ -48,19 +55,41 @@ module RocketJob
48
55
  # end
49
56
  # end
50
57
  #
51
- # # Queue the job for processing using the default cron_schedule specified above
58
+ # # Queue the job for processing using the default cron_schedule specified above.
52
59
  # MyCronJob.create!
53
60
  #
54
- # # Set the cron schedule:
55
- # MyCronJob.create!(cron_schedule: '* 1 * * * America/New_York')
56
61
  #
62
+ # Example, a job that can run at regular intervals, and can be run for ad-hoc reporting etc.:
63
+ #
64
+ # class ReportJob < RocketJob::Job
65
+ # # Do not set a default cron_schedule so that the job can also be used for ad-hoc work.
66
+ # include RocketJob::Plugins::Cron
67
+ #
68
+ # field :start_date, type: Date
69
+ # field :end_date, type: Date
70
+ #
71
+ # def perform
72
+ # # Uses `scheduled_at` to take into account any possible delays.
73
+ # self.start_at ||= scheduled_at.beginning_of_week.to_date
74
+ # self.end_at ||= scheduled_at.end_of_week.to_date
75
+ #
76
+ # puts "Running report, starting at #{start_date}, ending at #{end_date}"
77
+ # end
78
+ # end
79
+ #
80
+ # # Queue the job for processing using a cron_schedule.
81
+ # # On completion the job will create a new instance to run at a future date.
82
+ # ReportJob.create!(cron_schedule: '* 1 * * * America/New_York')
83
+ #
84
+ # # Queue the job for processing outside of the above cron schedule.
85
+ # # On completion the job will _not_ create a new instance to run at a future date.
86
+ # job = ReportJob.create!(start_date: 30.days.ago, end_date: 10.days.ago)
57
87
  #
58
- # Note:
59
88
  #
60
- # To prevent multiple instances of the job from running at the same time,
61
- # add: "include RocketJob::Plugins::Singleton"
89
+ # To prevent multiple instances of the job from running at the same time, add the singleton plug-in:
90
+ # include RocketJob::Plugins::Singleton
62
91
  #
63
- # Example: Only allow one instance of the cron job to run at a time:
92
+ # Example: Only allow one instance of this job to be active at the same time (running, queued, scheduled, or failed):
64
93
  #
65
94
  # class MyCronJob < RocketJob::Job
66
95
  # # Add `cron_schedule`
@@ -106,14 +135,45 @@ module RocketJob
106
135
 
107
136
  before_save :rocket_job_set_run_at
108
137
 
109
- validates_presence_of :cron_schedule
110
138
  validates_each :cron_schedule do |record, attr, value|
111
139
  begin
112
- RocketJob::Plugins::Rufus::CronLine.new(value)
140
+ RocketJob::Plugins::Rufus::CronLine.new(value) if value
113
141
  rescue ArgumentError => exc
114
142
  record.errors.add(attr, exc.message)
115
143
  end
116
144
  end
145
+
146
+ private
147
+
148
+ # Prevent auto restart if this job does not have a cron schedule.
149
+ # Overrides: RocketJob::Plugins::Restart#rocket_job_restart_new_instance
150
+ def rocket_job_restart_new_instance
151
+ return unless cron_schedule
152
+ super
153
+ end
154
+
155
+ # On failure:
156
+ # - create a new instance scheduled to run in the future.
157
+ # - clear out the `cron_schedule` so this instance will not schedule another instance to run on completion.
158
+ # Overrides: RocketJob::Plugins::Restart#rocket_job_restart_abort
159
+ def rocket_job_restart_abort
160
+ return unless cron_schedule
161
+ rocket_job_restart_new_instance
162
+ self.cron_schedule = nil
163
+ end
164
+ end
165
+
166
+ # Returns [Time] at which this job was intended to run at.
167
+ #
168
+ # Takes into account any delays that could occur.
169
+ # Recommended to use this Time instead of Time.now in the `#perform` since the job could run outside its
170
+ # intended window. Especially if a failed job is only retried quite sometime later.
171
+ #
172
+ # Notes:
173
+ # * When `cron_schedule` is set, this would be the `run_at` time, otherwise it is the `created_at` time
174
+ # since that would be the intended time for which this job is running.
175
+ def scheduled_at
176
+ run_at || created_at
117
177
  end
118
178
 
119
179
  # Returns [Time] the next time this job will be scheduled to run at.
@@ -129,6 +189,7 @@ module RocketJob
129
189
  private
130
190
 
131
191
  def rocket_job_set_run_at
192
+ return unless cron_schedule
132
193
  self.run_at = rocket_job_cron_next_time if cron_schedule_changed? && !run_at_changed?
133
194
  end
134
195
 
@@ -21,7 +21,7 @@ module RocketJob
21
21
  logger.info('Start #perform')
22
22
  logger.measure_info(
23
23
  'Completed #perform',
24
- metric: "RocketJob/#{self.class.name}/perform",
24
+ metric: "#{self.class.name}/perform",
25
25
  log_exception: :full,
26
26
  on_exception_level: :error,
27
27
  silence: log_level,
@@ -1,3 +1,3 @@
1
1
  module RocketJob #:nodoc
2
- VERSION = '3.3.4'
2
+ VERSION = '3.4.0'
3
3
  end
@@ -71,10 +71,9 @@ module Plugins
71
71
  end
72
72
 
73
73
  describe '#valid?' do
74
- it 'fails on missing cron schedule' do
74
+ it 'allows missing cron schedule' do
75
75
  @job = CronJob.new
76
- refute @job.valid?
77
- assert_equal "can't be blank", @job.errors.messages[:cron_schedule].first
76
+ assert @job.valid?
78
77
  end
79
78
 
80
79
  it 'fails on bad cron schedule' do
@@ -89,6 +88,61 @@ module Plugins
89
88
  end
90
89
  end
91
90
 
91
+ describe '#fail' do
92
+ describe 'with cron_schedule' do
93
+ let :job do
94
+ job = CronJob.create!(cron_schedule: '* 1 * * *')
95
+ job.start
96
+ job.fail
97
+ job
98
+ end
99
+
100
+ it 'allows current cron job instance to fail' do
101
+ assert job.failed?
102
+ end
103
+
104
+ it 'clears out cron_schedule' do
105
+ refute job.cron_schedule
106
+ end
107
+
108
+ it 'retains run_at' do
109
+ assert job.run_at
110
+ end
111
+
112
+ it 'schedules a new instance' do
113
+ assert_equal 0, CronJob.count
114
+ job
115
+ assert_equal 2, CronJob.count
116
+ assert scheduled_job = CronJob.last
117
+ assert scheduled_job.queued?
118
+ assert_equal '* 1 * * *', scheduled_job.cron_schedule
119
+ end
120
+ end
121
+
122
+ describe 'without cron_schedule' do
123
+ let :job do
124
+ job = CronJob.create!
125
+ job.start
126
+ job.fail
127
+ job
128
+ end
129
+
130
+ it 'allows current cron job instance to fail' do
131
+ assert job.failed?
132
+ end
133
+
134
+ it 'has no cron_schedule' do
135
+ refute job.cron_schedule
136
+ end
137
+
138
+ it 'does not schedule a new instance' do
139
+ assert_equal 0, CronJob.count
140
+ job
141
+ assert_equal 1, CronJob.count
142
+ end
143
+ end
144
+ end
145
+
92
146
  end
93
147
  end
94
148
  end
data/test/test_db.sqlite3 CHANGED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rocketjob
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.4
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-30 00:00:00.000000000 Z
11
+ date: 2017-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby