rocketjob 3.5.2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -1
  3. data/bin/rocketjob +1 -0
  4. data/bin/rocketjob_batch_perf +11 -0
  5. data/lib/rocket_job/batch.rb +32 -0
  6. data/lib/rocket_job/batch/callbacks.rb +40 -0
  7. data/lib/rocket_job/batch/io.rb +154 -0
  8. data/lib/rocket_job/batch/logger.rb +57 -0
  9. data/lib/rocket_job/batch/lower_priority.rb +54 -0
  10. data/lib/rocket_job/batch/model.rb +157 -0
  11. data/lib/rocket_job/batch/performance.rb +99 -0
  12. data/lib/rocket_job/batch/result.rb +8 -0
  13. data/lib/rocket_job/batch/results.rb +9 -0
  14. data/lib/rocket_job/batch/state_machine.rb +102 -0
  15. data/lib/rocket_job/batch/statistics.rb +88 -0
  16. data/lib/rocket_job/batch/tabular.rb +56 -0
  17. data/lib/rocket_job/batch/tabular/input.rb +123 -0
  18. data/lib/rocket_job/batch/tabular/output.rb +59 -0
  19. data/lib/rocket_job/batch/throttle.rb +91 -0
  20. data/lib/rocket_job/batch/throttle_running_slices.rb +53 -0
  21. data/lib/rocket_job/batch/worker.rb +288 -0
  22. data/lib/rocket_job/cli.rb +29 -7
  23. data/lib/rocket_job/config.rb +1 -1
  24. data/lib/rocket_job/extensions/mongoid/clients/options.rb +37 -0
  25. data/lib/rocket_job/extensions/mongoid/contextual/mongo.rb +17 -0
  26. data/lib/rocket_job/extensions/mongoid/factory.rb +4 -4
  27. data/lib/rocket_job/extensions/mongoid_5/clients/options.rb +38 -0
  28. data/lib/rocket_job/extensions/mongoid_5/contextual/mongo.rb +64 -0
  29. data/lib/rocket_job/extensions/mongoid_5/factory.rb +13 -0
  30. data/lib/rocket_job/jobs/on_demand_batch_job.rb +127 -0
  31. data/lib/rocket_job/jobs/performance_job.rb +18 -0
  32. data/lib/rocket_job/jobs/upload_file_job.rb +2 -5
  33. data/lib/rocket_job/plugins/document.rb +2 -8
  34. data/lib/rocket_job/plugins/job/persistence.rb +6 -4
  35. data/lib/rocket_job/plugins/job/throttle.rb +3 -6
  36. data/lib/rocket_job/plugins/job/worker.rb +2 -2
  37. data/lib/rocket_job/server.rb +14 -3
  38. data/lib/rocket_job/sliced/input.rb +336 -0
  39. data/lib/rocket_job/sliced/output.rb +99 -0
  40. data/lib/rocket_job/sliced/slice.rb +166 -0
  41. data/lib/rocket_job/sliced/slices.rb +166 -0
  42. data/lib/rocket_job/sliced/writer/input.rb +60 -0
  43. data/lib/rocket_job/sliced/writer/output.rb +82 -0
  44. data/lib/rocket_job/version.rb +1 -1
  45. data/lib/rocket_job/worker.rb +2 -2
  46. data/lib/rocketjob.rb +28 -0
  47. metadata +51 -62
  48. data/test/config/database.yml +0 -5
  49. data/test/config/mongoid.yml +0 -88
  50. data/test/config_test.rb +0 -10
  51. data/test/dirmon_entry_test.rb +0 -313
  52. data/test/dirmon_job_test.rb +0 -216
  53. data/test/files/text.txt +0 -3
  54. data/test/job_test.rb +0 -71
  55. data/test/jobs/housekeeping_job_test.rb +0 -102
  56. data/test/jobs/on_demand_job_test.rb +0 -59
  57. data/test/jobs/upload_file_job_test.rb +0 -107
  58. data/test/plugins/cron_test.rb +0 -166
  59. data/test/plugins/job/callbacks_test.rb +0 -166
  60. data/test/plugins/job/defaults_test.rb +0 -53
  61. data/test/plugins/job/logger_test.rb +0 -56
  62. data/test/plugins/job/model_test.rb +0 -94
  63. data/test/plugins/job/persistence_test.rb +0 -94
  64. data/test/plugins/job/state_machine_test.rb +0 -116
  65. data/test/plugins/job/throttle_test.rb +0 -111
  66. data/test/plugins/job/worker_test.rb +0 -199
  67. data/test/plugins/processing_window_test.rb +0 -109
  68. data/test/plugins/restart_test.rb +0 -193
  69. data/test/plugins/retry_test.rb +0 -88
  70. data/test/plugins/singleton_test.rb +0 -92
  71. data/test/plugins/state_machine_event_callbacks_test.rb +0 -102
  72. data/test/plugins/state_machine_test.rb +0 -67
  73. data/test/plugins/transaction_test.rb +0 -84
  74. data/test/test_db.sqlite3 +0 -0
  75. data/test/test_helper.rb +0 -17
@@ -1,116 +0,0 @@
1
- require_relative '../../test_helper'
2
- module Plugins
3
- module Job
4
- # Unit Test for RocketJob::Job
5
- class StateMachineTest < Minitest::Test
6
- class StateMachineJob < RocketJob::Job
7
- def perform
8
- end
9
- end
10
-
11
- describe RocketJob::Plugins::Job::StateMachine do
12
- before do
13
- @job = StateMachineJob.new
14
- end
15
-
16
- after do
17
- @job.destroy if @job && !@job.new_record?
18
- end
19
-
20
- describe '#requeue!' do
21
- it 'requeue jobs from dead workers' do
22
- worker_name = 'server:12345'
23
- @job.worker_name = worker_name
24
- @job.start!
25
- assert @job.running?
26
-
27
- @job.requeue!(worker_name)
28
- @job.reload
29
-
30
- assert @job.queued?
31
- assert_nil @job.worker_name
32
- end
33
- end
34
-
35
- describe '#requeue' do
36
- it 'requeue jobs from dead workers' do
37
- worker_name = 'server:12345'
38
- @job.worker_name = worker_name
39
- assert @job.valid?, @job.errors.messages
40
- @job.start!
41
- assert @job.running?, @job.state
42
-
43
- @job.requeue(worker_name)
44
- assert @job.queued?
45
- assert_nil @job.worker_name
46
-
47
- @job.reload
48
- assert @job.running?
49
- assert_equal worker_name, @job.worker_name
50
- end
51
- end
52
-
53
- describe '#after_complete' do
54
- it 'destroy on complete' do
55
- @job.destroy_on_complete = true
56
- @job.perform_now
57
- assert @job.completed?, @job.state
58
- assert_equal 0, RocketJob::Job.where(id: @job.id).count
59
- end
60
- end
61
-
62
- describe '#fail!' do
63
- it 'fail with message' do
64
- @job.start!
65
- @job.fail!('myworker:2323', 'oh no')
66
- assert @job.failed?
67
- assert exc = @job.exception
68
- assert_equal 'RocketJob::JobException', exc.class_name
69
- assert_equal 'oh no', exc.message
70
- end
71
-
72
- it 'fail with no arguments' do
73
- @job.start!
74
- @job.fail!
75
- assert @job.failed?
76
- assert exc = @job.exception
77
- assert_equal 'RocketJob::JobException', exc.class_name
78
- assert_nil exc.message
79
- assert_nil exc.worker_name
80
- assert_equal [], exc.backtrace
81
- end
82
-
83
- it 'fail with exception' do
84
- @job.start!
85
- exception = RuntimeError.new('Oh no')
86
- @job.fail!('myworker:2323', exception)
87
- assert @job.failed?
88
- assert exc = @job.exception
89
- assert_equal exception.class.name, exc.class_name
90
- assert_equal exception.message, exc.message
91
- assert_equal [], exc.backtrace
92
- end
93
- end
94
-
95
- describe '#retry!' do
96
- it 'retry failed jobs' do
97
- worker_name = 'server:12345'
98
- @job.worker_name = worker_name
99
- @job.start!
100
- assert @job.running?
101
- assert_equal worker_name, @job.worker_name
102
-
103
- @job.fail!(worker_name, 'oh no')
104
- assert @job.failed?
105
- assert_equal 'oh no', @job.exception.message
106
-
107
- @job.retry!
108
- assert @job.queued?
109
- assert_nil @job.worker_name
110
- assert_nil @job.exception
111
- end
112
- end
113
- end
114
- end
115
- end
116
- end
@@ -1,111 +0,0 @@
1
- require_relative '../../test_helper'
2
-
3
- # Unit Test for RocketJob::Job
4
- module Plugins
5
- module Job
6
- class ThrottleTest < Minitest::Test
7
- class ThrottleJob < RocketJob::Job
8
- # Only allow one to be processed at a time
9
- self.throttle_running_jobs = 1
10
- self.pausable = true
11
-
12
- def perform
13
- 21
14
- end
15
- end
16
-
17
- describe RocketJob::Plugins::Job::Throttle do
18
- before do
19
- RocketJob::Job.delete_all
20
- end
21
-
22
- describe '.throttle?' do
23
- it 'defines the running jobs throttle' do
24
- assert ThrottleJob.throttle?(:throttle_running_jobs_exceeded?), ThrottleJob.rocket_job_throttles
25
- refute ThrottleJob.throttle?(:blah?), ThrottleJob.rocket_job_throttles
26
- end
27
- end
28
-
29
- describe '.undefine_throttle' do
30
- it 'undefines the running jobs throttle' do
31
- assert ThrottleJob.throttle?(:throttle_running_jobs_exceeded?), ThrottleJob.rocket_job_throttles
32
- ThrottleJob.undefine_throttle(:throttle_running_jobs_exceeded?)
33
- refute ThrottleJob.throttle?(:throttle_running_jobs_exceeded?), ThrottleJob.rocket_job_throttles
34
- ThrottleJob.define_throttle(:throttle_running_jobs_exceeded?)
35
- assert ThrottleJob.throttle?(:throttle_running_jobs_exceeded?), ThrottleJob.rocket_job_throttles
36
- end
37
- end
38
-
39
- describe '#throttle_running_jobs_exceeded??' do
40
- it 'does not exceed throttle when no other jobs are running' do
41
- ThrottleJob.create!
42
- job = ThrottleJob.new
43
- refute job.send(:throttle_running_jobs_exceeded?)
44
- end
45
-
46
- it 'exceeds throttle when other jobs are running' do
47
- job1 = ThrottleJob.new
48
- job1.start!
49
- job2 = ThrottleJob.new
50
- assert job2.send(:throttle_running_jobs_exceeded?)
51
- end
52
-
53
- it 'excludes paused jobs' do
54
- job1 = ThrottleJob.new
55
- job1.start
56
- job1.pause!
57
- job2 = ThrottleJob.new
58
- refute job2.send(:throttle_running_jobs_exceeded?)
59
- end
60
-
61
- it 'excludes failed jobs' do
62
- job1 = ThrottleJob.new
63
- job1.start
64
- job1.fail!
65
- job2 = ThrottleJob.new
66
- refute job2.send(:throttle_running_jobs_exceeded?)
67
- end
68
- end
69
-
70
- describe '.rocket_job_next_job' do
71
- before do
72
- @worker_name = 'worker:123'
73
- end
74
-
75
- after do
76
- @job.destroy if @job && !@job.new_record?
77
- end
78
-
79
- it 'return nil when no jobs available' do
80
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name)
81
- end
82
-
83
- it 'return the job when others are queued, paused, failed, or complete' do
84
- @job = ThrottleJob.create!
85
- ThrottleJob.create!(state: :failed)
86
- ThrottleJob.create!(state: :complete)
87
- ThrottleJob.create!(state: :paused)
88
- assert job = RocketJob::Job.rocket_job_next_job(@worker_name), -> { ThrottleJob.all.to_a.ai }
89
- assert_equal @job.id, job.id, -> { ThrottleJob.all.to_a.ai }
90
- end
91
-
92
- it 'return nil when other jobs are running' do
93
- ThrottleJob.create!
94
- @job = ThrottleJob.new
95
- @job.start!
96
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name), -> { ThrottleJob.all.to_a.ai }
97
- end
98
-
99
- it 'add job to filter when other jobs are running' do
100
- ThrottleJob.create!
101
- @job = ThrottleJob.new
102
- @job.start!
103
- filter = {}
104
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name, filter), -> { ThrottleJob.all.to_a.ai }
105
- assert_equal 1, filter.size
106
- end
107
- end
108
- end
109
- end
110
- end
111
- end
@@ -1,199 +0,0 @@
1
- require_relative '../../test_helper'
2
-
3
- module Plugins
4
- module Job
5
- # Unit Test for RocketJob::Job
6
- class WorkerTest < Minitest::Test
7
- class QuietJob < RocketJob::Job
8
- # Test increasing log level for debugging purposes
9
- def perform
10
- logger.trace 'enable tracing level for just the job instance'
11
- end
12
- end
13
-
14
- class NoisyJob < RocketJob::Job
15
- # Test silencing noisy logging
16
- def perform
17
- logger.info 'some very noisy logging'
18
- end
19
- end
20
-
21
- class SumJob < RocketJob::Job
22
- self.destroy_on_complete = false
23
- self.collect_output = true
24
- self.priority = 51
25
-
26
- field :first, type: Integer
27
- field :second, type: Integer
28
-
29
- def perform
30
- first + second
31
- end
32
- end
33
-
34
- describe RocketJob::Plugins::Job::Worker do
35
- before do
36
- RocketJob::Job.delete_all
37
- RocketJob::Server.delete_all
38
- end
39
-
40
- after do
41
- @job.destroy if @job && !@job.new_record?
42
- end
43
-
44
- describe '.rocket_job_next_job' do
45
- before do
46
- @job = QuietJob.new
47
- @worker_name = 'worker:123'
48
- end
49
-
50
- it 'return nil when no jobs available' do
51
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name)
52
- end
53
-
54
- it 'return the first job' do
55
- @job.save!
56
- assert job = RocketJob::Job.rocket_job_next_job(@worker_name), 'Failed to find job'
57
- assert_equal @job.id, job.id
58
- end
59
-
60
- it 'Ignore future dated jobs' do
61
- @job.run_at = Time.now + 1.hour
62
- @job.save!
63
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name)
64
- end
65
-
66
- it 'Process future dated jobs when time is now' do
67
- @job.run_at = Time.now
68
- @job.save!
69
- assert job = RocketJob::Job.rocket_job_next_job(@worker_name), 'Failed to find future job'
70
- assert_equal @job.id, job.id
71
- end
72
-
73
- it 'Skip expired jobs' do
74
- count = RocketJob::Job.count
75
- @job.expires_at = Time.now - 100
76
- @job.save!
77
- assert_nil RocketJob::Job.rocket_job_next_job(@worker_name)
78
- assert_equal count, RocketJob::Job.count
79
- end
80
- end
81
-
82
- describe '#perform_now' do
83
- it 'calls perform method' do
84
- @job = SumJob.new(first: 10, second: 5)
85
- assert_equal 15, @job.perform_now['result']
86
- assert @job.completed?, @job.attributes.ai
87
- assert_equal 15, @job.result['result']
88
- end
89
-
90
- it 'converts type' do
91
- @job = SumJob.new(first: '10', second: 5)
92
- assert_equal 15, @job.perform_now['result']
93
- assert @job.completed?, @job.attributes.ai
94
- assert_equal 15, @job.result['result']
95
- end
96
-
97
- it 'silence logging when log_level is set' do
98
- @job = NoisyJob.new
99
- @job.log_level = :warn
100
- logged = false
101
- @job.logger.stub(:log_internal, ->(_level, _index, message, _payload, _exception) { logged = true if message.include?('some very noisy logging') }) do
102
- @job.perform_now
103
- end
104
- assert_equal false, logged
105
- end
106
-
107
- it 'raise logging when log_level is set' do
108
- @job = QuietJob.new
109
- @job.log_level = :trace
110
- logged = false
111
- # Raise global log level to :info
112
- SemanticLogger.stub(:default_level_index, 3) do
113
- @job.logger.stub(:log_internal, -> { logged = true }) do
114
- @job.perform_now
115
- end
116
- end
117
- assert_equal false, logged
118
- end
119
- end
120
-
121
- describe '.perform_later' do
122
- it 'queues the job for processing' do
123
- RocketJob::Config.stub(:inline_mode, false) do
124
- @job = SumJob.perform_later(first: 1, second: 23)
125
- end
126
- assert @job.queued?
127
-
128
- # Manually run the job
129
- @job.perform_now
130
- assert @job.completed?, @job.attributes.ai
131
- assert_equal 24, @job.result['result'], -> { @job.result.ai }
132
-
133
- assert_nil @job.worker_name
134
- assert @job.completed_at
135
- assert @job.created_at
136
- assert_equal false, @job.destroy_on_complete
137
- assert_nil @job.expires_at
138
- assert_equal 100, @job.percent_complete
139
- assert_equal 51, @job.priority
140
- assert_equal 0, @job.failure_count
141
- assert_nil @job.run_at
142
- assert @job.started_at
143
- end
144
-
145
- it 'runs the job immediately when inline_mode = true' do
146
- RocketJob::Config.stub(:inline_mode, true) do
147
- @job = SumJob.perform_later(first: 1, second: 23)
148
- end
149
-
150
- assert @job.completed?, @job.attributes.ai
151
- assert_equal 24, @job.result['result']
152
-
153
- assert_nil @job.worker_name
154
- assert @job.completed_at
155
- assert @job.created_at
156
- assert_equal false, @job.destroy_on_complete
157
- assert_nil @job.expires_at
158
- assert_equal 100, @job.percent_complete
159
- assert_equal 51, @job.priority
160
- assert_equal 0, @job.failure_count
161
- assert_nil @job.run_at
162
- assert @job.started_at
163
- end
164
- end
165
-
166
- describe '.perform_now' do
167
- it 'run the job immediately' do
168
- @job = SumJob.perform_now(first: 1, second: 5)
169
- assert_equal true, @job.completed?
170
- assert_equal 6, @job.result['result']
171
- end
172
- end
173
-
174
- describe '#rocket_job_active_workers' do
175
- before do
176
- @job = QuietJob.create!
177
- @worker_name = 'worker:123'
178
- end
179
-
180
- it 'should return empty hash for no active jobs' do
181
- assert_equal([], @job.rocket_job_active_workers)
182
- end
183
-
184
- it 'should return active servers' do
185
- assert job = RocketJob::Job.rocket_job_next_job(@worker_name)
186
- assert active = job.rocket_job_active_workers
187
- assert_equal 1, active.size
188
- assert active_worker = active.first
189
- assert_equal @job.id, active_worker.job.id
190
- assert_equal @worker_name, active_worker.name
191
- assert_equal job.started_at, active_worker.started_at
192
- assert active_worker.duration_s
193
- assert active_worker.duration
194
- end
195
- end
196
- end
197
- end
198
- end
199
- end
@@ -1,109 +0,0 @@
1
- require_relative '../test_helper'
2
-
3
- # Unit Test for RocketJob::Job
4
- module Plugins
5
- class ProcessingWindowTest < Minitest::Test
6
- class ProcessingWindowJob < RocketJob::Job
7
- include RocketJob::Plugins::ProcessingWindow
8
-
9
- def perform
10
- 'DONE'
11
- end
12
- end
13
-
14
- describe RocketJob::Plugins::ProcessingWindow do
15
- before do
16
- # destroy_all could create new instances
17
- ProcessingWindowJob.delete_all
18
- assert_equal 0, ProcessingWindowJob.count
19
- end
20
-
21
- after do
22
- @job.destroy if @job && !@job.new_record?
23
- ProcessingWindowJob.delete_all
24
- end
25
-
26
- describe '#create!' do
27
- it 'queues a new job' do
28
- @job = ProcessingWindowJob.create!(processing_schedule: '* 1 * * *', processing_duration: 1.hour)
29
- assert @job.valid?
30
- refute @job.new_record?
31
- end
32
-
33
- describe 'timezones are supported' do
34
- it 'handles UTC' do
35
- time = Time.parse('2015-12-09 17:50:05 UTC')
36
- Time.stub(:now, time) do
37
- @job = ProcessingWindowJob.create!(processing_schedule: '* 1 * * * UTC', processing_duration: 1.hour)
38
- end
39
- assert @job.valid?
40
- refute @job.new_record?
41
- assert_equal Time.parse('2015-12-10 01:00:00 UTC'), @job.run_at
42
- end
43
-
44
- it 'handles Eastern' do
45
- time = Time.parse('2015-12-09 17:50:05 UTC')
46
- Time.stub(:now, time) do
47
- @job = ProcessingWindowJob.create!(processing_schedule: '* 1 * * * America/New_York', processing_duration: 1.hour)
48
- end
49
- assert @job.valid?
50
- refute @job.new_record?
51
- assert_equal Time.parse('2015-12-10 06:00:00 UTC'), @job.run_at
52
- end
53
- end
54
- end
55
-
56
- describe '#rocket_job_processing_window_active?' do
57
- it 'returns true when in the processing window' do
58
- time = Time.parse('2015-12-09 17:50:05 UTC')
59
- @job = ProcessingWindowJob.new(processing_schedule: '* 17 * * * UTC', processing_duration: 1.hour)
60
- result = Time.stub(:now, time) do
61
- @job.rocket_job_processing_window_active?
62
- end
63
- assert result, @job.attributes.ai
64
- end
65
-
66
- it 'returns false when not in the processing window' do
67
- time = Time.parse('2015-12-09 16:50:05 UTC')
68
- @job = ProcessingWindowJob.new(processing_schedule: '* 17 * * * UTC', processing_duration: 1.hour)
69
- result = Time.stub(:now, time) do
70
- @job.rocket_job_processing_window_active?
71
- end
72
- refute result, @job.attributes.ai
73
- end
74
- end
75
-
76
- describe '#valid?' do
77
- it 'fails on missing processing_schedule' do
78
- @job = ProcessingWindowJob.new
79
- refute @job.valid?
80
- assert_equal "can't be blank", @job.errors.messages[:processing_schedule].first
81
- assert_equal 'not a string: nil', @job.errors.messages[:processing_schedule].second
82
- assert_equal "can't be blank", @job.errors.messages[:processing_duration].first
83
- end
84
-
85
- it 'fails on bad cron schedule' do
86
- @job = ProcessingWindowJob.new(processing_schedule: 'blah')
87
- refute @job.valid?
88
- assert_equal "not a valid cronline : 'blah'", @job.errors.messages[:processing_schedule].first
89
- end
90
-
91
- it 'passes on valid cron schedule' do
92
- @job = ProcessingWindowJob.new(processing_schedule: '* 1 * * *', processing_duration: 1.hour)
93
- assert @job.valid?
94
- end
95
- end
96
-
97
- describe 're-queue' do
98
- it 'if outside processing window' do
99
- time = Time.parse('2015-12-09 16:50:05 UTC')
100
- Time.stub(:now, time) do
101
- @job = ProcessingWindowJob.new(processing_schedule: '* 17 * * * UTC', processing_duration: 1.hour)
102
- @job.perform_now
103
- end
104
- assert @job.queued?, @job.attributes.ai
105
- end
106
- end
107
- end
108
- end
109
- end