rocketjob 3.3.1 → 3.3.2

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: 73879d59ee0d46f407f77acfc5b443b693e16727
4
- data.tar.gz: 27d8a5a990b39d19c00ff086d57b3df2263eb727
3
+ metadata.gz: 39e1ecc5af4c504fb096f81dd86504bbd80d2336
4
+ data.tar.gz: 0b25172aa4de31ae79713a7c5427d1c985163384
5
5
  SHA512:
6
- metadata.gz: 3fb4043fb6aca63ecb3968393aada59cd81101d69453592cc5032722d1751ce3716c095dee54baa0be77136df05f36ce49687d1a4f1a66a37c68feeae22870b9
7
- data.tar.gz: ff2c14ea7b456f59f86b85f34174a2ab0d90d72799c7e839b90def2a288b44969f8a558a915129df0dce726d9b0d28252c91d1f9d5aefaf331dcf43d9500cd51
6
+ metadata.gz: 62efb08e25832d84977ec3060982167c0e6958d4b9380f8ecf67f7a64c18b1a4be2765e086bc9d07cade9edaf6a3d8077a725329df6c1c27543d35072b0918c1
7
+ data.tar.gz: 3f4380575fc99756a2fd63f9d84f571c9ff1ce12dbeab8d642aacd2c4c4b04a54ba98416d6d04dd00760aeb59427304815a755e0dc205770fcf8293776db97cc
@@ -16,7 +16,7 @@ module RocketJob
16
16
  def self.all(server_name = nil)
17
17
  servers = []
18
18
  # Need paused, failed or aborted since servers may still be working on active slices
19
- query = RocketJob::Job.where(:state.in => [:running, :paused, :failed, :aborted])
19
+ query = RocketJob::Job.where(:state.in => [:running, :paused, :failed, :aborted])
20
20
  query = query.where(worker_name: /\A#{server_name}/) if server_name
21
21
  query.each do |job|
22
22
  servers += job.rocket_job_active_workers
@@ -7,8 +7,8 @@ module RocketJob
7
7
  class CLI
8
8
  include SemanticLogger::Loggable
9
9
  attr_accessor :name, :workers, :environment, :pidfile, :directory, :quiet,
10
- :log_level, :log_file, :mongo_config, :symmetric_encryption_config,
11
- :filter
10
+ :log_level, :log_file, :mongo_config, :symmetric_encryption_config,
11
+ :filter
12
12
 
13
13
  def initialize(argv)
14
14
  @name = nil
@@ -234,7 +234,7 @@ module RocketJob
234
234
  next if file_name.include?(self.class.default_archive_directory)
235
235
 
236
236
  # Security check?
237
- if (whitelist_paths.size > 0) && whitelist_paths.none? {|whitepath| file_name.to_s.start_with?(whitepath)}
237
+ if (whitelist_paths.size > 0) && whitelist_paths.none? { |whitepath| file_name.to_s.start_with?(whitepath) }
238
238
  logger.error "Skipping file: #{file_name} since it is not in any of the whitelisted paths: #{whitelist_paths.join(', ')}"
239
239
  next
240
240
  end
@@ -29,8 +29,8 @@ module RocketJob
29
29
  include RocketJob::Plugins::Cron
30
30
  include RocketJob::Plugins::Singleton
31
31
 
32
- self.priority = 25
33
- self.description = 'Cleans out historical jobs, and zombie servers.'
32
+ self.priority = 25
33
+ self.description = 'Cleans out historical jobs, and zombie servers.'
34
34
  # Runs every 15 minutes
35
35
  self.cron_schedule = '*/15 * * * * UTC'
36
36
 
@@ -70,14 +70,15 @@ module RocketJob
70
70
  # }
71
71
  def counts_by_state
72
72
  counts = {}
73
- collection.aggregate([
74
- {
75
- '$group' => {
76
- _id: '$state',
77
- count: {'$sum' => 1}
73
+ collection.aggregate(
74
+ [
75
+ {
76
+ '$group' => {
77
+ _id: '$state',
78
+ count: {'$sum' => 1}
79
+ }
78
80
  }
79
- }
80
- ]
81
+ ]
81
82
  ).each do |result|
82
83
  counts[result['_id'].to_sym] = result['count']
83
84
  end
@@ -77,9 +77,9 @@ module RocketJob
77
77
  end
78
78
 
79
79
  event :requeue do
80
- transitions from: :running, to: :queued,
81
- if: -> server_name { worker_on_server?(server_name) },
82
- after: :rocket_job_clear_started_at
80
+ transitions from: :running, to: :queued,
81
+ if: -> server_name { worker_on_server?(server_name) },
82
+ after: :rocket_job_clear_started_at
83
83
  end
84
84
  end
85
85
  # @formatter:on
@@ -38,8 +38,8 @@ module RocketJob
38
38
  def throttle_running_jobs_exceeded?
39
39
  throttle_running_jobs &&
40
40
  (throttle_running_jobs != 0) &&
41
- # Cannot use class since it will include instances of parent job classes.
42
- (RocketJob::Job.running.where('_type' => self.class.name, :id.ne => id).count >= throttle_running_jobs)
41
+ # Cannot use the class since it will include instances of parent job classes.
42
+ (RocketJob::Job.running.where('_type' => self.class.name, :id.ne => id).count >= throttle_running_jobs)
43
43
  end
44
44
  end
45
45
  end
@@ -114,7 +114,7 @@ module RocketJob
114
114
  end
115
115
  count += 1
116
116
  end
117
- logger.warn("New job instance not started: #{job.errors.messages.join(', ')}")
117
+ logger.warn("New job instance not started: #{job.errors.messages.inspect}")
118
118
  false
119
119
  end
120
120
 
@@ -25,7 +25,7 @@ module RocketJob
25
25
  # include RocketJob::Plugins::Retry
26
26
  #
27
27
  # # Set the default retry_count
28
- # self.max_retries = 3
28
+ # self.retry_limit = 3
29
29
  #
30
30
  # def perform
31
31
  # puts "DONE"
@@ -36,10 +36,10 @@ module RocketJob
36
36
  # MyJob.create!
37
37
  #
38
38
  # # Replace the default retry_count
39
- # MyCronJob.create!(max_retries: 10)
39
+ # MyCronJob.create!(retry_limit: 10)
40
40
  #
41
41
  # # Disable retries for this job instance
42
- # MyCronJob.create!(max_retries: 0)
42
+ # MyCronJob.create!(retry_limit: 0)
43
43
  #
44
44
  module Retry
45
45
  extend ActiveSupport::Concern
@@ -49,17 +49,21 @@ module RocketJob
49
49
 
50
50
  # Maximum number of times to retry this job
51
51
  # 25 is approximately 3 weeks of retries
52
- field :max_retries, type: Integer, default: 25, class_attribute: true, user_editable: true, copy_on_restart: true
52
+ field :retry_limit, type: Integer, default: 25, class_attribute: true, user_editable: true, copy_on_restart: true
53
53
 
54
54
  # List of times when this job failed
55
- field :failed_times, type: Array, default: []
55
+ field :failed_at_list, type: Array, default: []
56
56
 
57
- validates_presence_of :max_retries
57
+ validates_presence_of :retry_limit
58
58
  end
59
59
 
60
- # Returns [true|false] whether this job will be automatically retried on failure
60
+ # Returns [true|false] whether this job should be retried on failure.
61
61
  def rocket_job_retry_on_fail?
62
- failure_count > max_retries
62
+ rocket_job_failure_count < retry_limit
63
+ end
64
+
65
+ def rocket_job_failure_count
66
+ failed_at_list.size
63
67
  end
64
68
 
65
69
  private
@@ -73,8 +77,8 @@ module RocketJob
73
77
 
74
78
  now = Time.now
75
79
  self.run_at = now + delay_seconds
76
- self.failed_times << now
77
- new_record? ? retry : retry!
80
+ self.failed_at_list << now
81
+ new_record? ? self.retry : self.retry!
78
82
  end
79
83
 
80
84
  # Prevent exception from being cleared on retry
@@ -85,9 +89,9 @@ module RocketJob
85
89
  end
86
90
 
87
91
  # Returns [Time] when to retry this job at
88
- # Same basic formula as Sidekiq and Delayed Job
92
+ # Same basic formula as Delayed Job
89
93
  def rocket_job_retry_seconds_to_delay
90
- (failure_count ** 4) + 15 + (rand(30)*(failure_count+1))
94
+ (rocket_job_failure_count ** 4) + 15 + (rand(30) * (rocket_job_failure_count + 1))
91
95
  end
92
96
 
93
97
  end
@@ -21,6 +21,7 @@
21
21
  #
22
22
  # Made in Japan.
23
23
  #++
24
+ #@formatter:off
24
25
 
25
26
  require 'set'
26
27
 
@@ -21,6 +21,7 @@
21
21
  #
22
22
  # Made in Japan.
23
23
  #++
24
+ #@formatter:off
24
25
 
25
26
  module RocketJob::Plugins::Rufus
26
27
  #
@@ -141,14 +141,15 @@ module RocketJob
141
141
  # # => {}
142
142
  def self.counts_by_state
143
143
  counts = {}
144
- collection.aggregate([
145
- {
146
- '$group' => {
147
- _id: '$state',
148
- count: {'$sum' => 1}
144
+ collection.aggregate(
145
+ [
146
+ {
147
+ '$group' => {
148
+ _id: '$state',
149
+ count: {'$sum' => 1}
150
+ }
149
151
  }
150
- }
151
- ]
152
+ ]
152
153
  ).each do |result|
153
154
  counts[result['_id'].to_sym] = result['count']
154
155
  end
@@ -1,3 +1,3 @@
1
1
  module RocketJob #:nodoc
2
- VERSION = '3.3.1'
2
+ VERSION = '3.3.2'
3
3
  end
data/lib/rocketjob.rb CHANGED
@@ -38,6 +38,7 @@ module RocketJob
38
38
  autoload :Document, 'rocket_job/plugins/document'
39
39
  autoload :ProcessingWindow, 'rocket_job/plugins/processing_window'
40
40
  autoload :Restart, 'rocket_job/plugins/restart'
41
+ autoload :Retry, 'rocket_job/plugins/retry'
41
42
  autoload :Singleton, 'rocket_job/plugins/singleton'
42
43
  autoload :StateMachine, 'rocket_job/plugins/state_machine'
43
44
  autoload :Transaction, 'rocket_job/plugins/transaction'
@@ -86,15 +86,15 @@ module Plugins
86
86
  ThrottleJob.create!(state: :failed)
87
87
  ThrottleJob.create!(state: :complete)
88
88
  ThrottleJob.create!(state: :paused)
89
- assert job = RocketJob::Job.rocket_job_next_job(@worker_name), -> {ThrottleJob.all.to_a.ai}
90
- assert_equal @job.id, job.id, -> {ThrottleJob.all.to_a.ai}
89
+ assert job = RocketJob::Job.rocket_job_next_job(@worker_name), -> { ThrottleJob.all.to_a.ai }
90
+ assert_equal @job.id, job.id, -> { ThrottleJob.all.to_a.ai }
91
91
  end
92
92
 
93
93
  it 'return nil when other jobs are running' do
94
94
  ThrottleJob.create!
95
95
  @job = ThrottleJob.new
96
96
  @job.start!
97
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name), -> {ThrottleJob.all.to_a.ai}
97
+ assert_nil RocketJob::Job.rocket_job_next_job(@worker_name), -> { ThrottleJob.all.to_a.ai }
98
98
  end
99
99
 
100
100
  it 'add job to filter when other jobs are running' do
@@ -102,7 +102,7 @@ module Plugins
102
102
  @job = ThrottleJob.new
103
103
  @job.start!
104
104
  filter = {}
105
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name, filter), -> {ThrottleJob.all.to_a.ai}
105
+ assert_nil RocketJob::Job.rocket_job_next_job(@worker_name, filter), -> { ThrottleJob.all.to_a.ai }
106
106
  assert_equal 1, filter.size
107
107
  end
108
108
  end
@@ -0,0 +1,89 @@
1
+ require_relative '../test_helper'
2
+
3
+ module Plugins
4
+ class RetryTest < Minitest::Test
5
+ class RetryJob < RocketJob::Job
6
+ include RocketJob::Plugins::Retry
7
+
8
+ # Fails 5 times before succeeding
9
+ def perform
10
+ raise "Oh No" unless rocket_job_failure_count >= 5
11
+ 'DONE'
12
+ end
13
+ end
14
+
15
+ describe RocketJob::Plugins::Retry do
16
+ before do
17
+ RetryJob.delete_all
18
+ end
19
+
20
+ after do
21
+ @job.delete if @job && !@job.new_record?
22
+ end
23
+
24
+ describe '#perform' do
25
+ it 're-queues job on failure' do
26
+ @job = RetryJob.create!
27
+ assert created_at = @job.created_at
28
+ assert_equal 0, @job.failed_at_list.size
29
+
30
+ assert_raises RuntimeError do
31
+ @job.perform_now
32
+ end
33
+
34
+ assert @job.queued?, -> { @job.attributes.ai }
35
+
36
+ # Includes failure time
37
+ assert_equal 1, @job.rocket_job_failure_count
38
+ assert failed_at = @job.failed_at_list.first
39
+ assert failed_at >= created_at
40
+
41
+ assert next_time = @job.run_at
42
+ assert next_time > failed_at
43
+ end
44
+
45
+ it 're-queues until it succeeds' do
46
+ @job = RetryJob.create!
47
+
48
+ # 5 retries
49
+ 5.times do |i|
50
+ assert_raises RuntimeError do
51
+ @job.perform_now
52
+ end
53
+ assert @job.queued?, -> { @job.attributes.ai }
54
+ assert_equal (i + 1), @job.rocket_job_failure_count
55
+ end
56
+
57
+ assert_equal 5, @job.rocket_job_failure_count
58
+
59
+ # Should succeed on the 6th attempt
60
+ @job.perform_now
61
+ assert @job.completed?, -> { @job.attributes.ai }
62
+ assert_equal 5, @job.rocket_job_failure_count
63
+ end
64
+
65
+ it 'stops re-queueing after limit is reached' do
66
+ @job = RetryJob.create!(retry_limit: 3)
67
+
68
+ # 3 attempts are retried
69
+ 3.times do |i|
70
+ assert_raises RuntimeError do
71
+ @job.perform_now
72
+ end
73
+ assert @job.queued?, -> { @job.attributes.ai }
74
+ assert_equal (i + 1), @job.rocket_job_failure_count
75
+ end
76
+
77
+ # Should fail on the 4th attempt
78
+ assert_equal 3, @job.rocket_job_failure_count
79
+ assert_raises RuntimeError do
80
+ @job.perform_now
81
+ end
82
+
83
+ assert @job.failed?, -> { @job.attributes.ai }
84
+ end
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -53,9 +53,9 @@ module Plugins
53
53
 
54
54
  describe '#rocket_job_transaction' do
55
55
  it 'is registered' do
56
- assert CommitTransactionJob.send(:get_callbacks, :perform).find {|c| c.filter == :rocket_job_transaction}
57
- assert RollbackTransactionJob.send(:get_callbacks, :perform).find {|c| c.filter == :rocket_job_transaction}
58
- refute RocketJob::Job.send(:get_callbacks, :perform).find {|c| c.filter == :rocket_job_transaction}
56
+ assert CommitTransactionJob.send(:get_callbacks, :perform).find { |c| c.filter == :rocket_job_transaction }
57
+ assert RollbackTransactionJob.send(:get_callbacks, :perform).find { |c| c.filter == :rocket_job_transaction }
58
+ refute RocketJob::Job.send(:get_callbacks, :perform).find { |c| c.filter == :rocket_job_transaction }
59
59
  end
60
60
  end
61
61
 
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.1
4
+ version: 3.3.2
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-05-09 00:00:00.000000000 Z
11
+ date: 2017-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -135,6 +135,7 @@ files:
135
135
  - test/plugins/job/worker_test.rb
136
136
  - test/plugins/processing_window_test.rb
137
137
  - test/plugins/restart_test.rb
138
+ - test/plugins/retry_test.rb
138
139
  - test/plugins/singleton_test.rb
139
140
  - test/plugins/state_machine_event_callbacks_test.rb
140
141
  - test/plugins/state_machine_test.rb
@@ -185,6 +186,7 @@ test_files:
185
186
  - test/plugins/job/worker_test.rb
186
187
  - test/plugins/processing_window_test.rb
187
188
  - test/plugins/restart_test.rb
189
+ - test/plugins/retry_test.rb
188
190
  - test/plugins/singleton_test.rb
189
191
  - test/plugins/state_machine_event_callbacks_test.rb
190
192
  - test/plugins/state_machine_test.rb