tengine_job 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Gemfile.lock +78 -48
- data/bin/tengine_job +71 -0
- data/examples/0004_retry_one_layer.rb +10 -7
- data/examples/0027_parallel_ssh_job +9 -0
- data/examples/0027_parallel_ssh_jobs.rb +14 -0
- data/lib/tengine/job.rb +19 -49
- data/lib/tengine/job/dsl.rb +13 -0
- data/lib/tengine/job/{dsl_binder.rb → dsl/binder.rb} +4 -4
- data/lib/tengine/job/{dsl_evaluator.rb → dsl/evaluator.rb} +2 -2
- data/lib/tengine/job/{dsl_loader.rb → dsl/loader.rb} +20 -22
- data/lib/tengine/job/runtime.rb +32 -0
- data/lib/tengine/job/{drivers → runtime/drivers}/job_control_driver.rb +46 -92
- data/lib/tengine/job/{drivers → runtime/drivers}/job_execution_driver.rb +14 -10
- data/lib/tengine/job/runtime/drivers/jobnet_control_driver.rb +240 -0
- data/lib/tengine/job/{drivers → runtime/drivers}/schedule_driver.rb +4 -4
- data/lib/tengine/job/{edge.rb → runtime/edge.rb} +79 -25
- data/lib/tengine/job/{executable.rb → runtime/executable.rb} +35 -15
- data/lib/tengine/job/{execution.rb → runtime/execution.rb} +19 -11
- data/lib/tengine/job/runtime/job_base.rb +5 -0
- data/lib/tengine/job/runtime/jobnet.rb +283 -0
- data/lib/tengine/job/runtime/junction.rb +44 -0
- data/lib/tengine/job/runtime/named_vertex.rb +95 -0
- data/lib/tengine/job/runtime/root_jobnet.rb +81 -0
- data/lib/tengine/job/{signal.rb → runtime/signal.rb} +99 -13
- data/lib/tengine/job/runtime/ssh_job.rb +486 -0
- data/lib/tengine/job/{jobnet → runtime}/state_transition.rb +6 -4
- data/lib/tengine/job/runtime/stoppable.rb +64 -0
- data/lib/tengine/job/runtime/vertex.rb +50 -0
- data/lib/tengine/job/structure.rb +20 -0
- data/lib/tengine/job/{category.rb → structure/category.rb} +9 -5
- data/lib/tengine/job/{jobnet/builder.rb → structure/edge_builder.rb} +11 -7
- data/lib/tengine/job/{element_selector_notation.rb → structure/element_selector_notation.rb} +15 -11
- data/lib/tengine/job/structure/jobnet_builder.rb +83 -0
- data/lib/tengine/job/structure/jobnet_finder.rb +60 -0
- data/lib/tengine/job/{name_path.rb → structure/name_path.rb} +2 -2
- data/lib/tengine/job/structure/tree.rb +20 -0
- data/lib/tengine/job/structure/visitor.rb +67 -0
- data/lib/tengine/job/template.rb +24 -0
- data/lib/tengine/job/template/edge.rb +37 -0
- data/lib/tengine/job/template/expansion.rb +24 -0
- data/lib/tengine/job/template/generator.rb +111 -0
- data/lib/tengine/job/template/jobnet.rb +83 -0
- data/lib/tengine/job/template/junction.rb +14 -0
- data/lib/tengine/job/{job.rb → template/named_vertex.rb} +3 -5
- data/lib/tengine/job/{root_jobnet_template.rb → template/root_jobnet.rb} +12 -26
- data/lib/tengine/job/template/ssh_job.rb +80 -0
- data/lib/tengine/job/template/vertex.rb +97 -0
- metadata +127 -93
- data/lib/tengine/job/connectable.rb +0 -43
- data/lib/tengine/job/drivers/jobnet_control_driver.rb +0 -249
- data/lib/tengine/job/end.rb +0 -32
- data/lib/tengine/job/expansion.rb +0 -37
- data/lib/tengine/job/fork.rb +0 -6
- data/lib/tengine/job/jobnet.rb +0 -184
- data/lib/tengine/job/jobnet/job_state_transition.rb +0 -167
- data/lib/tengine/job/jobnet/jobnet_state_transition.rb +0 -110
- data/lib/tengine/job/jobnet_actual.rb +0 -84
- data/lib/tengine/job/jobnet_template.rb +0 -10
- data/lib/tengine/job/join.rb +0 -6
- data/lib/tengine/job/junction.rb +0 -29
- data/lib/tengine/job/killing.rb +0 -30
- data/lib/tengine/job/mm_compatibility.rb +0 -6
- data/lib/tengine/job/mm_compatibility/connectable.rb +0 -13
- data/lib/tengine/job/root.rb +0 -16
- data/lib/tengine/job/root_jobnet_actual.rb +0 -58
- data/lib/tengine/job/script_executable.rb +0 -235
- data/lib/tengine/job/start.rb +0 -20
- data/lib/tengine/job/stoppable.rb +0 -15
- data/lib/tengine/job/vertex.rb +0 -181
@@ -1,43 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
require 'tengine/job'
|
3
|
-
|
4
|
-
require 'tengine_resource'
|
5
|
-
|
6
|
-
module Tengine::Job::Connectable
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
field :server_name , :type => String # 接続先となるサーバ名。Tengine::Resource::Server#name を指定します
|
11
|
-
field :credential_name, :type => String # 接続時に必要な認証情報。Tengine::Resource::Credential#name を指定します
|
12
|
-
|
13
|
-
include Tengine::Job::MmCompatibility::Connectable
|
14
|
-
|
15
|
-
def actual_credential_name
|
16
|
-
credential_name || (parent ? parent.actual_credential_name : nil)
|
17
|
-
end
|
18
|
-
|
19
|
-
def actual_server_name
|
20
|
-
server_name || (parent ? parent.actual_server_name : nil)
|
21
|
-
end
|
22
|
-
|
23
|
-
def actual_credential
|
24
|
-
key = actual_credential_name
|
25
|
-
return nil if key.blank?
|
26
|
-
result = Tengine::Resource::Credential.where({:name => key}).first
|
27
|
-
# TODO 使用する例外クラスはこれで良いのか検討
|
28
|
-
raise Mongoid::Errors::DocumentNotFound.new(Tengine::Resource::Credential, key, []) unless result
|
29
|
-
result
|
30
|
-
end
|
31
|
-
|
32
|
-
def actual_server
|
33
|
-
key = actual_server_name
|
34
|
-
return nil if key.blank?
|
35
|
-
result = Tengine::Resource::Server.where({:name => key}).first
|
36
|
-
# TODO 使用する例外クラスはこれで良いのか検討
|
37
|
-
raise Mongoid::Errors::DocumentNotFound.new(Tengine::Resource::Server, key, []) unless result
|
38
|
-
result
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
@@ -1,249 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
include Tengine::Core::SafeUpdatable
|
3
|
-
|
4
|
-
[
|
5
|
-
:'start.jobnet.job.tengine',
|
6
|
-
:'success.job.job.tengine',
|
7
|
-
:'error.job.job.tengine',
|
8
|
-
:'success.jobnet.job.tengine',
|
9
|
-
:'error.jobnet.job.tengine',
|
10
|
-
:'stop.jobnet.job.tengine',
|
11
|
-
].each do |i|
|
12
|
-
ack_policy :after_all_handler_submit, i
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
# ジョブネット制御ドライバ
|
17
|
-
driver :jobnet_control_driver do
|
18
|
-
|
19
|
-
on :'start.jobnet.job.tengine' do
|
20
|
-
signal = Tengine::Job::Signal.new(event)
|
21
|
-
root_jobnet = Tengine::Job::RootJobnetActual.find(event[:root_jobnet_id])
|
22
|
-
root_jobnet.update_with_lock do
|
23
|
-
signal.reset
|
24
|
-
target_jobnet = root_jobnet.find_descendant(event[:target_jobnet_id]) || root_jobnet
|
25
|
-
signal.with_paths_backup do
|
26
|
-
target_jobnet.activate(signal)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
signal.execution.with(safe: safemode(Tengine::Job::Execution.collection)).save! if event[:root_jobnet_id] == event[:target_jobnet_id]
|
30
|
-
signal.reservations.each{|r| fire(*r.fire_args)}
|
31
|
-
submit
|
32
|
-
end
|
33
|
-
|
34
|
-
on :'start.jobnet.job.tengine.failed.tengined' do
|
35
|
-
# このイベントは壊れていたからfailedなのかもしれない。多重送信によ
|
36
|
-
# りfailedなのかもしれない。あまりへんな仮定を置かない方が良い。
|
37
|
-
e = event
|
38
|
-
f = e.properties or next
|
39
|
-
g = f["original_event"] or next
|
40
|
-
h = g["properties"] or next
|
41
|
-
i = h["root_jobnet_id"] or next
|
42
|
-
j = h["target_jobnet_id"] or next
|
43
|
-
k = Tengine::Job::RootJobnetActual.find(i) or next
|
44
|
-
|
45
|
-
k.update_with_lock do
|
46
|
-
l = k.find_descendant(j) || k
|
47
|
-
l.phase_key = :stuck
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
on :'success.job.job.tengine' do
|
52
|
-
signal = Tengine::Job::Signal.new(event)
|
53
|
-
root_jobnet = Tengine::Job::RootJobnetActual.find(event[:root_jobnet_id])
|
54
|
-
root_jobnet.update_with_lock do
|
55
|
-
signal.reset
|
56
|
-
target_job = root_jobnet.find_descendant(event[:target_job_id])
|
57
|
-
signal.with_paths_backup do
|
58
|
-
edge = target_job.next_edges.first
|
59
|
-
edge.transmit(signal)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
# (*1)
|
63
|
-
signal.reservations.each{|r| fire(*r.fire_args)}
|
64
|
-
submit
|
65
|
-
end
|
66
|
-
|
67
|
-
on :'success.job.job.tengine.failed.tengined' do
|
68
|
-
# このイベントは壊れていたからfailedなのかもしれない。多重送信によ
|
69
|
-
# りfailedなのかもしれない。あまりへんな仮定を置かない方が良い。
|
70
|
-
e = event
|
71
|
-
f = e.properties or next
|
72
|
-
g = f["original_event"] or next
|
73
|
-
h = g["properties"] or next
|
74
|
-
i = h["root_jobnet_id"] or next
|
75
|
-
j = h["target_jobnet_id"] or next
|
76
|
-
k = h["target_job_id"] or next
|
77
|
-
l = Tengine::Job::RootJobnetActual.find(i) or next
|
78
|
-
|
79
|
-
# 上記(*1)のポイントでtenginedが落ちた時のことを考えると、後続のエッ
|
80
|
-
# ジはもうtransmitしているが送信すべきイベントが欠けている状態であ
|
81
|
-
# るので、この場合このジョブがおかしくなっているというよりむしろジョ
|
82
|
-
# ブネット全体がおかしくなっているというべきである。
|
83
|
-
l.update_with_lock do
|
84
|
-
m = l.find_descendant(j) || l
|
85
|
-
n = m.find_descendant(k)
|
86
|
-
o = n.parent || n
|
87
|
-
o.phase_key = :stuck
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
on :'error.job.job.tengine' do
|
92
|
-
signal = Tengine::Job::Signal.new(event)
|
93
|
-
root_jobnet = Tengine::Job::RootJobnetActual.find(event[:root_jobnet_id])
|
94
|
-
root_jobnet.update_with_lock do
|
95
|
-
signal.reset
|
96
|
-
target_job = root_jobnet.vertex(event[:target_job_id])
|
97
|
-
signal.with_paths_backup do
|
98
|
-
edge = target_job.next_edges.first
|
99
|
-
edge.close_followings
|
100
|
-
edge.transmit(signal)
|
101
|
-
end
|
102
|
-
# target_jobnet = target_job.parent
|
103
|
-
# target_jobnet.jobnet_fail(signal)
|
104
|
-
end
|
105
|
-
signal.reservations.each{|r| fire(*r.fire_args)}
|
106
|
-
submit
|
107
|
-
end
|
108
|
-
|
109
|
-
on :'error.job.job.tengine.failed.tengined' do
|
110
|
-
# このイベントは壊れていたからfailedなのかもしれない。多重送信によ
|
111
|
-
# りfailedなのかもしれない。あまりへんな仮定を置かない方が良い。
|
112
|
-
e = event
|
113
|
-
f = e.properties or next
|
114
|
-
g = f["original_event"] or next
|
115
|
-
h = g["properties"] or next
|
116
|
-
i = h["root_jobnet_id"] or next
|
117
|
-
j = h["target_jobnet_id"] or next
|
118
|
-
k = h["target_job_id"] or next
|
119
|
-
l = Tengine::Job::RootJobnetActual.find(i) or next
|
120
|
-
|
121
|
-
# 同上で、この場合このジョブがおかしくなっているというよりむしろジョ
|
122
|
-
# ブネット全体がおかしくなっているというべきである。
|
123
|
-
l.update_with_lock do
|
124
|
-
m = l.find_descendant(j) || l
|
125
|
-
n = m.find_descendant(k)
|
126
|
-
o = n.parent || n
|
127
|
-
o.phase_key = :stuck
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
on :'success.jobnet.job.tengine' do
|
132
|
-
signal = Tengine::Job::Signal.new(event)
|
133
|
-
root_jobnet = Tengine::Job::RootJobnetActual.find(event[:root_jobnet_id])
|
134
|
-
root_jobnet.update_with_lock do
|
135
|
-
signal.reset
|
136
|
-
target_jobnet = root_jobnet.vertex(event[:target_jobnet_id])
|
137
|
-
signal.with_paths_backup do
|
138
|
-
case target_jobnet.jobnet_type_key
|
139
|
-
when :finally then
|
140
|
-
parent = target_jobnet.parent
|
141
|
-
edge = parent.end_vertex.prev_edges.first
|
142
|
-
(edge.closed? || edge.closing?) ?
|
143
|
-
parent.fail(signal) :
|
144
|
-
parent.succeed(signal)
|
145
|
-
else
|
146
|
-
if edge = (target_jobnet.next_edges || []).first
|
147
|
-
edge.transmit(signal)
|
148
|
-
else
|
149
|
-
(target_jobnet.parent || signal.execution).succeed(signal)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
signal.execution.with(sage: safemode(Tengine::Job::Execution.collection)).save! if event[:root_jobnet_id] == event[:target_jobnet_id]
|
155
|
-
signal.reservations.each{|r| fire(*r.fire_args)}
|
156
|
-
submit
|
157
|
-
end
|
158
|
-
|
159
|
-
on :'success.jobnet.job.tengine.failed.tengined' do
|
160
|
-
# このイベントは壊れていたからfailedなのかもしれない。多重送信によ
|
161
|
-
# りfailedなのかもしれない。あまりへんな仮定を置かない方が良い。
|
162
|
-
e = event
|
163
|
-
f = e.properties or next
|
164
|
-
g = f["original_event"] or next
|
165
|
-
h = g["properties"] or next
|
166
|
-
i = h["root_jobnet_id"] or next
|
167
|
-
j = h["target_jobnet_id"] or next
|
168
|
-
k = Tengine::Job::RootJobnetActual.find(i) or next
|
169
|
-
|
170
|
-
k.update_with_lock do
|
171
|
-
l = k.find_descendant(j) || k
|
172
|
-
l.phase_key = :stuck
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
on :'error.jobnet.job.tengine' do
|
177
|
-
signal = Tengine::Job::Signal.new(event)
|
178
|
-
root_jobnet = Tengine::Job::RootJobnetActual.find(event[:root_jobnet_id])
|
179
|
-
root_jobnet.update_with_lock do
|
180
|
-
signal.reset
|
181
|
-
target_jobnet = root_jobnet.find_descendant(event[:target_jobnet_id]) || root_jobnet
|
182
|
-
signal.with_paths_backup do
|
183
|
-
case target_jobnet.jobnet_type_key
|
184
|
-
when :finally then
|
185
|
-
target_jobnet.parent.fail(signal)
|
186
|
-
else
|
187
|
-
if edge = (target_jobnet.next_edges || []).first
|
188
|
-
edge.close_followings
|
189
|
-
edge.transmit(signal)
|
190
|
-
else
|
191
|
-
(target_jobnet.parent || signal.execution).fail(signal)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
# if target_parent = target_jobnet.parent
|
196
|
-
# target_parent.end_vertex.transmit(signal)
|
197
|
-
# end
|
198
|
-
end
|
199
|
-
signal.execution.with(safe: safemode(Tengine::Job::Execution.collection)).save! if event[:root_jobnet_id] == event[:target_jobnet_id]
|
200
|
-
signal.reservations.each{|r| fire(*r.fire_args)}
|
201
|
-
submit
|
202
|
-
end
|
203
|
-
|
204
|
-
on :'error.jobnet.job.tengine.failed.tengined' do
|
205
|
-
# このイベントは壊れていたからfailedなのかもしれない。多重送信によ
|
206
|
-
# りfailedなのかもしれない。あまりへんな仮定を置かない方が良い。
|
207
|
-
e = event
|
208
|
-
f = e.properties or next
|
209
|
-
g = f["original_event"] or next
|
210
|
-
h = g["properties"] or next
|
211
|
-
i = h["root_jobnet_id"] or next
|
212
|
-
j = h["target_jobnet_id"] or next
|
213
|
-
k = Tengine::Job::RootJobnetActual.find(i) or next
|
214
|
-
|
215
|
-
k.update_with_lock do
|
216
|
-
l = k.find_descendant(j) || k
|
217
|
-
l.phase_key = :stuck
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
on :'stop.jobnet.job.tengine' do
|
222
|
-
signal = Tengine::Job::Signal.new(event)
|
223
|
-
root_jobnet = Tengine::Job::RootJobnetActual.find(event[:root_jobnet_id])
|
224
|
-
root_jobnet.update_with_lock do
|
225
|
-
signal.reset
|
226
|
-
target_jobnet = root_jobnet.find_descendant(event[:target_jobnet_id]) || root_jobnet
|
227
|
-
target_jobnet.stop(signal)
|
228
|
-
end
|
229
|
-
signal.reservations.each{|r| fire(*r.fire_args) }
|
230
|
-
submit
|
231
|
-
end
|
232
|
-
|
233
|
-
on :'stop.jobnet.job.tengine.failed.tengined' do
|
234
|
-
# このイベントは壊れていたからfailedなのかもしれない。多重送信によ
|
235
|
-
# りfailedなのかもしれない。あまりへんな仮定を置かない方が良い。
|
236
|
-
e = event
|
237
|
-
f = e.properties or next
|
238
|
-
g = f["original_event"] or next
|
239
|
-
h = g["properties"] or next
|
240
|
-
i = h["root_jobnet_id"] or next
|
241
|
-
j = h["target_jobnet_id"] or next
|
242
|
-
k = Tengine::Job::RootJobnetActual.find(i) or next
|
243
|
-
|
244
|
-
k.update_with_lock do
|
245
|
-
l = k.find_descendant(j) || k
|
246
|
-
l.phase_key = :stuck
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
data/lib/tengine/job/end.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
require 'tengine/job'
|
3
|
-
|
4
|
-
# ジョブネットの終端を表すVertex。特に状態は持たない。
|
5
|
-
class Tengine::Job::End < Tengine::Job::Vertex
|
6
|
-
|
7
|
-
# https://cacoo.com/diagrams/hdLgrzYsTBBpV3Wj#D26C1
|
8
|
-
def transmit(signal)
|
9
|
-
activate(signal)
|
10
|
-
end
|
11
|
-
|
12
|
-
def activate(signal)
|
13
|
-
complete_origin_edge(signal, :except_closed => true)
|
14
|
-
parent = self.parent # Endのparentであるジョブネット
|
15
|
-
parent_finally = parent.finally_vertex
|
16
|
-
if parent_finally && (parent.phase_key != :dying)
|
17
|
-
parent_finally.transmit(signal)
|
18
|
-
else
|
19
|
-
parent.finish(signal) unless parent.phase_key == :stuck
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def reset(signal)
|
24
|
-
parent = self.parent # Endのparentであるジョブネット
|
25
|
-
if signal.execution.in_scope?(parent)
|
26
|
-
if f = parent.finally_vertex
|
27
|
-
f.reset(signal)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
require 'tengine/job'
|
3
|
-
|
4
|
-
# ルートジョブネットを他のジョブネット内に展開するための特殊なテンプレート用Vertex。
|
5
|
-
class Tengine::Job::Expansion < Tengine::Job::Job
|
6
|
-
def actual_class
|
7
|
-
Tengine::Job::JobnetActual
|
8
|
-
end
|
9
|
-
def root_jobnet_template
|
10
|
-
unless @root_jobnet_template
|
11
|
-
cond = {:dsl_version => root.dsl_version, :name => name}
|
12
|
-
@root_jobnet_template = Tengine::Job::RootJobnetTemplate.where(cond).first
|
13
|
-
end
|
14
|
-
@root_jobnet_template
|
15
|
-
end
|
16
|
-
|
17
|
-
IGNORED_FIELD_NAMES = (Tengine::Job::Vertex::IGNORED_FIELD_NAMES + %w[name dsl_version jobnet_type_cd version updated_at created_at children edges]).freeze
|
18
|
-
|
19
|
-
def generating_attrs
|
20
|
-
result = super
|
21
|
-
attrs = root_jobnet_template.attributes.dup
|
22
|
-
if template = root_jobnet_template
|
23
|
-
attrs[:template_id] = template.id
|
24
|
-
end
|
25
|
-
attrs.delete_if{|attr, value| IGNORED_FIELD_NAMES.include?(attr)}
|
26
|
-
result.update(attrs)
|
27
|
-
result
|
28
|
-
end
|
29
|
-
def generating_children; root_jobnet_template.children; end
|
30
|
-
def generating_edges; root_jobnet_template.edges; end
|
31
|
-
|
32
|
-
def generate(klass = actual_class)
|
33
|
-
result = super
|
34
|
-
result.was_expansion = true
|
35
|
-
result
|
36
|
-
end
|
37
|
-
end
|
data/lib/tengine/job/fork.rb
DELETED
data/lib/tengine/job/jobnet.rb
DELETED
@@ -1,184 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
require 'tengine/job'
|
3
|
-
|
4
|
-
require 'selectable_attr'
|
5
|
-
|
6
|
-
# ジョブの始端から終端までを持ち、VertexとEdgeを組み合わせてジョブネットを構成することができるVertex。
|
7
|
-
# 自身もジョブネットを構成するVertexの一部として扱われる。
|
8
|
-
class Tengine::Job::Jobnet < Tengine::Job::Job
|
9
|
-
include Tengine::Core::SelectableAttr
|
10
|
-
include Tengine::Job::ElementSelectorNotation
|
11
|
-
include Tengine::Core::SafeUpdatable
|
12
|
-
|
13
|
-
autoload :Builder, "tengine/job/jobnet/builder"
|
14
|
-
autoload :StateTransition, 'tengine/job/jobnet/state_transition'
|
15
|
-
autoload :JobStateTransition, 'tengine/job/jobnet/job_state_transition'
|
16
|
-
autoload :JobnetStateTransition, 'tengine/job/jobnet/jobnet_state_transition'
|
17
|
-
|
18
|
-
field :script , :type => String # 実行されるスクリプト(本来Tengine::Job::Scriptが保持しますが、子要素を保持してかつスクリプトを実行するhadoop_job_runもある)
|
19
|
-
field :description , :type => String # ジョブネットの説明
|
20
|
-
field :jobnet_type_cd, :type => Integer, :default => 1 # ジョブネットの種類。後述の定義を参照してください。
|
21
|
-
|
22
|
-
selectable_attr :jobnet_type_cd do
|
23
|
-
entry 1, :normal , "normal"
|
24
|
-
entry 2, :finally , "finally", :alternative => true
|
25
|
-
# entry 3, :recover , "recover", :alternative => true
|
26
|
-
entry 4, :hadoop_job_run, "hadoop job run"
|
27
|
-
entry 5, :hadoop_job , "hadoop job" , :chained_box => true
|
28
|
-
entry 6, :map_phase , "map phase" , :chained_box => true
|
29
|
-
entry 7, :reduce_phase , "reduce phase" , :chained_box => true
|
30
|
-
end
|
31
|
-
def chained_box?; jobnet_type_entry[:chained_box]; end
|
32
|
-
|
33
|
-
embeds_many :edges, :class_name => "Tengine::Job::Edge", :inverse_of => :owner , :validate => false
|
34
|
-
|
35
|
-
before_validation do |r|
|
36
|
-
r.edges.each do |edge|
|
37
|
-
unless edge.valid?
|
38
|
-
edge.errors.each do |f, error|
|
39
|
-
r.errors.add(:base, "#{edge.name_for_message} #{f.to_s.humanize} #{error}")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class << self
|
46
|
-
def by_name(name)
|
47
|
-
where({:name => name}).first
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def script_executable?
|
52
|
-
!script.blank?
|
53
|
-
end
|
54
|
-
|
55
|
-
def start_vertex
|
56
|
-
self.children.detect{|child| child.is_a?(Tengine::Job::Start)}
|
57
|
-
end
|
58
|
-
|
59
|
-
def end_vertex
|
60
|
-
self.children.detect{|child| child.is_a?(Tengine::Job::End)}
|
61
|
-
end
|
62
|
-
|
63
|
-
def finally_vertex
|
64
|
-
self.children.detect{|child| child.is_a?(Tengine::Job::Jobnet) && (child.jobnet_type_key == :finally)}
|
65
|
-
end
|
66
|
-
alias_method :finally_jobnet, :finally_vertex
|
67
|
-
|
68
|
-
def with_start
|
69
|
-
self.children << Tengine::Job::Start.new
|
70
|
-
self
|
71
|
-
end
|
72
|
-
|
73
|
-
def prepare_end
|
74
|
-
if self.children.last.is_a?(Tengine::Job::End)
|
75
|
-
_end = self.children.last
|
76
|
-
yield(_end) if block_given?
|
77
|
-
else
|
78
|
-
_end = Tengine::Job::End.new
|
79
|
-
yield(_end) if block_given?
|
80
|
-
self.children << _end
|
81
|
-
end
|
82
|
-
_end
|
83
|
-
end
|
84
|
-
|
85
|
-
def child_by_name(str)
|
86
|
-
case str
|
87
|
-
when '..' then parent
|
88
|
-
when '.' then self
|
89
|
-
when 'start' then start_vertex
|
90
|
-
when 'end' then end_vertex
|
91
|
-
when 'finally' then finally_vertex
|
92
|
-
else
|
93
|
-
self.children.detect{|c| c.is_a?(Tengine::Job::Job) && (c.name == str)}
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def build_edges(auto_sequence, boot_job_names, redirections)
|
98
|
-
if self.children.length == 1 # 最初に追加したStartだけなら。
|
99
|
-
self.children.delete_all
|
100
|
-
return
|
101
|
-
end
|
102
|
-
if auto_sequence || boot_job_names.empty?
|
103
|
-
prepare_end
|
104
|
-
build_sequencial_edges
|
105
|
-
else
|
106
|
-
Builder.new(self, boot_job_names, redirections).process
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def build_sequencial_edges
|
111
|
-
self.edges.clear
|
112
|
-
current = nil
|
113
|
-
self.children.each do |child|
|
114
|
-
next if child.is_a?(Tengine::Job::Jobnet) && !!child.jobnet_type_entry[:alternative]
|
115
|
-
if current
|
116
|
-
edge = self.new_edge(current, child)
|
117
|
-
yield(edge) if block_given?
|
118
|
-
end
|
119
|
-
current = child
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def new_edge(origin, destination)
|
124
|
-
origin_id = origin.is_a?(Tengine::Job::Vertex) ? origin.id : origin
|
125
|
-
destination_id = destination.is_a?(Tengine::Job::Vertex) ? destination.id : destination
|
126
|
-
edges.new(:origin_id => origin_id, :destination_id => destination_id)
|
127
|
-
end
|
128
|
-
|
129
|
-
def find_descendant_edge(edge_id)
|
130
|
-
edge_id = String(edge_id)
|
131
|
-
visitor = Tengine::Job::Vertex::AnyVisitor.new do |vertex|
|
132
|
-
if vertex.respond_to?(:edges)
|
133
|
-
vertex.edges.detect{|edge| edge.id.to_s == edge_id}
|
134
|
-
else
|
135
|
-
nil
|
136
|
-
end
|
137
|
-
end
|
138
|
-
visitor.visit(self)
|
139
|
-
end
|
140
|
-
alias_method :edge, :find_descendant_edge
|
141
|
-
|
142
|
-
def find_descendant(vertex_id)
|
143
|
-
vertex_id = String(vertex_id)
|
144
|
-
return nil if vertex_id == self.id.to_s
|
145
|
-
vertex(vertex_id)
|
146
|
-
end
|
147
|
-
|
148
|
-
def vertex(vertex_id)
|
149
|
-
vertex_id = String(vertex_id)
|
150
|
-
return self if vertex_id == self.id.to_s
|
151
|
-
visitor = Tengine::Job::Vertex::AnyVisitor.new{|v| vertex_id == v.id.to_s ? v : nil }
|
152
|
-
visitor.visit(self)
|
153
|
-
end
|
154
|
-
|
155
|
-
def find_descendant_by_name_path(name_path)
|
156
|
-
return nil if name_path == self.name_path
|
157
|
-
vertex_by_name_path(name_path)
|
158
|
-
end
|
159
|
-
|
160
|
-
def vertex_by_name_path(name_path)
|
161
|
-
Tengine::Job::NamePath.absolute?(name_path) ?
|
162
|
-
root.vertex_by_absolute_name_path(name_path) :
|
163
|
-
vertex_by_relative_name_path(name_path)
|
164
|
-
end
|
165
|
-
|
166
|
-
def vertex_by_absolute_name_path(name_path)
|
167
|
-
return self if name_path.to_s == self.name_path
|
168
|
-
visitor = Tengine::Job::Vertex::AnyVisitor.new do |vertex|
|
169
|
-
if name_path == (vertex.respond_to?(:name_path) ? vertex.name_path : nil)
|
170
|
-
vertex
|
171
|
-
else
|
172
|
-
nil
|
173
|
-
end
|
174
|
-
end
|
175
|
-
visitor.visit(self)
|
176
|
-
end
|
177
|
-
|
178
|
-
def vertex_by_relative_name_path(name_path)
|
179
|
-
head, tail = *name_path.split(Tengine::Job::NamePath::SEPARATOR, 2)
|
180
|
-
child = child_by_name(head)
|
181
|
-
tail ? child.vertex_by_relative_name_path(tail) : child
|
182
|
-
end
|
183
|
-
|
184
|
-
end
|