rocketjob 5.1.1 → 5.2.0.beta1
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 +4 -4
- data/bin/rocketjob +2 -2
- data/bin/rocketjob_batch_perf +1 -1
- data/bin/rocketjob_perf +1 -1
- data/lib/rocket_job/active_worker.rb +1 -0
- data/lib/rocket_job/batch.rb +16 -17
- data/lib/rocket_job/batch/callbacks.rb +1 -2
- data/lib/rocket_job/batch/io.rb +10 -6
- data/lib/rocket_job/batch/logger.rb +2 -2
- data/lib/rocket_job/batch/lower_priority.rb +2 -2
- data/lib/rocket_job/batch/model.rb +23 -23
- data/lib/rocket_job/batch/performance.rb +19 -21
- data/lib/rocket_job/batch/result.rb +1 -1
- data/lib/rocket_job/batch/results.rb +1 -1
- data/lib/rocket_job/batch/state_machine.rb +5 -6
- data/lib/rocket_job/batch/statistics.rb +10 -8
- data/lib/rocket_job/batch/tabular.rb +2 -2
- data/lib/rocket_job/batch/tabular/input.rb +11 -7
- data/lib/rocket_job/batch/tabular/output.rb +1 -1
- data/lib/rocket_job/batch/throttle.rb +11 -30
- data/lib/rocket_job/batch/{throttle_running_slices.rb → throttle_running_workers.rb} +13 -10
- data/lib/rocket_job/batch/worker.rb +102 -85
- data/lib/rocket_job/cli.rb +57 -54
- data/lib/rocket_job/config.rb +8 -10
- data/lib/rocket_job/dirmon_entry.rb +13 -10
- data/lib/rocket_job/event.rb +16 -16
- data/lib/rocket_job/extensions/mongo/logging.rb +2 -2
- data/lib/rocket_job/extensions/mongoid/clients/options.rb +2 -2
- data/lib/rocket_job/extensions/mongoid/contextual/mongo.rb +4 -2
- data/lib/rocket_job/extensions/mongoid/factory.rb +13 -5
- data/lib/rocket_job/extensions/rocket_job_adapter.rb +2 -1
- data/lib/rocket_job/job_exception.rb +0 -3
- data/lib/rocket_job/jobs/dirmon_job.rb +4 -4
- data/lib/rocket_job/jobs/housekeeping_job.rb +7 -7
- data/lib/rocket_job/jobs/on_demand_batch_job.rb +14 -4
- data/lib/rocket_job/jobs/on_demand_job.rb +3 -3
- data/lib/rocket_job/jobs/performance_job.rb +1 -1
- data/lib/rocket_job/jobs/re_encrypt/relational_job.rb +11 -10
- data/lib/rocket_job/jobs/upload_file_job.rb +9 -5
- data/lib/rocket_job/performance.rb +24 -22
- data/lib/rocket_job/plugins/cron.rb +7 -3
- data/lib/rocket_job/plugins/document.rb +7 -5
- data/lib/rocket_job/plugins/job/callbacks.rb +1 -1
- data/lib/rocket_job/plugins/job/logger.rb +3 -3
- data/lib/rocket_job/plugins/job/model.rb +34 -27
- data/lib/rocket_job/plugins/job/persistence.rb +7 -34
- data/lib/rocket_job/plugins/job/state_machine.rb +5 -4
- data/lib/rocket_job/plugins/job/throttle.rb +12 -28
- data/lib/rocket_job/plugins/job/throttle_running_jobs.rb +2 -2
- data/lib/rocket_job/plugins/job/worker.rb +22 -70
- data/lib/rocket_job/plugins/processing_window.rb +5 -4
- data/lib/rocket_job/plugins/restart.rb +3 -3
- data/lib/rocket_job/plugins/retry.rb +2 -2
- data/lib/rocket_job/plugins/singleton.rb +1 -2
- data/lib/rocket_job/plugins/state_machine.rb +4 -4
- data/lib/rocket_job/plugins/transaction.rb +1 -1
- data/lib/rocket_job/rocket_job.rb +5 -4
- data/lib/rocket_job/server.rb +2 -2
- data/lib/rocket_job/server/model.rb +14 -13
- data/lib/rocket_job/server/state_machine.rb +1 -2
- data/lib/rocket_job/sliced/compressed_slice.rb +4 -4
- data/lib/rocket_job/sliced/encrypted_slice.rb +4 -4
- data/lib/rocket_job/sliced/input.rb +16 -16
- data/lib/rocket_job/sliced/output.rb +2 -2
- data/lib/rocket_job/sliced/slice.rb +43 -20
- data/lib/rocket_job/sliced/slices.rb +14 -11
- data/lib/rocket_job/subscriber.rb +6 -6
- data/lib/rocket_job/subscribers/logger.rb +3 -3
- data/lib/rocket_job/supervisor.rb +12 -12
- data/lib/rocket_job/supervisor/shutdown.rb +7 -7
- data/lib/rocket_job/throttle_definition.rb +37 -0
- data/lib/rocket_job/throttle_definitions.rb +39 -0
- data/lib/rocket_job/version.rb +1 -1
- data/lib/rocket_job/worker.rb +116 -34
- data/lib/rocket_job/worker_pool.rb +6 -6
- data/lib/rocketjob.rb +72 -76
- metadata +16 -18
- data/lib/rocket_job/extensions/mongoid_5/clients/options.rb +0 -38
- data/lib/rocket_job/extensions/mongoid_5/contextual/mongo.rb +0 -64
- data/lib/rocket_job/extensions/mongoid_5/factory.rb +0 -13
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
module RocketJob
|
4
4
|
module Plugins
|
@@ -8,27 +8,29 @@ module RocketJob
|
|
8
8
|
include ::Mongoid::Document
|
9
9
|
|
10
10
|
included do
|
11
|
-
store_in client:
|
11
|
+
store_in client: "rocketjob"
|
12
12
|
end
|
13
13
|
|
14
|
+
# rubocop:disable Style/RedundantSort
|
14
15
|
module ClassMethods
|
15
16
|
# Mongoid does not apply ordering, add sort
|
16
17
|
def first
|
17
|
-
all.sort(
|
18
|
+
all.sort("_id" => 1).first
|
18
19
|
end
|
19
20
|
|
20
21
|
# Mongoid does not apply ordering, add sort
|
21
22
|
def last
|
22
|
-
all.sort(
|
23
|
+
all.sort("_id" => -1).first
|
23
24
|
end
|
24
25
|
end
|
26
|
+
# rubocop:enable Style/RedundantSort
|
25
27
|
|
26
28
|
private
|
27
29
|
|
28
30
|
# Apply changes to this document returning the updated document from the database.
|
29
31
|
# Allows other changes to be made on the server that will be loaded.
|
30
32
|
def find_and_update(attrs)
|
31
|
-
doc = collection.find(_id: id).find_one_and_update({
|
33
|
+
doc = collection.find(_id: id).find_one_and_update({"$set" => attrs}, return_document: :after)
|
32
34
|
raise(::Mongoid::Errors::DocumentNotFound.new(self.class, id)) unless doc
|
33
35
|
|
34
36
|
# Clear out keys that are not returned during the reload from MongoDB
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
module RocketJob
|
4
4
|
module Plugins
|
@@ -18,9 +18,9 @@ module RocketJob
|
|
18
18
|
# - on_exception_level changes log level from info to error on exception
|
19
19
|
# - silence noisy jobs by raising log level
|
20
20
|
def rocket_job_around_logger(&block)
|
21
|
-
logger.info(
|
21
|
+
logger.info("Start #perform")
|
22
22
|
logger.measure_info(
|
23
|
-
|
23
|
+
"Completed #perform",
|
24
24
|
metric: "#{self.class.name}/perform",
|
25
25
|
log_exception: :full,
|
26
26
|
on_exception_level: :error,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
module RocketJob
|
4
4
|
module Plugins
|
@@ -87,7 +87,7 @@ module RocketJob
|
|
87
87
|
field :percent_complete, type: Integer, default: 0
|
88
88
|
|
89
89
|
# Store the last exception for this job
|
90
|
-
embeds_one :exception, class_name:
|
90
|
+
embeds_one :exception, class_name: "RocketJob::JobException"
|
91
91
|
|
92
92
|
# Store the Hash result from this job if collect_output is true,
|
93
93
|
# and the job returned actually returned a Hash, otherwise nil
|
@@ -110,7 +110,7 @@ module RocketJob
|
|
110
110
|
# job.underscore_name
|
111
111
|
# # => "data_study"
|
112
112
|
def underscore_name
|
113
|
-
@underscore_name ||= name.sub(/Job$/,
|
113
|
+
@underscore_name ||= name.sub(/Job$/, "").underscore
|
114
114
|
end
|
115
115
|
|
116
116
|
# Allow the collective name for this job class to be overridden
|
@@ -125,7 +125,7 @@ module RocketJob
|
|
125
125
|
# job.human_name
|
126
126
|
# # => "Data Study"
|
127
127
|
def human_name
|
128
|
-
@human_name ||= name.sub(/Job$/,
|
128
|
+
@human_name ||= name.sub(/Job$/, "").titleize
|
129
129
|
end
|
130
130
|
|
131
131
|
# Allow the human readable job name for this job class to be overridden
|
@@ -140,7 +140,7 @@ module RocketJob
|
|
140
140
|
# job.collective_name
|
141
141
|
# # => "data_studies"
|
142
142
|
def collective_name
|
143
|
-
@collective_name ||= name.sub(/Job$/,
|
143
|
+
@collective_name ||= name.sub(/Job$/, "").pluralize.underscore
|
144
144
|
end
|
145
145
|
|
146
146
|
# Allow the collective name for this job class to be overridden
|
@@ -155,8 +155,14 @@ module RocketJob
|
|
155
155
|
|
156
156
|
# Scope for queued jobs that can run now
|
157
157
|
# I.e. Queued jobs excluding scheduled jobs
|
158
|
-
|
159
|
-
|
158
|
+
if Mongoid::VERSION.to_f >= 7.1
|
159
|
+
def queued_now
|
160
|
+
queued.and(RocketJob::Job.where(run_at: nil).or(:run_at.lte => Time.now))
|
161
|
+
end
|
162
|
+
else
|
163
|
+
def queued_now
|
164
|
+
queued.or({run_at: nil}, :run_at.lte => Time.now)
|
165
|
+
end
|
160
166
|
end
|
161
167
|
|
162
168
|
# Defines all the fields that are accessible on the Document
|
@@ -193,7 +199,7 @@ module RocketJob
|
|
193
199
|
|
194
200
|
# DEPRECATED
|
195
201
|
def rocket_job
|
196
|
-
warn
|
202
|
+
warn "Replace calls to .rocket_job with calls to set class instance variables. For example: self.priority = 50"
|
197
203
|
yield(self)
|
198
204
|
end
|
199
205
|
|
@@ -276,42 +282,42 @@ module RocketJob
|
|
276
282
|
# Returns [Hash] status of this job
|
277
283
|
def as_json
|
278
284
|
attrs = serializable_hash(methods: %i[seconds duration])
|
279
|
-
attrs.delete(
|
280
|
-
attrs.delete(
|
285
|
+
attrs.delete("result") unless collect_output?
|
286
|
+
attrs.delete("failure_count") unless failure_count.positive?
|
281
287
|
if queued?
|
282
|
-
attrs.delete(
|
283
|
-
attrs.delete(
|
284
|
-
attrs.delete(
|
288
|
+
attrs.delete("started_at")
|
289
|
+
attrs.delete("completed_at")
|
290
|
+
attrs.delete("result")
|
285
291
|
attrs
|
286
292
|
elsif running?
|
287
|
-
attrs.delete(
|
288
|
-
attrs.delete(
|
293
|
+
attrs.delete("completed_at")
|
294
|
+
attrs.delete("result")
|
289
295
|
attrs
|
290
296
|
elsif completed?
|
291
|
-
attrs.delete(
|
297
|
+
attrs.delete("percent_complete")
|
292
298
|
attrs
|
293
299
|
elsif paused?
|
294
|
-
attrs.delete(
|
295
|
-
attrs.delete(
|
300
|
+
attrs.delete("completed_at")
|
301
|
+
attrs.delete("result")
|
296
302
|
# Ensure 'paused_at' appears first in the hash
|
297
|
-
{
|
303
|
+
{"paused_at" => completed_at}.merge(attrs)
|
298
304
|
elsif aborted?
|
299
|
-
attrs.delete(
|
300
|
-
attrs.delete(
|
301
|
-
{
|
305
|
+
attrs.delete("completed_at")
|
306
|
+
attrs.delete("result")
|
307
|
+
{"aborted_at" => completed_at}.merge(attrs)
|
302
308
|
elsif failed?
|
303
|
-
attrs.delete(
|
304
|
-
attrs.delete(
|
305
|
-
{
|
309
|
+
attrs.delete("completed_at")
|
310
|
+
attrs.delete("result")
|
311
|
+
{"failed_at" => completed_at}.merge(attrs)
|
306
312
|
else
|
307
313
|
attrs
|
308
314
|
end
|
309
315
|
end
|
310
316
|
|
311
317
|
# Returns [Hash] the status of this job
|
312
|
-
def status(time_zone =
|
318
|
+
def status(time_zone = "Eastern Time (US & Canada)")
|
313
319
|
h = as_json
|
314
|
-
h.delete(
|
320
|
+
h.delete("seconds")
|
315
321
|
h.dup.each_pair do |k, v|
|
316
322
|
if v.is_a?(Time)
|
317
323
|
h[k] = v.in_time_zone(time_zone).to_s
|
@@ -325,6 +331,7 @@ module RocketJob
|
|
325
331
|
# Returns [Boolean] whether the worker runs on a particular server.
|
326
332
|
def worker_on_server?(server_name)
|
327
333
|
return false unless worker_name.present? && server_name.present?
|
334
|
+
|
328
335
|
worker_name.start_with?(server_name)
|
329
336
|
end
|
330
337
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
module RocketJob
|
4
4
|
module Plugins
|
@@ -9,38 +9,10 @@ module RocketJob
|
|
9
9
|
|
10
10
|
included do
|
11
11
|
# Store all job types in this collection
|
12
|
-
store_in collection:
|
12
|
+
store_in collection: "rocket_job.jobs"
|
13
13
|
end
|
14
14
|
|
15
15
|
module ClassMethods
|
16
|
-
# Retrieves the next job to work on in priority based order
|
17
|
-
# and assigns it to this worker
|
18
|
-
#
|
19
|
-
# Returns nil if no jobs are available for processing
|
20
|
-
#
|
21
|
-
# Parameters
|
22
|
-
# worker_name: [String]
|
23
|
-
# Name of the worker that will be processing this job
|
24
|
-
#
|
25
|
-
# filter: [Hash]
|
26
|
-
# Filter to apply to the query.
|
27
|
-
# For example: to exclude jobs from being returned.
|
28
|
-
#
|
29
|
-
# Example:
|
30
|
-
# # Skip any job ids from the job_ids_list
|
31
|
-
# filter = {:id.nin => job_ids_list}
|
32
|
-
# job = RocketJob::Job.rocket_job_retrieve('host:pid:worker', filter)
|
33
|
-
def rocket_job_retrieve(worker_name, filter)
|
34
|
-
SemanticLogger.silence(:info) do
|
35
|
-
scheduled = {'$or' => [{run_at: nil}, {:run_at.lte => Time.now}]}
|
36
|
-
working = {'$or' => [{state: :queued}, {state: :running, sub_state: :processing}]}
|
37
|
-
query = self.and(working, scheduled)
|
38
|
-
query = query.where(filter) unless filter.blank?
|
39
|
-
update = {'$set' => {'worker_name' => worker_name, 'state' => 'running'}}
|
40
|
-
query.sort(priority: 1, _id: 1).find_one_and_update(update, bypass_document_validation: true)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
16
|
# Returns [Hash<String:Integer>] of the number of jobs in each state
|
45
17
|
# Queued jobs are separated into :queued_now and :scheduled
|
46
18
|
# :queued_now are jobs that are awaiting processing and can be processed now.
|
@@ -73,14 +45,14 @@ module RocketJob
|
|
73
45
|
collection.aggregate(
|
74
46
|
[
|
75
47
|
{
|
76
|
-
|
77
|
-
_id:
|
78
|
-
count: {
|
48
|
+
"$group" => {
|
49
|
+
_id: "$state",
|
50
|
+
count: {"$sum" => 1}
|
79
51
|
}
|
80
52
|
}
|
81
53
|
]
|
82
54
|
).each do |result|
|
83
|
-
counts[result[
|
55
|
+
counts[result["_id"].to_sym] = result["count"]
|
84
56
|
end
|
85
57
|
|
86
58
|
# Calculate :queued_now and :scheduled if there are queued jobs
|
@@ -101,6 +73,7 @@ module RocketJob
|
|
101
73
|
# Set in-memory job to complete if `destroy_on_complete` and the job has been destroyed
|
102
74
|
def reload
|
103
75
|
return super unless destroy_on_complete
|
76
|
+
|
104
77
|
begin
|
105
78
|
super
|
106
79
|
rescue ::Mongoid::Errors::DocumentNotFound
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
module RocketJob
|
4
4
|
module Plugins
|
@@ -126,7 +126,7 @@ module RocketJob
|
|
126
126
|
exception.worker_name = worker_name
|
127
127
|
else
|
128
128
|
build_exception(
|
129
|
-
class_name:
|
129
|
+
class_name: "RocketJob::JobException",
|
130
130
|
message: exc_or_message,
|
131
131
|
backtrace: [],
|
132
132
|
worker_name: worker_name
|
@@ -134,8 +134,9 @@ module RocketJob
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
-
def rocket_job_set_started_at
|
138
|
-
self.started_at
|
137
|
+
def rocket_job_set_started_at(worker_name = nil)
|
138
|
+
self.started_at = Time.now
|
139
|
+
self.worker_name = worker_name if worker_name
|
139
140
|
end
|
140
141
|
|
141
142
|
def rocket_job_mark_complete
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
module RocketJob
|
4
4
|
module Plugins
|
@@ -30,7 +30,6 @@ module RocketJob
|
|
30
30
|
|
31
31
|
included do
|
32
32
|
class_attribute :rocket_job_throttles
|
33
|
-
self.rocket_job_throttles = []
|
34
33
|
end
|
35
34
|
|
36
35
|
module ClassMethods
|
@@ -40,6 +39,7 @@ module RocketJob
|
|
40
39
|
# method_name: [Symbol]
|
41
40
|
# Name of method to call to evaluate whether a throttle has been exceeded.
|
42
41
|
# Note: Must return true or false.
|
42
|
+
#
|
43
43
|
# filter: [Symbol|Proc]
|
44
44
|
# Name of method to call to return the filter when the throttle has been exceeded.
|
45
45
|
# Or, a block that will return the filter.
|
@@ -47,24 +47,24 @@ module RocketJob
|
|
47
47
|
#
|
48
48
|
# Note: Throttles are executed in the order they are defined.
|
49
49
|
def define_throttle(method_name, filter: :throttle_filter_class)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
raise(ArgumentError, "Cannot define #{method_name} twice, undefine previous throttle first")
|
55
|
-
end
|
56
|
-
|
57
|
-
self.rocket_job_throttles += [ThrottleDefinition.new(method_name, filter)]
|
50
|
+
# Duplicate to prevent modifying parent class throttles
|
51
|
+
definitions = rocket_job_throttles ? rocket_job_throttles.dup : ThrottleDefinitions.new
|
52
|
+
definitions.add(method_name, filter)
|
53
|
+
self.rocket_job_throttles = definitions
|
58
54
|
end
|
59
55
|
|
60
56
|
# Undefine a previously defined throttle
|
61
57
|
def undefine_throttle(method_name)
|
62
|
-
|
58
|
+
return unless rocket_job_throttles
|
59
|
+
|
60
|
+
definitions = rocket_job_throttles.dup
|
61
|
+
definitions.remove(method_name)
|
62
|
+
self.rocket_job_throttles = definitions
|
63
63
|
end
|
64
64
|
|
65
65
|
# Has a throttle been defined?
|
66
66
|
def throttle?(method_name)
|
67
|
-
rocket_job_throttles
|
67
|
+
rocket_job_throttles&.exist?(method_name)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -81,22 +81,6 @@ module RocketJob
|
|
81
81
|
def throttle_filter_id
|
82
82
|
{:id.nin => [id]}
|
83
83
|
end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
ThrottleDefinition = Struct.new(:method_name, :filter)
|
88
|
-
|
89
|
-
# Returns the matching filter, or nil if no throttles were triggered.
|
90
|
-
def rocket_job_evaluate_throttles
|
91
|
-
rocket_job_throttles.each do |throttle|
|
92
|
-
# Throttle exceeded?
|
93
|
-
next unless send(throttle.method_name)
|
94
|
-
logger.debug { "Throttle: #{throttle.method_name} has been exceeded. #{self.class.name}:#{id}" }
|
95
|
-
filter = throttle.filter
|
96
|
-
return filter.is_a?(Proc) ? filter.call(self) : send(filter)
|
97
|
-
end
|
98
|
-
nil
|
99
|
-
end
|
100
84
|
end
|
101
85
|
end
|
102
86
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
module RocketJob
|
4
4
|
module Plugins
|
@@ -40,7 +40,7 @@ module RocketJob
|
|
40
40
|
|
41
41
|
# Cannot use this class since it will include instances of parent job classes.
|
42
42
|
RocketJob::Job.with(read: {mode: :primary}) do |conn|
|
43
|
-
conn.running.where(
|
43
|
+
conn.running.where("_type" => self.class.name, :id.ne => id).count >= throttle_running_jobs
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/concern"
|
2
2
|
|
3
3
|
# Worker behavior for a job
|
4
4
|
module RocketJob
|
@@ -23,41 +23,6 @@ module RocketJob
|
|
23
23
|
job
|
24
24
|
end
|
25
25
|
|
26
|
-
# Returns the next job to work on in priority based order
|
27
|
-
# Returns nil if there are currently no queued jobs, or processing batch jobs
|
28
|
-
# with records that require processing
|
29
|
-
#
|
30
|
-
# Parameters
|
31
|
-
# worker_name [String]
|
32
|
-
# Name of the worker that will be processing this job
|
33
|
-
#
|
34
|
-
# skip_job_ids [Array<BSON::ObjectId>]
|
35
|
-
# Job ids to exclude when looking for the next job
|
36
|
-
#
|
37
|
-
# Note:
|
38
|
-
# If a job is in queued state it will be started
|
39
|
-
def rocket_job_next_job(worker_name, filter = {})
|
40
|
-
while (job = rocket_job_retrieve(worker_name, filter))
|
41
|
-
# Batch Job?
|
42
|
-
return job if job.running?
|
43
|
-
|
44
|
-
if job.expired?
|
45
|
-
job.rocket_job_fail_on_exception!(worker_name) { job.destroy }
|
46
|
-
logger.info "Destroyed expired job #{job.class.name}, id:#{job.id}"
|
47
|
-
elsif (new_filter = job.send(:rocket_job_evaluate_throttles))
|
48
|
-
rocket_job_merge_filter(filter, new_filter)
|
49
|
-
# Restore retrieved job so that other workers can process it later
|
50
|
-
job.set(worker_name: nil, state: :queued)
|
51
|
-
else
|
52
|
-
job.worker_name = worker_name
|
53
|
-
job.rocket_job_fail_on_exception!(worker_name) do
|
54
|
-
job.start!
|
55
|
-
end
|
56
|
-
return job if job.running?
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
26
|
# Requeues all jobs that were running on a server that died
|
62
27
|
def requeue_dead_server(server_name)
|
63
28
|
# Need to requeue paused, failed since user may have transitioned job before it finished
|
@@ -67,20 +32,6 @@ module RocketJob
|
|
67
32
|
end
|
68
33
|
end
|
69
34
|
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def rocket_job_merge_filter(target, source)
|
74
|
-
source.each_pair do |k, v|
|
75
|
-
target[k] =
|
76
|
-
if (previous = target[k])
|
77
|
-
v.is_a?(Array) ? previous + v : v
|
78
|
-
else
|
79
|
-
v
|
80
|
-
end
|
81
|
-
end
|
82
|
-
target
|
83
|
-
end
|
84
35
|
end
|
85
36
|
|
86
37
|
# Runs the job now in the current thread.
|
@@ -112,38 +63,38 @@ module RocketJob
|
|
112
63
|
#
|
113
64
|
# The job is automatically saved only if an exception is raised in the supplied block.
|
114
65
|
#
|
115
|
-
# worker_name: [String]
|
116
|
-
# Name of the server on which the exception has occurred
|
117
|
-
#
|
118
66
|
# re_raise_exceptions: [true|false]
|
119
67
|
# Re-raise the exception after updating the job
|
120
68
|
# Default: false
|
121
|
-
def
|
122
|
-
|
123
|
-
rescue Exception =>
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
69
|
+
def fail_on_exception!(re_raise_exceptions = false, &block)
|
70
|
+
SemanticLogger.named_tagged(job: id.to_s, &block)
|
71
|
+
rescue Exception => e
|
72
|
+
SemanticLogger.named_tagged(job: id.to_s) do
|
73
|
+
if failed? || !may_fail?
|
74
|
+
self.exception = JobException.from_exception(e)
|
75
|
+
exception.worker_name = worker_name
|
76
|
+
save! unless new_record? || destroyed?
|
77
|
+
elsif new_record? || destroyed?
|
78
|
+
fail(worker_name, e)
|
79
|
+
else
|
80
|
+
fail!(worker_name, e)
|
81
|
+
end
|
82
|
+
raise e if re_raise_exceptions
|
132
83
|
end
|
133
|
-
raise exc if re_raise_exceptions
|
134
84
|
end
|
135
85
|
|
136
86
|
# Works on this job
|
137
87
|
#
|
138
|
-
# Returns [true|false] whether
|
88
|
+
# Returns [true|false] whether any work was performed.
|
139
89
|
#
|
140
90
|
# If an exception is thrown the job is marked as failed and the exception
|
141
91
|
# is set in the job itself.
|
142
92
|
#
|
143
93
|
# Thread-safe, can be called by multiple threads at the same time
|
144
|
-
def rocket_job_work(
|
145
|
-
raise(ArgumentError,
|
146
|
-
|
94
|
+
def rocket_job_work(_worker, re_raise_exceptions = false)
|
95
|
+
raise(ArgumentError, "Job must be started before calling #rocket_job_work") unless running?
|
96
|
+
|
97
|
+
fail_on_exception!(re_raise_exceptions) do
|
147
98
|
if _perform_callbacks.empty?
|
148
99
|
@rocket_job_output = perform
|
149
100
|
else
|
@@ -156,7 +107,7 @@ module RocketJob
|
|
156
107
|
|
157
108
|
if collect_output?
|
158
109
|
# Result must be a Hash, if not put it in a Hash
|
159
|
-
self.result = @rocket_job_output.is_a?(Hash) ? @rocket_job_output : {
|
110
|
+
self.result = @rocket_job_output.is_a?(Hash) ? @rocket_job_output : {"result" => @rocket_job_output}
|
160
111
|
end
|
161
112
|
|
162
113
|
if new_record? || destroyed?
|
@@ -171,6 +122,7 @@ module RocketJob
|
|
171
122
|
# Returns [Hash<String:[Array<ActiveWorker>]>] All servers actively working on this job
|
172
123
|
def rocket_job_active_workers(server_name = nil)
|
173
124
|
return [] if !running? || (server_name && !worker_on_server?(server_name))
|
125
|
+
|
174
126
|
[ActiveWorker.new(worker_name, started_at, self)]
|
175
127
|
end
|
176
128
|
end
|