rbbt-util 5.10.2 → 5.11.1
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/lib/rbbt/persist.rb +60 -20
- data/lib/rbbt/tsv/dumper.rb +1 -1
- data/lib/rbbt/tsv/parallel/traverse.rb +83 -65
- data/lib/rbbt/tsv/parser.rb +23 -8
- data/lib/rbbt/util/concurrency/processes.rb +23 -10
- data/lib/rbbt/util/concurrency/processes/worker.rb +3 -1
- data/lib/rbbt/util/log.rb +5 -10
- data/lib/rbbt/util/misc.rb +85 -52
- data/lib/rbbt/workflow.rb +2 -1
- data/lib/rbbt/workflow/step.rb +79 -29
- data/share/rbbt_commands/benchmark/throughput +5 -4
- data/share/rbbt_commands/tsv/slice +13 -4
- data/share/rbbt_commands/workflow/task +13 -7
- data/test/rbbt/test_persist.rb +21 -4
- data/test/rbbt/tsv/parallel/test_traverse.rb +9 -0
- data/test/rbbt/util/concurrency/processes/test_socket.rb +3 -1
- data/test/rbbt/util/concurrency/test_processes.rb +29 -0
- data/test/rbbt/util/test_misc.rb +6 -6
- data/test/rbbt/workflow/test_step.rb +1 -1
- metadata +2 -2
@@ -28,9 +28,11 @@ class RbbtProcessQueue
|
|
28
28
|
|
29
29
|
rescue ClosedStream
|
30
30
|
rescue Aborted
|
31
|
-
Log.
|
31
|
+
Log.error "Worker #{Process.pid} aborted"
|
32
|
+
Kernel.exit! -1
|
32
33
|
rescue Exception
|
33
34
|
@callback_queue.push($!) if @callback_queue
|
35
|
+
Kernel.exit! -1
|
34
36
|
ensure
|
35
37
|
@callback_queue.close_write if @callback_queue
|
36
38
|
end
|
data/lib/rbbt/util/log.rb
CHANGED
@@ -72,6 +72,7 @@ module Log
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
LOG_MUTEX = Mutex.new
|
75
76
|
def self.log(message = nil, severity = MEDIUM, &block)
|
76
77
|
return if severity < self.severity
|
77
78
|
message ||= block.call if block_given?
|
@@ -85,8 +86,10 @@ module Log
|
|
85
86
|
message = "" << highlight << message << color(0) if severity >= INFO
|
86
87
|
str = prefix << " " << message
|
87
88
|
|
88
|
-
|
89
|
-
|
89
|
+
LOG_MUTEX.synchronize do
|
90
|
+
STDERR.puts str
|
91
|
+
logfile.puts str unless logfile.nil?
|
92
|
+
end
|
90
93
|
end
|
91
94
|
|
92
95
|
def self.debug(message = nil, &block)
|
@@ -194,14 +197,6 @@ def iii(message, file = $stdout)
|
|
194
197
|
Log.info{""}
|
195
198
|
end
|
196
199
|
|
197
|
-
def www(message, file = $stdout)
|
198
|
-
stack = caller
|
199
|
-
Log.warn{"#{Log.color :cyan, "INFO:"} " << stack.first}
|
200
|
-
Log.warn{""}
|
201
|
-
Log.warn{"=> " << message.inspect}
|
202
|
-
Log.warn{""}
|
203
|
-
end
|
204
|
-
|
205
200
|
def eee(message, file = $stdout)
|
206
201
|
stack = caller
|
207
202
|
Log.error{"#{Log.color :cyan, "INFO:"} " << stack.first}
|
data/lib/rbbt/util/misc.rb
CHANGED
@@ -21,6 +21,12 @@ class FieldNotFoundError < Exception;end
|
|
21
21
|
class Aborted < Exception; end
|
22
22
|
class TryAgain < Exception; end
|
23
23
|
class ClosedStream < Exception; end
|
24
|
+
class KeepLocked < Exception
|
25
|
+
attr_accessor :payload
|
26
|
+
def initialize(payload)
|
27
|
+
@payload = payload
|
28
|
+
end
|
29
|
+
end
|
24
30
|
|
25
31
|
module LaterString
|
26
32
|
def to_s
|
@@ -31,27 +37,35 @@ end
|
|
31
37
|
module ConcurrentStream
|
32
38
|
attr_accessor :threads, :pids, :callback, :filename
|
33
39
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
40
|
+
def join
|
41
|
+
|
42
|
+
if @threads and @threads.any?
|
43
|
+
@threads.each do |t|
|
44
|
+
t.join
|
45
|
+
end
|
46
|
+
@threads = []
|
47
|
+
end
|
48
|
+
|
49
|
+
if @pids and @pids.any?
|
50
|
+
@pids.each do |pid|
|
51
|
+
begin
|
52
|
+
Process.waitpid(pid, Process::WUNTRACED)
|
53
|
+
raise "Error joining process #{pid} in #{self.inspect}" unless $?.success?
|
54
|
+
rescue Errno::ECHILD
|
55
|
+
end
|
56
|
+
end
|
57
|
+
@pids = []
|
38
58
|
end
|
39
|
-
end
|
40
59
|
|
41
|
-
def join
|
42
|
-
filename = self.respond_to?(:filename)? self.filename : :none
|
43
60
|
if @callback
|
44
61
|
@callback.call
|
62
|
+
@callback = nil
|
45
63
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
raise "Error joining process #{pid} in #{self.inspect}" unless $?.success?
|
52
|
-
rescue Errno::ECHILD
|
53
|
-
end
|
54
|
-
end if @pids
|
64
|
+
end
|
65
|
+
|
66
|
+
def abort
|
67
|
+
@threads.each{|t| t.raise Aborted.new } if @threads
|
68
|
+
@pids.each{|pid| Process.kill :INT, pid } if @pids
|
55
69
|
end
|
56
70
|
|
57
71
|
def self.setup(stream, options = {}, &block)
|
@@ -116,9 +130,11 @@ module Misc
|
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
119
|
-
def self.open_pipe(do_fork = false,
|
133
|
+
def self.open_pipe(do_fork = false, close = true)
|
120
134
|
raise "No block given" unless block_given?
|
135
|
+
|
121
136
|
sout, sin = Misc.pipe
|
137
|
+
|
122
138
|
if do_fork
|
123
139
|
parent_pid = Process.pid
|
124
140
|
pid = Process.fork {
|
@@ -131,22 +147,23 @@ module Misc
|
|
131
147
|
Process.kill :INT, parent_pid
|
132
148
|
Kernel.exit! -1
|
133
149
|
ensure
|
134
|
-
|
150
|
+
sin.close unless sin.closed?
|
135
151
|
end
|
136
152
|
Kernel.exit! 0
|
137
153
|
}
|
138
|
-
|
154
|
+
sin.close if close
|
155
|
+
ConcurrentStream.setup sout, :pids => [pid]
|
139
156
|
else
|
140
157
|
thread = Thread.new(Thread.current) do |parent|
|
141
158
|
begin
|
142
159
|
yield sin
|
143
160
|
rescue
|
144
|
-
Log.exception $!
|
145
161
|
parent.raise $!
|
146
162
|
ensure
|
147
|
-
|
163
|
+
sin.close if close
|
148
164
|
end
|
149
165
|
end
|
166
|
+
ConcurrentStream.setup sout, :threads => [thread]
|
150
167
|
end
|
151
168
|
sout
|
152
169
|
end
|
@@ -161,20 +178,24 @@ module Misc
|
|
161
178
|
stream_out2.close
|
162
179
|
begin
|
163
180
|
filename = stream.respond_to?(:filename)? stream.filename : nil
|
181
|
+
skip1 = skip2 = false
|
164
182
|
while block = stream.read(2048)
|
165
|
-
begin stream_in1.write block; rescue Exception; Log.exception
|
166
|
-
begin stream_in2.write block; rescue Exception; Log.exception
|
183
|
+
begin stream_in1.write block; rescue Exception; Log.exception $!; skip1 = true end unless skip1
|
184
|
+
begin stream_in2.write block; rescue Exception; Log.exception $!; skip2 = true end unless skip2
|
167
185
|
end
|
186
|
+
raise "Error writing in stream_in2" if skip2
|
187
|
+
raise "Error writing in stream_in2" if skip2
|
188
|
+
rescue Aborted
|
189
|
+
stream.abort if stream.respond_to? :abort
|
190
|
+
raise $!
|
168
191
|
rescue IOError
|
169
192
|
Log.exception $!
|
170
193
|
rescue Exception
|
171
194
|
Log.exception $!
|
172
195
|
ensure
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
Misc.release_pipes(stream_in1)
|
177
|
-
Misc.release_pipes(stream_in2)
|
196
|
+
stream_in1.close
|
197
|
+
stream_in2.close
|
198
|
+
stream.join if stream.respond_to? :join
|
178
199
|
end
|
179
200
|
end
|
180
201
|
stream.close
|
@@ -195,21 +216,23 @@ module Misc
|
|
195
216
|
splitter_thread = Thread.new(Thread.current, stream_in1, stream_in2) do |parent,stream_in1,stream_in2|
|
196
217
|
begin
|
197
218
|
filename = stream.respond_to?(:filename)? stream.filename : nil
|
219
|
+
skip1 = skip2 = false
|
198
220
|
while block = stream.read(2048)
|
199
|
-
begin stream_in1.write block; rescue Exception;
|
200
|
-
begin stream_in2.write block; rescue Exception;
|
221
|
+
begin stream_in1.write block; rescue Exception; Aborted === $! ? raise($!): Log.exception($!); skip1 = true end unless skip1
|
222
|
+
begin stream_in2.write block; rescue Exception; Aborted === $! ? raise($!): Log.exception($!); skip2 = true end unless skip2
|
201
223
|
end
|
224
|
+
rescue Aborted
|
225
|
+
stream.abort if stream.respond_to? :abort
|
226
|
+
raise $!
|
202
227
|
rescue IOError
|
203
228
|
Log.exception $!
|
204
229
|
rescue Exception
|
205
230
|
Log.exception $!
|
206
231
|
parent.raise $!
|
207
232
|
ensure
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
Misc.release_pipes(stream_in1)
|
212
|
-
Misc.release_pipes(stream_in2)
|
233
|
+
stream_in1.close
|
234
|
+
stream_in2.close
|
235
|
+
stream.join if stream.respond_to? :join
|
213
236
|
end
|
214
237
|
end
|
215
238
|
|
@@ -220,7 +243,7 @@ module Misc
|
|
220
243
|
end
|
221
244
|
|
222
245
|
class << self
|
223
|
-
alias tee_stream
|
246
|
+
alias tee_stream tee_stream_thread
|
224
247
|
end
|
225
248
|
|
226
249
|
def self.format_paragraph(text, size = 80, indent = 0, offset = 0)
|
@@ -494,6 +517,8 @@ module Misc
|
|
494
517
|
case obj
|
495
518
|
when nil
|
496
519
|
"nil"
|
520
|
+
when (defined? Step and Step)
|
521
|
+
obj.path || Misc.fingerprint([obj.task.name, obj.inputs])
|
497
522
|
when TrueClass
|
498
523
|
"true"
|
499
524
|
when FalseClass
|
@@ -1276,8 +1301,8 @@ end
|
|
1276
1301
|
@hostanem ||= `hostname`.strip
|
1277
1302
|
end
|
1278
1303
|
|
1279
|
-
def self.lock(file,
|
1280
|
-
return yield
|
1304
|
+
def self.lock(file, unlock = true)
|
1305
|
+
return yield if file.nil?
|
1281
1306
|
FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exists? File.dirname(File.expand_path(file))
|
1282
1307
|
|
1283
1308
|
res = nil
|
@@ -1287,27 +1312,34 @@ end
|
|
1287
1312
|
|
1288
1313
|
begin
|
1289
1314
|
Misc.insist 3 do
|
1290
|
-
if File.exists?
|
1291
|
-
Misc.hostname == (info = Open.open(
|
1315
|
+
if File.exists? lock_path and
|
1316
|
+
Misc.hostname == (info = Open.open(lock_path){|f| YAML.load(f) })["host"] and
|
1292
1317
|
info["pid"] and not Misc.pid_exists?(info["pid"])
|
1293
1318
|
|
1294
|
-
Log.info("Removing lockfile: #{
|
1295
|
-
FileUtils.rm
|
1319
|
+
Log.info("Removing lockfile: #{lock_path}. This pid #{Process.pid}. Content: #{info.inspect}")
|
1320
|
+
FileUtils.rm lock_path
|
1296
1321
|
end
|
1297
1322
|
end
|
1298
1323
|
rescue
|
1299
|
-
Log.warn("Error checking lockfile #{
|
1300
|
-
FileUtils.rm
|
1324
|
+
Log.warn("Error checking lockfile #{lock_path}: #{$!.message}. Removing. Content: #{begin Open.read(lock_path) rescue "Could not open file" end}")
|
1325
|
+
FileUtils.rm lock_path if File.exists?(lock_path)
|
1301
1326
|
lockfile = Lockfile.new(lock_path)
|
1302
1327
|
retry
|
1303
1328
|
end
|
1304
1329
|
|
1305
1330
|
begin
|
1306
|
-
lockfile.lock
|
1307
|
-
|
1331
|
+
lockfile.lock
|
1332
|
+
res = yield lockfile
|
1333
|
+
rescue Lockfile::StolenLockError
|
1334
|
+
unlock = false
|
1335
|
+
rescue KeepLocked
|
1336
|
+
unlock = false
|
1337
|
+
res = $!.payload
|
1338
|
+
ensure
|
1339
|
+
if unlock and lockfile.locked?
|
1340
|
+
lockfile.unlock
|
1341
|
+
FileUtils.rm lock_path if File.exists? lock_path
|
1308
1342
|
end
|
1309
|
-
rescue Interrupt
|
1310
|
-
raise $!
|
1311
1343
|
end
|
1312
1344
|
|
1313
1345
|
res
|
@@ -1315,7 +1347,6 @@ end
|
|
1315
1347
|
|
1316
1348
|
|
1317
1349
|
LOCK_REPO_SERIALIZER=Marshal
|
1318
|
-
|
1319
1350
|
def self.lock_in_repo(repo, key, *args)
|
1320
1351
|
return yield file, *args if repo.nil? or key.nil?
|
1321
1352
|
|
@@ -1402,17 +1433,17 @@ end
|
|
1402
1433
|
|
1403
1434
|
def self.sensiblewrite(path, content = nil, &block)
|
1404
1435
|
return if File.exists? path
|
1405
|
-
|
1436
|
+
tmp_path = path + '.sensible_write'
|
1437
|
+
Misc.lock tmp_path do
|
1406
1438
|
if not File.exists? path
|
1439
|
+
FileUtils.rm_f tmp_path if File.exists? tmp_path
|
1407
1440
|
begin
|
1408
|
-
tmp_path = path + '.sensible_write'
|
1409
1441
|
case
|
1410
1442
|
when block_given?
|
1411
1443
|
File.open(tmp_path, 'w', &block)
|
1412
1444
|
when String === content
|
1413
1445
|
File.open(tmp_path, 'w') do |f| f.write content end
|
1414
1446
|
when (IO === content or StringIO === content or File === content)
|
1415
|
-
#Thread.pass while IO.select([content], nil, nil, 1) if IO === content
|
1416
1447
|
File.open(tmp_path, 'w') do |f|
|
1417
1448
|
while block = content.read(2048);
|
1418
1449
|
f.write block
|
@@ -1488,6 +1519,8 @@ end
|
|
1488
1519
|
str << remove_long_items(v)
|
1489
1520
|
when Array === v
|
1490
1521
|
str << k.to_s << "=>[" << v * "," << "]"
|
1522
|
+
when File === v
|
1523
|
+
str << k.to_s << "=>[File:" << v.path << "]"
|
1491
1524
|
else
|
1492
1525
|
v_ins = v.inspect
|
1493
1526
|
|
data/lib/rbbt/workflow.rb
CHANGED
@@ -138,7 +138,8 @@ module Workflow
|
|
138
138
|
if wf_name =~ /::\w+$/
|
139
139
|
clean_name = wf_name.sub(/::.*/,'')
|
140
140
|
Log.info{"Looking for '#{wf_name}' in '#{clean_name}'"}
|
141
|
-
|
141
|
+
require_workflow clean_name
|
142
|
+
return Misc.string2const Misc.camel_case(wf_name)
|
142
143
|
end
|
143
144
|
|
144
145
|
Log.info{"Loading workflow #{wf_name}"}
|
data/lib/rbbt/workflow/step.rb
CHANGED
@@ -24,9 +24,14 @@ class Step
|
|
24
24
|
else
|
25
25
|
[dependencies]
|
26
26
|
end
|
27
|
+
@mutex = Mutex.new
|
27
28
|
@inputs = inputs || []
|
28
29
|
end
|
29
30
|
|
31
|
+
def task_name
|
32
|
+
@task.name
|
33
|
+
end
|
34
|
+
|
30
35
|
def path
|
31
36
|
@path = Misc.sanitize_filename(Path.setup(@path.call)) if Proc === @path
|
32
37
|
@path
|
@@ -43,10 +48,9 @@ class Step
|
|
43
48
|
attr_accessor :relay_step
|
44
49
|
alias original_log log
|
45
50
|
def log(status, message = nil)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
relay_step.log([task.name.to_s, status.to_s] * ">", message.nil? ? nil : [task.name.to_s, message] * ">")
|
51
|
+
self.status = status
|
52
|
+
message message
|
53
|
+
relay_step.log([task.name.to_s, status.to_s] * ">", message.nil? ? nil : message )
|
50
54
|
end
|
51
55
|
end
|
52
56
|
end
|
@@ -70,7 +74,10 @@ class Step
|
|
70
74
|
else
|
71
75
|
value.read
|
72
76
|
end
|
77
|
+
rescue Exception
|
78
|
+
value.abort if value.respond_to? :abort
|
73
79
|
ensure
|
80
|
+
value.close unless value.closed?
|
74
81
|
value.join if value.respond_to? :join
|
75
82
|
end
|
76
83
|
when (not defined? Entity or description.nil? or not Entity.formats.include? description)
|
@@ -88,6 +95,17 @@ class Step
|
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
98
|
+
def get_stream
|
99
|
+
@mutex.synchronize do
|
100
|
+
begin
|
101
|
+
res = @result
|
102
|
+
IO === res ? res : nil
|
103
|
+
ensure
|
104
|
+
@result = nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
91
109
|
def _exec
|
92
110
|
@exec = true if @exec.nil?
|
93
111
|
@task.exec_in((bindings ? bindings : self), *@inputs)
|
@@ -100,13 +118,18 @@ class Step
|
|
100
118
|
end
|
101
119
|
|
102
120
|
def join
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
121
|
+
stream = get_stream
|
122
|
+
begin
|
123
|
+
stream.read if stream
|
124
|
+
rescue
|
125
|
+
stream.abort if stream.respond_to? :abort
|
126
|
+
raise $!
|
127
|
+
ensure
|
128
|
+
stream.join if stream.respond_to? :join
|
108
129
|
end
|
109
130
|
|
131
|
+
dependencies.each{|dep| dep.join }
|
132
|
+
|
110
133
|
if @pid.nil?
|
111
134
|
self
|
112
135
|
else
|
@@ -140,12 +163,15 @@ class Step
|
|
140
163
|
|
141
164
|
set_info :dependencies, dependencies.collect{|dep| [dep.task.name, dep.name]}
|
142
165
|
log(:preparing, "Preparing job")
|
166
|
+
seen_deps = []
|
143
167
|
dependencies.each{|dependency|
|
144
168
|
Log.info "#{Log.color :magenta, "Checking dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task.name.to_s || ""}"
|
145
169
|
begin
|
170
|
+
next if seen_deps.include? dependency.path
|
146
171
|
dependency.relay_log self
|
147
172
|
dependency.clean if not dependency.done? and dependency.error?
|
148
|
-
dependency.run true
|
173
|
+
dependency.run true unless dependency.done?
|
174
|
+
seen_deps.concat dependency.rec_dependencies.collect{|d| d.path}
|
149
175
|
rescue Exception
|
150
176
|
backtrace = $!.backtrace
|
151
177
|
set_info :backtrace, backtrace
|
@@ -157,7 +183,7 @@ class Step
|
|
157
183
|
set_info :inputs, Misc.remove_long_items(Misc.zip2hash(task.inputs, @inputs)) unless task.inputs.nil?
|
158
184
|
|
159
185
|
set_info :started, (start_time = Time.now)
|
160
|
-
log :started, "#{Log.color :
|
186
|
+
log :started, "#{Log.color :green, "Starting task"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}]"
|
161
187
|
|
162
188
|
begin
|
163
189
|
result = _exec
|
@@ -191,26 +217,33 @@ class Step
|
|
191
217
|
end
|
192
218
|
|
193
219
|
case result
|
194
|
-
when IO
|
220
|
+
when IO
|
195
221
|
log :streaming, "#{Log.color :magenta, "Streaming task result IO"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}]"
|
196
222
|
ConcurrentStream.setup result do
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
223
|
+
begin
|
224
|
+
set_info :done, (done_time = Time.now)
|
225
|
+
set_info :time_elapsed, (time_elapsed = done_time - start_time)
|
226
|
+
log :done, "#{Log.color :red, "Completed task"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}] +#{time_elapsed.to_i}"
|
227
|
+
rescue
|
228
|
+
Log.exception $!
|
229
|
+
end
|
201
230
|
end
|
202
231
|
when TSV::Dumper
|
203
232
|
log :streaming, "#{Log.color :magenta, "Streaming task result TSV::Dumper"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}]"
|
204
233
|
ConcurrentStream.setup result.stream do
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
234
|
+
begin
|
235
|
+
set_info :done, (done_time = Time.now)
|
236
|
+
set_info :done, (done_time = Time.now)
|
237
|
+
set_info :time_elapsed, (time_elapsed = done_time - start_time)
|
238
|
+
log :done, "#{Log.color :red, "Completed task"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}] +#{time_elapsed.to_i}"
|
239
|
+
rescue
|
240
|
+
Log.exception $!
|
241
|
+
end
|
209
242
|
end
|
210
243
|
else
|
211
244
|
set_info :done, (done_time = Time.now)
|
212
245
|
set_info :time_elapsed, (time_elapsed = done_time - start_time)
|
213
|
-
log :done, "#{Log.color :
|
246
|
+
log :done, "#{Log.color :red, "Completed task"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}] +#{time_elapsed.to_i}"
|
214
247
|
end
|
215
248
|
|
216
249
|
result
|
@@ -232,9 +265,13 @@ class Step
|
|
232
265
|
FileUtils.mkdir_p File.dirname(path) unless Open.exists? File.dirname(path)
|
233
266
|
begin
|
234
267
|
res = run(true)
|
235
|
-
io =
|
236
|
-
io = res.result
|
237
|
-
|
268
|
+
io = get_stream
|
269
|
+
#io = res.result if IO === res.result
|
270
|
+
#io = res.result.stream if TSV::Dumper === res.result
|
271
|
+
if IO === io
|
272
|
+
io.read
|
273
|
+
io.join if io.respond_to? :join
|
274
|
+
end
|
238
275
|
rescue Aborted
|
239
276
|
Log.debug{"Forked process aborted: #{path}"}
|
240
277
|
log :aborted, "Aborted"
|
@@ -275,13 +312,20 @@ class Step
|
|
275
312
|
|
276
313
|
def abort
|
277
314
|
@pid ||= info[:pid]
|
278
|
-
|
315
|
+
|
316
|
+
return true unless info[:forked]
|
317
|
+
|
318
|
+
case @pid
|
319
|
+
when nil
|
279
320
|
Log.medium "Could not abort #{path}: no pid"
|
280
321
|
false
|
322
|
+
when Process.pid
|
323
|
+
Log.medium "Could not abort #{path}: same process"
|
324
|
+
false
|
281
325
|
else
|
282
326
|
Log.medium "Aborting #{path}: #{ @pid }"
|
283
327
|
begin
|
284
|
-
Process.kill("KILL", @pid)
|
328
|
+
Process.kill("KILL", @pid)
|
285
329
|
Process.waitpid @pid
|
286
330
|
rescue Exception
|
287
331
|
Log.debug("Aborted job #{@pid} was not killed: #{$!.message}")
|
@@ -289,6 +333,7 @@ class Step
|
|
289
333
|
log(:aborted, "Job aborted by user")
|
290
334
|
true
|
291
335
|
end
|
336
|
+
log(:aborted, "Job aborted by user")
|
292
337
|
end
|
293
338
|
|
294
339
|
def child(&block)
|
@@ -335,9 +380,12 @@ class Step
|
|
335
380
|
# placed. In that case, do not consider its dependencies
|
336
381
|
return [] if self.done? and not Open.exists? self.info_file
|
337
382
|
|
338
|
-
dependencies.
|
383
|
+
return [] if dependencies.nil? or dependencies.empty?
|
384
|
+
new_dependencies = dependencies.collect{|step|
|
339
385
|
step.rec_dependencies
|
340
|
-
}.flatten
|
386
|
+
}.flatten
|
387
|
+
|
388
|
+
dependencies + new_dependencies
|
341
389
|
end
|
342
390
|
|
343
391
|
def recursive_clean
|
@@ -350,6 +398,8 @@ class Step
|
|
350
398
|
end
|
351
399
|
|
352
400
|
def step(name)
|
353
|
-
rec_dependencies.select
|
401
|
+
rec_dependencies.select do |step|
|
402
|
+
step.task_name.to_sym == name.to_sym
|
403
|
+
end.first
|
354
404
|
end
|
355
405
|
end
|