rbbt-util 5.22.3 → 5.22.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/util/concurrency/processes.rb +34 -16
- data/lib/rbbt/util/concurrency/processes/worker.rb +6 -2
- data/lib/rbbt/util/misc/development.rb +1 -1
- data/lib/rbbt/util/misc/exceptions.rb +1 -1
- data/lib/rbbt/util/misc/inspect.rb +8 -5
- data/lib/rbbt/util/simpleopt/parse.rb +10 -4
- data/lib/rbbt/workflow/accessor.rb +7 -2
- data/lib/rbbt/workflow/step/run.rb +2 -1
- data/share/rbbt_commands/system/status +4 -4
- data/share/rbbt_commands/workflow/info +1 -1
- data/share/rbbt_commands/workflow/prov +5 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 694be20134e0bd77c1d240c04fe52f547cd4b431
|
4
|
+
data.tar.gz: f96f17c3f62ec9f5d781036966c022f275e8b879
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d725866e6cbf97a5a627ca5e575d202e348e2688bf37aff4032d8c752b7fd6e747e1df85c00cf69de6258b7112812da43356db552f65940f22ef86101107afb
|
7
|
+
data.tar.gz: 98dfdd3a29d277cb2c2c52f76e6ffbae1c7f1d033f823a36637235b7b47bb61e0ae43652c14f626a9341df41f370fa0fa7ed55b2a625a63896ffce82c4d9d37a
|
@@ -63,6 +63,18 @@ class RbbtProcessQueue
|
|
63
63
|
@init_block = block
|
64
64
|
|
65
65
|
@master_pid = Process.fork do
|
66
|
+
@close_up = false
|
67
|
+
Signal.trap(:INT) do
|
68
|
+
@close_up = true
|
69
|
+
Misc.insist([0,0.01,0.1,0.2,0.5]) do
|
70
|
+
raise TryAgain unless @manager_thread
|
71
|
+
if @manager_thread.alive?
|
72
|
+
raise "Manager thread for #{Process.pid} Not working yet" unless @manager_thread["working"]
|
73
|
+
@manager_thread.raise TryAgain
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
66
78
|
if @callback_queue
|
67
79
|
Misc.purge_pipes(@queue.swrite,@queue.sread,@callback_queue.swrite, @callback_queue.sread)
|
68
80
|
else
|
@@ -72,34 +84,36 @@ class RbbtProcessQueue
|
|
72
84
|
@total = num_processes
|
73
85
|
@count = 0
|
74
86
|
@processes = []
|
75
|
-
@close_up = false
|
76
|
-
|
77
|
-
|
78
|
-
Signal.trap(:INT) do
|
79
|
-
@close_up = true
|
80
|
-
@manager_thread.raise TryAgain
|
81
|
-
end
|
82
87
|
|
83
88
|
@manager_thread = Thread.new do
|
89
|
+
begin
|
84
90
|
while true
|
85
91
|
begin
|
92
|
+
Thread.current["working"] = true
|
93
|
+
if @close_up
|
94
|
+
Log.debug "Closing up process queue #{Process.pid}"
|
95
|
+
@count = 0
|
96
|
+
Thread.new do
|
97
|
+
while true
|
98
|
+
@queue.push ClosedStream.new unless @queue.cleaned
|
99
|
+
end unless @processes.empty?
|
100
|
+
end
|
101
|
+
@close_up = false
|
102
|
+
end
|
103
|
+
|
86
104
|
begin
|
87
|
-
sleep
|
105
|
+
sleep 3
|
88
106
|
rescue TryAgain
|
89
107
|
end
|
90
108
|
|
109
|
+
raise TryAgain if @close_up
|
110
|
+
|
91
111
|
@process_mutex.synchronize do
|
92
|
-
if @close_up
|
93
|
-
@total.times do
|
94
|
-
@queue.push ClosedStream.new unless @queue.cleaned
|
95
|
-
end unless @processes.empty?
|
96
|
-
@count = 0
|
97
|
-
end
|
98
112
|
while @count > 0
|
99
113
|
@count -= 1
|
100
114
|
@total += 1
|
101
115
|
@processes << RbbtProcessQueueWorker.new(@queue, @callback_queue, @cleanup, @respawn, @offset, &@init_block)
|
102
|
-
Log.
|
116
|
+
Log.warn "Added process #{@processes.last.pid} to #{Process.pid} (#{@processes.length})"
|
103
117
|
end
|
104
118
|
|
105
119
|
while @count < 0
|
@@ -107,7 +121,7 @@ class RbbtProcessQueue
|
|
107
121
|
next unless @processes.length > 1
|
108
122
|
first = @processes.shift
|
109
123
|
first.stop
|
110
|
-
Log.
|
124
|
+
Log.warn "Removed process #{first.pid} from #{Process.pid} (#{@processes.length})"
|
111
125
|
end
|
112
126
|
end
|
113
127
|
rescue TryAgain
|
@@ -120,6 +134,10 @@ class RbbtProcessQueue
|
|
120
134
|
raise Exception
|
121
135
|
end
|
122
136
|
end
|
137
|
+
rescue Exception
|
138
|
+
Log.exception $!
|
139
|
+
raise $!
|
140
|
+
end
|
123
141
|
end
|
124
142
|
|
125
143
|
Signal.trap(:USR1) do
|
@@ -35,16 +35,19 @@ class RbbtProcessQueue
|
|
35
35
|
|
36
36
|
loop do
|
37
37
|
p = @queue.pop
|
38
|
+
|
38
39
|
next if p.nil?
|
39
40
|
raise p if Exception === p
|
40
41
|
raise p.first if Array === p and Exception === p.first
|
42
|
+
|
41
43
|
begin
|
42
44
|
res = @block.call *p
|
43
45
|
@callback_queue.push res if @callback_queue
|
44
46
|
rescue Respawn
|
45
|
-
@callback_queue.push $!.payload
|
47
|
+
@callback_queue.push $!.payload if @callback_queue
|
46
48
|
raise $!
|
47
49
|
end
|
50
|
+
|
48
51
|
raise Respawn if @respawn
|
49
52
|
if @stop
|
50
53
|
Log.high "Worker #{Process.pid} leaving"
|
@@ -121,6 +124,7 @@ class RbbtProcessQueue
|
|
121
124
|
end
|
122
125
|
|
123
126
|
while true
|
127
|
+
@prev = @current
|
124
128
|
pid, status = Process.waitpid2 @current
|
125
129
|
code = status.to_i >> 8
|
126
130
|
break unless code == 28
|
@@ -128,7 +132,7 @@ class RbbtProcessQueue
|
|
128
132
|
run
|
129
133
|
end
|
130
134
|
@asked = false
|
131
|
-
Log.high "Worker #{Process.pid} respawning to #{@current}"
|
135
|
+
Log.high "Worker #{Process.pid} respawning from #{@prev} to #{@current}"
|
132
136
|
end
|
133
137
|
rescue Aborted, Interrupt
|
134
138
|
Log.warn "Worker #{Process.pid} aborted. Current #{@current} #{Misc.pid_exists?(@current) ? "exists" : "does not exist"}"
|
@@ -143,7 +143,7 @@ def self.add_libdir(dir=nil)
|
|
143
143
|
try = 0
|
144
144
|
|
145
145
|
if sleep.nil?
|
146
|
-
sleep_array = ([0] + [0.001, 0.01, 0.1] * (times / 3)).sort[0..times-1]
|
146
|
+
sleep_array = ([0] + [0.001, 0.01, 0.1, 0.5] * (times / 3)).sort[0..times-1]
|
147
147
|
sleep = sleep_array.shift
|
148
148
|
end
|
149
149
|
|
@@ -270,12 +270,15 @@ module Misc
|
|
270
270
|
obj + " (file missing)"
|
271
271
|
end
|
272
272
|
when String
|
273
|
-
|
274
|
-
|
275
|
-
if obj.length > HASH2MD5_MAX_STRING_LENGTH
|
276
|
-
sample_large_obj(obj, HASH2MD5_MAX_STRING_LENGTH) << "--" << txt_digest_str(obj)
|
273
|
+
if Misc.is_filename?(obj)
|
274
|
+
obj2str Path.setup(obj.dup)
|
277
275
|
else
|
278
|
-
obj
|
276
|
+
obj = obj.chomp if String === obj
|
277
|
+
if obj.length > HASH2MD5_MAX_STRING_LENGTH
|
278
|
+
sample_large_obj(obj, HASH2MD5_MAX_STRING_LENGTH) << "--" << txt_digest_str(obj)
|
279
|
+
else
|
280
|
+
obj
|
281
|
+
end
|
279
282
|
end
|
280
283
|
when Array
|
281
284
|
if obj.length > HASH2MD5_MAX_ARRAY_LENGTH
|
@@ -11,10 +11,16 @@ module SOPT
|
|
11
11
|
current = [chars.shift]
|
12
12
|
short = current * ""
|
13
13
|
|
14
|
-
if (shortcuts.include?(short) and not shortcuts[short] == long)
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
if (shortcuts.include?(short) and not shortcuts[short] == long)
|
15
|
+
if long.index "-" or long.index "_"
|
16
|
+
parts = long.split(/[_-]/)
|
17
|
+
acc = parts.collect{|s| s[0] } * ""
|
18
|
+
return acc unless shortcuts.include? acc
|
19
|
+
elsif m = long.match(/(\d+)/)
|
20
|
+
n = m[0]
|
21
|
+
acc = long[0] + n
|
22
|
+
return acc unless shortcuts.include? acc
|
23
|
+
end
|
18
24
|
end
|
19
25
|
|
20
26
|
while shortcuts.include?(short) and not shortcuts[short] == long
|
@@ -906,11 +906,16 @@ module Workflow
|
|
906
906
|
|
907
907
|
TAG = ENV["RBBT_INPUT_JOBNAME"] == "true" ? :inputs : :hash
|
908
908
|
def step_path(taskname, jobname, inputs, dependencies, extension = nil)
|
909
|
-
raise "Jobname makes an invalid path: #{ jobname }" if jobname
|
909
|
+
raise "Jobname makes an invalid path: #{ jobname }" if jobname.include? '..'
|
910
910
|
if inputs.length > 0 or dependencies.any?
|
911
911
|
tagged_jobname = case TAG
|
912
912
|
when :hash
|
913
|
-
|
913
|
+
clean_inputs = Annotated.purge(inputs)
|
914
|
+
clean_inputs = clean_inputs.collect{|i| Symbol === i ? i.to_s : i }
|
915
|
+
key_obj = {:inputs => clean_inputs, :dependencies => dependencies}
|
916
|
+
key_str = Misc.obj2str(key_obj)
|
917
|
+
hash_str = Misc.digest(key_str)
|
918
|
+
Log.debug "Hash for '#{[taskname, jobname] * "/"}' #{hash_str} for #{key_str}"
|
914
919
|
jobname + '_' << hash_str
|
915
920
|
when :inputs
|
916
921
|
all_inputs = {}
|
@@ -21,7 +21,8 @@ class Step
|
|
21
21
|
def resolve_input_steps
|
22
22
|
step = false
|
23
23
|
pos = 0
|
24
|
-
|
24
|
+
|
25
|
+
input_options = Workflow === workflow ? workflow.task_info(task_name)[:input_options] : {}
|
25
26
|
new_inputs = inputs.collect do |i|
|
26
27
|
begin
|
27
28
|
if Step === i
|
@@ -45,13 +45,14 @@ def pid_msg(pid)
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
|
48
49
|
def status_msg(status)
|
49
50
|
color = case status.to_sym
|
50
51
|
when :error, :aborted, :missing, :dead
|
51
52
|
:red
|
52
53
|
when :streaming, :started
|
53
54
|
:cyan
|
54
|
-
when :done
|
55
|
+
when :done, :noinfo
|
55
56
|
:green
|
56
57
|
when :dependencies, :waiting, :setyp
|
57
58
|
:yellow
|
@@ -64,7 +65,6 @@ def status_msg(status)
|
|
64
65
|
end
|
65
66
|
Log.color(color, status.to_s)
|
66
67
|
end
|
67
|
-
|
68
68
|
puts Log.color(:magenta, "# System report")
|
69
69
|
puts
|
70
70
|
sort_files = Proc.new do |a,b|
|
@@ -166,14 +166,14 @@ workflows.sort.each do |workflow,tasks|
|
|
166
166
|
str << " (dirty)" if status == 'done' && Workflow.load_step(file).dirty?
|
167
167
|
|
168
168
|
if inputs and inputs.any? and info[:inputs]
|
169
|
-
job_inputs =
|
169
|
+
job_inputs = Workflow.load_step(file).recursive_inputs.to_hash
|
170
170
|
IndiferentHash.setup(job_inputs)
|
171
171
|
|
172
172
|
inputs.each do |input|
|
173
173
|
value = job_inputs[input]
|
174
174
|
next if value.nil?
|
175
175
|
value_str = Misc.fingerprint(value)
|
176
|
-
str << "
|
176
|
+
str << "\t#{Log.color :magenta, input}=#{value_str}"
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
@@ -45,7 +45,7 @@ def status_msg(status)
|
|
45
45
|
:red
|
46
46
|
when :streaming, :started
|
47
47
|
:cyan
|
48
|
-
when :done
|
48
|
+
when :done, :noinfo
|
49
49
|
:green
|
50
50
|
when :dependencies, :waiting, :setyp
|
51
51
|
:yellow
|
@@ -73,7 +73,7 @@ def report_msg(status, name, path, info = nil)
|
|
73
73
|
end
|
74
74
|
|
75
75
|
if $inputs and $inputs.any?
|
76
|
-
job_inputs =
|
76
|
+
job_inputs = Workflow.load_step(path).recursive_inputs.to_hash
|
77
77
|
IndiferentHash.setup(job_inputs)
|
78
78
|
|
79
79
|
$inputs.each do |input|
|
@@ -134,6 +134,7 @@ def adjacency(step)
|
|
134
134
|
end
|
135
135
|
name = name.split(":").last
|
136
136
|
status = :unsync if status == :done and not File.exist? path
|
137
|
+
shapes = Hash.new "circle"
|
137
138
|
edge_info = {:status => status, :workflow => workflow, :task => task, :name => name, :label => task, :shape => shapes[workflow], :color => status == 'remote' ? 'blue' : 'green'}
|
138
139
|
id = Misc.digest(path)
|
139
140
|
edges = []
|
@@ -143,7 +144,7 @@ def adjacency(step)
|
|
143
144
|
info[:dependencies].each do |task,name,path|
|
144
145
|
dep = get_step path
|
145
146
|
_id, _edges, _node_info = adjacency(dep)
|
146
|
-
edges << [
|
147
|
+
edges << [_id, id]
|
147
148
|
edges.concat _edges
|
148
149
|
node_info.merge!(_node_info)
|
149
150
|
end
|
@@ -173,9 +174,6 @@ if options[:plot]
|
|
173
174
|
|
174
175
|
require 'rbbt/util/R'
|
175
176
|
|
176
|
-
ppp Open.read edge_file
|
177
|
-
ppp Open.read node_info_file
|
178
|
-
|
179
177
|
R.run <<-EOF
|
180
178
|
nodes <- read.csv("#{node_info_file}", header=T, as.is=T)
|
181
179
|
links <- read.csv("#{edge_file}", header=T, as.is=T)
|
@@ -185,7 +183,7 @@ if options[:plot]
|
|
185
183
|
net <- graph.data.frame(links, nodes, directed=T)
|
186
184
|
net <- simplify(net, remove.multiple = F, remove.loops = T)
|
187
185
|
|
188
|
-
png("#{options[:plot]}")
|
186
|
+
png("#{options[:plot]}", width=1000, height=1000)
|
189
187
|
plot(net, edge.arrow.size=0.4, vertex.label=net$label, vertex.color=net$color)
|
190
188
|
dev.off()
|
191
189
|
EOF
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbt-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.22.
|
4
|
+
version: 5.22.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|