rocketjob 3.2.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba34033326ffcb1f7047751977fdca6cd5f2ae6d
4
- data.tar.gz: 834c136c510ebad348c84925d8d63f985fd9b612
3
+ metadata.gz: 1974e77ea4b6aa126dfa57155d15bd49a659ae1e
4
+ data.tar.gz: 900333f68eb5ee6e378fc19d494b7408944fa83b
5
5
  SHA512:
6
- metadata.gz: d6cb3e4861f65738fda7ef5a135cc7f48ff446fe35ed5dce3f6058044a3f8bb12e887e2ffdaf1a4985dc37777c1ab02fb38f0587ec831684593f64fc69ea0197
7
- data.tar.gz: 75c958355fb7f96e1b7ad6af4aaf10ba740fce214dcdfefe37c638495cb951abe0eb9d60e715f1bbede8c375b8e83d78570303b0d2303e3c4ec401e60f4002f4
6
+ metadata.gz: 741923205b5e7caa759db125afe234fe4c237e80bfdadbb58db512b2ef2269f42fd9fc58207c4e9eb97a0447f164b9179472ccc0e1ba3ec64aaa155753cf0257
7
+ data.tar.gz: b44d77f843c6e6342a2be309ec50fbf25eae7f9db26e074eb96143d18283a321981050d70287189cc5c855bc3f9600da5d11328e388ac9b2f5a3aea3420170cf
@@ -7,7 +7,7 @@ module RocketJob
7
7
  # Returns the single instance of the Rocket Job Configuration for this site
8
8
  # in a thread-safe way
9
9
  def self.instance
10
- @@instance ||= begin
10
+ @instance ||= begin
11
11
  first || create
12
12
  rescue StandardError
13
13
  # In case another process has already created the first document
@@ -146,8 +146,8 @@ module RocketJob
146
146
  # Default: [] ==> Do not enforce whitelists
147
147
  #
148
148
  # Returns [Array<String>] a copy of the whitelisted paths
149
- def self.whitelist_paths
150
- @@whitelist_paths.dup
149
+ def self.get_whitelist_paths
150
+ self.whitelist_paths.dup
151
151
  end
152
152
 
153
153
  # Add a path to the whitelist
@@ -155,8 +155,8 @@ module RocketJob
155
155
  def self.add_whitelist_path(path)
156
156
  # Confirms that path exists
157
157
  path = Pathname.new(path).realpath.to_s
158
- @@whitelist_paths << path
159
- @@whitelist_paths.uniq!
158
+ self.whitelist_paths << path
159
+ self.whitelist_paths.uniq!
160
160
  path
161
161
  end
162
162
 
@@ -165,8 +165,8 @@ module RocketJob
165
165
  def self.delete_whitelist_path(path)
166
166
  # Confirms that path exists
167
167
  path = Pathname.new(path).realpath.to_s
168
- @@whitelist_paths.delete(path)
169
- @@whitelist_paths.uniq!
168
+ self.whitelist_paths.delete(path)
169
+ self.whitelist_paths.uniq!
170
170
  path
171
171
  end
172
172
 
@@ -203,9 +203,9 @@ module RocketJob
203
203
 
204
204
  # The default archive directory that is used when the job being queued does not respond
205
205
  # to #upload, and does not have an `archive_directory` specified in this entry
206
- cattr_accessor :default_archive_directory
206
+ class_attribute :default_archive_directory
207
207
 
208
- @@default_archive_directory = '_archive'.freeze
208
+ self.default_archive_directory = '_archive'.freeze
209
209
 
210
210
  # Returns [Pathname] the archive_directory if set, otherwise the default_archive_directory
211
211
  # Creates the archive directory if one is set
@@ -266,8 +266,6 @@ module RocketJob
266
266
  end
267
267
  end
268
268
 
269
- @@whitelist_paths = Concurrent::Array.new
270
-
271
269
  # Returns the Job to be queued
272
270
  def job_class
273
271
  return if job_class_name.nil?
@@ -292,10 +290,8 @@ module RocketJob
292
290
 
293
291
  private
294
292
 
295
- # Instance method to return whitelist paths
296
- def whitelist_paths
297
- @@whitelist_paths
298
- end
293
+ class_attribute :whitelist_paths
294
+ self.whitelist_paths = Concurrent::Array.new
299
295
 
300
296
  # Upload the file to the job
301
297
  def upload_file(job, pathname)
@@ -30,12 +30,15 @@ module RocketJob
30
30
  include RocketJob::Plugins::Singleton
31
31
 
32
32
  self.priority = 25
33
- self.description = 'Cleans out historical jobs'
34
- # Runs hourly on the hour
35
- self.cron_schedule = '0 * * * * America/New_York'
33
+ self.description = 'Cleans out historical jobs, and zombie servers.'
34
+ # Runs every 15 minutes
35
+ self.cron_schedule = '*/15 * * * * UTC'
36
36
 
37
- # Retention intervals in seconds
38
- # Set to nil to not
37
+ # Whether to destroy zombie servers automatically
38
+ field :destroy_zombies, type: Boolean, default: true, user_editable: true, copy_on_restart: true
39
+
40
+ # Retention intervals in seconds.
41
+ # Set to nil to retain everything.
39
42
  field :aborted_retention, type: Integer, default: 7.days, user_editable: true, copy_on_restart: true
40
43
  field :completed_retention, type: Integer, default: 7.days, user_editable: true, copy_on_restart: true
41
44
  field :failed_retention, type: Integer, default: 14.days, user_editable: true, copy_on_restart: true
@@ -43,6 +46,8 @@ module RocketJob
43
46
  field :queued_retention, type: Integer, user_editable: true, copy_on_restart: true
44
47
 
45
48
  def perform
49
+ RocketJob::Server.destroy_zombies if destroy_zombies
50
+
46
51
  RocketJob::Job.aborted.where(created_at: {'$lte' => aborted_retention.seconds.ago}).destroy_all if aborted_retention
47
52
  RocketJob::Job.completed.where(created_at: {'$lte' => completed_retention.seconds.ago}).destroy_all if completed_retention
48
53
  RocketJob::Job.failed.where(created_at: {'$lte' => failed_retention.seconds.ago}).destroy_all if failed_retention
@@ -87,8 +87,10 @@ module RocketJob
87
87
 
88
88
  # Run again in the future, even if this run fails with an exception
89
89
  def rocket_job_restart_new_instance
90
- logger.info('Job has expired. Not creating a new instance.')
91
- return if expired?
90
+ if expired?
91
+ logger.info('Job has expired. Not creating a new instance.')
92
+ return
93
+ end
92
94
  attrs = rocket_job_restart_attributes.reduce({}) { |attrs, attr| attrs[attr] = send(attr); attrs }
93
95
  rocket_job_restart_create(attrs)
94
96
  end
@@ -112,7 +114,7 @@ module RocketJob
112
114
  end
113
115
  count += 1
114
116
  end
115
- logger.warn('New job instance not started since one is already active')
117
+ logger.warn("New job instance not started: #{job.errors.messages.join(', ')}")
116
118
  false
117
119
  end
118
120
 
@@ -0,0 +1,44 @@
1
+ require 'active_support/concern'
2
+
3
+ module RocketJob
4
+ module Plugins
5
+ # Perform under a single Active Record transaction / unit or work.
6
+ #
7
+ # If the perform raises an exception it will cause any database changes to be rolled back.
8
+ #
9
+ # For Batch Jobs the transaction is at the slice level so that the entire slice succeeds,
10
+ # or is rolled back.
11
+ #
12
+ # Example:
13
+ # # Update User and create an Audit entry as a single database transaction.
14
+ # # If Audit.create! fails then the user change will also be rolled back.
15
+ # class MyJob < RocketJob::Job
16
+ # include RocketJob::Plugins::Transaction
17
+ #
18
+ # def perform
19
+ # u = User.find(name: 'Jack')
20
+ # u.age = 21
21
+ # u.save!
22
+ #
23
+ # Audit.create!(table: 'user', description: 'Changed age to 21')
24
+ # end
25
+ # end
26
+ module Transaction
27
+ extend ActiveSupport::Concern
28
+
29
+ included do
30
+ if respond_to?(:around_slice)
31
+ around_slice :rocket_job_transaction
32
+ else
33
+ around_perform :rocket_job_transaction
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def rocket_job_transaction(&block)
40
+ ActiveRecord::Base.transaction(&block)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -92,8 +92,8 @@ module RocketJob
92
92
  # Requeue any jobs being worked by this server when it is destroyed
93
93
  before_destroy :requeue_jobs
94
94
 
95
- # Destroy's all instances of zombie server and requeue any jobs still "running"
96
- # on those servers
95
+ # Destroy's all instances of zombie servers and requeues any jobs still "running"
96
+ # on those servers.
97
97
  def self.destroy_zombies
98
98
  count = 0
99
99
  each do |server|
@@ -159,27 +159,27 @@ module RocketJob
159
159
  if defined?(Concurrent::JavaAtomicBoolean) || defined?(Concurrent::CAtomicBoolean)
160
160
  # Returns [true|false] whether the shutdown indicator has been set for this server process
161
161
  def self.shutdown?
162
- @@shutdown.value
162
+ @shutdown.value
163
163
  end
164
164
 
165
165
  # Set shutdown indicator for this server process
166
166
  def self.shutdown!
167
- @@shutdown.make_true
167
+ @shutdown.make_true
168
168
  end
169
169
 
170
- @@shutdown = Concurrent::AtomicBoolean.new(false)
170
+ @shutdown = Concurrent::AtomicBoolean.new(false)
171
171
  else
172
172
  # Returns [true|false] whether the shutdown indicator has been set for this server process
173
173
  def self.shutdown?
174
- @@shutdown
174
+ @shutdown
175
175
  end
176
176
 
177
177
  # Set shutdown indicator for this server process
178
178
  def self.shutdown!
179
- @@shutdown = true
179
+ @shutdown = true
180
180
  end
181
181
 
182
- @@shutdown = false
182
+ @shutdown = false
183
183
  end
184
184
 
185
185
  # Run the server process
@@ -1,3 +1,3 @@
1
1
  module RocketJob #:nodoc
2
- VERSION = '3.2.1'
2
+ VERSION = '3.3.0'
3
3
  end
@@ -27,6 +27,7 @@ module RocketJob
27
27
  autoload :Persistence, 'rocket_job/plugins/job/persistence'
28
28
  autoload :Throttle, 'rocket_job/plugins/job/throttle'
29
29
  autoload :ThrottleRunningJobs, 'rocket_job/plugins/job/throttle_running_jobs'
30
+ autoload :Transaction, 'rocket_job/plugins/job/transaction'
30
31
  autoload :Worker, 'rocket_job/plugins/job/worker'
31
32
  end
32
33
  module Rufus
@@ -13,15 +13,15 @@ class DirmonEntryTest < Minitest::Test
13
13
  end
14
14
 
15
15
  class SumJob < RocketJob::Job
16
- @@result = nil
16
+ @result = nil
17
17
 
18
18
  # For temp test data
19
19
  def self.result
20
- @@result
20
+ @result
21
21
  end
22
22
 
23
23
  def perform(a, b)
24
- @@result = a + b
24
+ @result = a + b
25
25
  end
26
26
  end
27
27
 
@@ -11,49 +11,79 @@ class HousekeepingJobTest < Minitest::Test
11
11
  before do
12
12
  HousekeepingJobTest::TestJob.delete_all
13
13
  RocketJob::Jobs::HousekeepingJob.delete_all
14
+ RocketJob::Server.delete_all
15
+ end
14
16
 
15
- job = HousekeepingJobTest::TestJob.new(created_at: 2.days.ago)
16
- job.abort!
17
- job = HousekeepingJobTest::TestJob.new(created_at: 8.days.ago)
18
- job.abort!
17
+ describe 'job retention' do
18
+ before do
19
+ job = HousekeepingJobTest::TestJob.new(created_at: 2.days.ago)
20
+ job.abort!
21
+ job = HousekeepingJobTest::TestJob.new(created_at: 8.days.ago)
22
+ job.abort!
19
23
 
20
- job = HousekeepingJobTest::TestJob.new(created_at: 2.days.ago)
21
- job.perform_now
22
- job.save!
23
- job = HousekeepingJobTest::TestJob.new(created_at: 8.days.ago)
24
- job.perform_now
25
- job.save!
24
+ job = HousekeepingJobTest::TestJob.new(created_at: 2.days.ago)
25
+ job.perform_now
26
+ job.save!
27
+ job = HousekeepingJobTest::TestJob.new(created_at: 8.days.ago)
28
+ job.perform_now
29
+ job.save!
26
30
 
27
- job = HousekeepingJobTest::TestJob.new(created_at: 2.days.ago)
28
- job.fail!
29
- job = HousekeepingJobTest::TestJob.new(created_at: 15.days.ago)
30
- job.fail!
31
+ job = HousekeepingJobTest::TestJob.new(created_at: 2.days.ago)
32
+ job.fail!
33
+ job = HousekeepingJobTest::TestJob.new(created_at: 15.days.ago)
34
+ job.fail!
31
35
 
32
- job = HousekeepingJobTest::TestJob.new(created_at: 400.days.ago)
33
- job.pause!
34
- job = HousekeepingJobTest::TestJob.new
35
- job.pause!
36
+ job = HousekeepingJobTest::TestJob.new(created_at: 400.days.ago)
37
+ job.pause!
38
+ job = HousekeepingJobTest::TestJob.new
39
+ job.pause!
36
40
 
37
- HousekeepingJobTest::TestJob.create!(created_at: 15.days.ago)
38
- HousekeepingJobTest::TestJob.create!
41
+ HousekeepingJobTest::TestJob.create!(created_at: 15.days.ago)
42
+ HousekeepingJobTest::TestJob.create!
39
43
 
40
- assert_equal 10, HousekeepingJobTest::TestJob.count, -> { HousekeepingJobTest::TestJob.all.to_a.ai }
41
- end
44
+ assert_equal 10, HousekeepingJobTest::TestJob.count, -> { HousekeepingJobTest::TestJob.all.to_a.ai }
45
+ end
42
46
 
43
- after do
44
- @job.destroy if @job && !@job.new_record?
47
+ after do
48
+ @job.destroy if @job && !@job.new_record?
49
+ end
50
+
51
+ describe 'perform' do
52
+ it 'destroys jobs' do
53
+ @job = RocketJob::Jobs::HousekeepingJob.new
54
+ @job.perform_now
55
+ assert_equal 1, HousekeepingJobTest::TestJob.aborted.count, -> { HousekeepingJobTest::TestJob.aborted.to_a.ai }
56
+ assert_equal 1, HousekeepingJobTest::TestJob.completed.count, -> { HousekeepingJobTest::TestJob.completed.to_a.ai }
57
+ assert_equal 1, HousekeepingJobTest::TestJob.failed.count, -> { HousekeepingJobTest::TestJob.failed.to_a.ai }
58
+ assert_equal 2, HousekeepingJobTest::TestJob.paused.count, -> { HousekeepingJobTest::TestJob.paused.to_a.ai }
59
+ assert_equal 2, HousekeepingJobTest::TestJob.queued.count, -> { HousekeepingJobTest::TestJob.queued.to_a.ai }
60
+ end
61
+ end
45
62
  end
46
63
 
47
- describe 'perform' do
48
- it 'destroys jobs' do
64
+ describe 'zombie cleanup' do
65
+ before do
66
+ @server = RocketJob::Server.new
67
+ @server.started!
68
+ assert @server.reload.zombie?
69
+ assert_equal 1, RocketJob::Server.count, -> { RocketJob::Server.all.to_a.ai }
70
+ end
71
+
72
+ it 'removes zombies' do
49
73
  @job = RocketJob::Jobs::HousekeepingJob.new
74
+ assert @job.destroy_zombies
75
+ @job.perform_now
76
+ assert_equal 0, RocketJob::Server.count, -> { RocketJob::Server.all.to_a.ai }
77
+ end
78
+
79
+ it 'leaves zombies' do
80
+ @job = RocketJob::Jobs::HousekeepingJob.new(destroy_zombies: false)
81
+ refute @job.destroy_zombies
82
+ assert_equal 1, RocketJob::Server.count, -> { RocketJob::Server.all.to_a.ai }
50
83
  @job.perform_now
51
- assert_equal 1, HousekeepingJobTest::TestJob.aborted.count, -> { HousekeepingJobTest::TestJob.aborted.to_a.ai }
52
- assert_equal 1, HousekeepingJobTest::TestJob.completed.count, -> { HousekeepingJobTest::TestJob.completed.to_a.ai }
53
- assert_equal 1, HousekeepingJobTest::TestJob.failed.count, -> { HousekeepingJobTest::TestJob.failed.to_a.ai }
54
- assert_equal 2, HousekeepingJobTest::TestJob.paused.count, -> { HousekeepingJobTest::TestJob.paused.to_a.ai }
55
- assert_equal 2, HousekeepingJobTest::TestJob.queued.count, -> { HousekeepingJobTest::TestJob.queued.to_a.ai }
84
+ assert_equal 1, RocketJob::Server.count, -> { RocketJob::Server.all.to_a.ai }
56
85
  end
57
86
  end
87
+
58
88
  end
59
89
  end
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.2.1
4
+ version: 3.3.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-04-06 00:00:00.000000000 Z
11
+ date: 2017-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -111,6 +111,7 @@ files:
111
111
  - lib/rocket_job/plugins/rufus/zo_time.rb
112
112
  - lib/rocket_job/plugins/singleton.rb
113
113
  - lib/rocket_job/plugins/state_machine.rb
114
+ - lib/rocket_job/plugins/transaction.rb
114
115
  - lib/rocket_job/rocket_job.rb
115
116
  - lib/rocket_job/server.rb
116
117
  - lib/rocket_job/version.rb