scout-gear 8.0.0 → 8.1.0
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/.vimproject +26 -9
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/bin/scout +15 -4
- data/doc/lib/scout/path.md +35 -0
- data/doc/lib/scout/workflow/task.md +13 -0
- data/lib/scout/cmd.rb +23 -24
- data/lib/scout/concurrent_stream.rb +36 -19
- data/lib/scout/exceptions.rb +10 -0
- data/lib/scout/log/color.rb +11 -11
- data/lib/scout/log/progress/report.rb +7 -5
- data/lib/scout/log/progress/util.rb +3 -0
- data/lib/scout/log/trap.rb +3 -3
- data/lib/scout/log.rb +64 -36
- data/lib/scout/meta_extension.rb +34 -0
- data/lib/scout/misc/digest.rb +11 -2
- data/lib/scout/misc/format.rb +12 -7
- data/lib/scout/misc/monitor.rb +11 -0
- data/lib/scout/misc/system.rb +48 -0
- data/lib/scout/named_array.rb +8 -0
- data/lib/scout/offsite/ssh.rb +171 -0
- data/lib/scout/offsite/step.rb +83 -0
- data/lib/scout/offsite/sync.rb +55 -0
- data/lib/scout/offsite.rb +3 -0
- data/lib/scout/open/lock.rb +5 -24
- data/lib/scout/open/remote.rb +12 -1
- data/lib/scout/open/stream.rb +110 -122
- data/lib/scout/open/util.rb +9 -0
- data/lib/scout/open.rb +5 -4
- data/lib/scout/path/find.rb +15 -10
- data/lib/scout/path/util.rb +5 -0
- data/lib/scout/persist/serialize.rb +3 -3
- data/lib/scout/persist.rb +1 -1
- data/lib/scout/resource/path.rb +4 -0
- data/lib/scout/resource/util.rb +10 -4
- data/lib/scout/tsv/dumper.rb +2 -0
- data/lib/scout/tsv/index.rb +28 -86
- data/lib/scout/tsv/open.rb +35 -14
- data/lib/scout/tsv/parser.rb +9 -2
- data/lib/scout/tsv/persist/tokyocabinet.rb +2 -0
- data/lib/scout/tsv/stream.rb +204 -0
- data/lib/scout/tsv/transformer.rb +11 -0
- data/lib/scout/tsv.rb +9 -2
- data/lib/scout/work_queue/worker.rb +2 -2
- data/lib/scout/work_queue.rb +36 -12
- data/lib/scout/workflow/definition.rb +2 -1
- data/lib/scout/workflow/deployment/orchestrator.rb +245 -0
- data/lib/scout/workflow/deployment.rb +1 -0
- data/lib/scout/workflow/step/dependencies.rb +37 -11
- data/lib/scout/workflow/step/file.rb +5 -0
- data/lib/scout/workflow/step/info.rb +5 -3
- data/lib/scout/workflow/step/load.rb +1 -1
- data/lib/scout/workflow/step/provenance.rb +1 -0
- data/lib/scout/workflow/step/status.rb +6 -8
- data/lib/scout/workflow/step.rb +75 -30
- data/lib/scout/workflow/task/dependencies.rb +114 -0
- data/lib/scout/workflow/task/inputs.rb +27 -13
- data/lib/scout/workflow/task.rb +9 -108
- data/lib/scout/workflow/usage.rb +40 -12
- data/lib/scout/workflow.rb +4 -2
- data/lib/scout-gear.rb +2 -0
- data/lib/scout.rb +6 -0
- data/scout-gear.gemspec +32 -7
- data/scout_commands/doc +37 -0
- data/scout_commands/find +1 -0
- data/scout_commands/offsite +30 -0
- data/scout_commands/update +29 -0
- data/scout_commands/workflow/info +15 -3
- data/scout_commands/workflow/install +102 -0
- data/scout_commands/workflow/task +26 -5
- data/test/scout/offsite/test_ssh.rb +15 -0
- data/test/scout/offsite/test_step.rb +33 -0
- data/test/scout/offsite/test_sync.rb +36 -0
- data/test/scout/offsite/test_task.rb +0 -0
- data/test/scout/resource/test_path.rb +6 -0
- data/test/scout/test_named_array.rb +6 -0
- data/test/scout/test_persist.rb +3 -2
- data/test/scout/test_tsv.rb +17 -0
- data/test/scout/test_work_queue.rb +63 -41
- data/test/scout/tsv/persist/test_adapter.rb +1 -1
- data/test/scout/tsv/test_index.rb +14 -0
- data/test/scout/tsv/test_parser.rb +14 -0
- data/test/scout/tsv/test_stream.rb +200 -0
- data/test/scout/tsv/test_transformer.rb +12 -0
- data/test/scout/workflow/deployment/test_orchestrator.rb +272 -0
- data/test/scout/workflow/step/test_dependencies.rb +68 -0
- data/test/scout/workflow/step/test_info.rb +18 -0
- data/test/scout/workflow/step/test_status.rb +0 -1
- data/test/scout/workflow/task/test_dependencies.rb +355 -0
- data/test/scout/workflow/task/test_inputs.rb +53 -0
- data/test/scout/workflow/test_definition.rb +18 -0
- data/test/scout/workflow/test_documentation.rb +24 -0
- data/test/scout/workflow/test_step.rb +109 -0
- data/test/scout/workflow/test_task.rb +0 -287
- data/test/test_scout.rb +9 -0
- metadata +83 -5
- data/scout_commands/workflow/task_old +0 -706
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ca509bfb5065aabcdae73545139db0f8b04748084821e002c0475a55be5cb70
|
4
|
+
data.tar.gz: 6f0333ca6dd0ceee0ea9290cf3c30f7164c2f0732b76ce739e29da19a0687242
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cbd82d97ec0dad50e624cda26ae6a05aeba8b9e5ff07a5b4746c677b8e2ab1996378237095ba09a70f8ed8cc926d782c1677aa24d6f94784f560090d6845a2c
|
7
|
+
data.tar.gz: aa9529b3393016c846b578b736428b964519d2fb5c1507a6335eff651d0588a5d9191cc61cff52279c18902f2efce386415099bcd92f8736f6d67cef1d33b561
|
data/.vimproject
CHANGED
@@ -8,11 +8,14 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
8
8
|
alias
|
9
9
|
find
|
10
10
|
glob
|
11
|
+
doc
|
12
|
+
update
|
13
|
+
offsite
|
11
14
|
workflow=workflow{
|
12
15
|
task
|
13
16
|
list
|
14
17
|
info
|
15
|
-
|
18
|
+
install
|
16
19
|
}
|
17
20
|
}
|
18
21
|
lib=lib {
|
@@ -99,24 +102,29 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
99
102
|
workflow.rb
|
100
103
|
workflow=workflow{
|
101
104
|
definition.rb
|
105
|
+
documentation.rb
|
106
|
+
usage.rb
|
107
|
+
util.rb
|
102
108
|
step.rb
|
103
109
|
step=step{
|
104
|
-
info.rb
|
105
|
-
status.rb
|
106
|
-
load.rb
|
107
|
-
file.rb
|
108
110
|
config.rb
|
109
111
|
dependencies.rb
|
110
|
-
|
112
|
+
file.rb
|
113
|
+
info.rb
|
114
|
+
load.rb
|
111
115
|
progress.rb
|
116
|
+
provenance.rb
|
117
|
+
status.rb
|
112
118
|
}
|
113
119
|
task.rb
|
114
120
|
task=task{
|
121
|
+
dependencies.rb
|
115
122
|
inputs.rb
|
116
123
|
}
|
117
|
-
|
118
|
-
|
119
|
-
|
124
|
+
deployment.rb
|
125
|
+
deployment=deployment{
|
126
|
+
orchestrator.rb
|
127
|
+
}
|
120
128
|
}
|
121
129
|
semaphore.rb
|
122
130
|
work_queue.rb
|
@@ -141,6 +149,8 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
141
149
|
persist=persist{
|
142
150
|
adapter.rb
|
143
151
|
serialize.rb
|
152
|
+
sdbm.rb
|
153
|
+
tkrzw.rb
|
144
154
|
tokyocabinet.rb
|
145
155
|
fix_width_table.rb
|
146
156
|
}
|
@@ -149,8 +159,15 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
149
159
|
attach.rb
|
150
160
|
change_id.rb
|
151
161
|
path.rb
|
162
|
+
stream.rb
|
152
163
|
open.rb
|
153
164
|
}
|
165
|
+
offsite.rb
|
166
|
+
offsite=offsite{
|
167
|
+
ssh.rb
|
168
|
+
sync.rb
|
169
|
+
step.rb
|
170
|
+
}
|
154
171
|
}
|
155
172
|
}
|
156
173
|
test=test {
|
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ Juwelier::Tasks.new do |gem|
|
|
12
12
|
gem.homepage = "http://github.com/mikisvaz/scout-gear"
|
13
13
|
gem.license = "MIT"
|
14
14
|
gem.summary = %Q{basic gear for scouts}
|
15
|
-
gem.description = %Q{Temporary files, logs, etc.}
|
15
|
+
gem.description = %Q{Temporary files, logs, path, resources, persistence, workflows, TSV, etc.}
|
16
16
|
gem.email = "mikisvaz@gmail.com"
|
17
17
|
gem.authors = ["Miguel Vazquez"]
|
18
18
|
|
@@ -21,6 +21,11 @@ Juwelier::Tasks.new do |gem|
|
|
21
21
|
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
22
22
|
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
23
23
|
gem.add_runtime_dependency 'term-ansicolor'
|
24
|
+
gem.add_runtime_dependency 'net-ssh'
|
25
|
+
gem.add_runtime_dependency 'matrix'
|
26
|
+
gem.add_runtime_dependency 'sys-proctable'
|
27
|
+
gem.add_runtime_dependency 'RubyInline'
|
28
|
+
#gem.add_runtime_dependency 'tokyocabinet'
|
24
29
|
|
25
30
|
gem.add_development_dependency "rdoc", "~> 3.12"
|
26
31
|
gem.add_development_dependency "bundler", "~> 1.0"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
8.
|
1
|
+
8.1.0
|
data/bin/scout
CHANGED
@@ -35,6 +35,12 @@ if dev_dir.nil?
|
|
35
35
|
ARGV.delete _s if _s
|
36
36
|
end
|
37
37
|
|
38
|
+
if dev_dir.nil? && ENV["SCOUT_DEV"]
|
39
|
+
dev_dir = ENV["SCOUT_DEV"]
|
40
|
+
ARGV.delete "--dev"
|
41
|
+
ARGV.delete dev_dir
|
42
|
+
end
|
43
|
+
|
38
44
|
if dev_dir
|
39
45
|
['scout-*/lib'].each do |pattern|
|
40
46
|
Dir.glob(File.join(File.expand_path(dev_dir), pattern)).each do |f|
|
@@ -62,6 +68,7 @@ $ #{$0} <command> <subcommand> ... -a --arg1 --arg2='value' --arg3 'another-valu
|
|
62
68
|
--nocolor #{Log.color :yellow, "Disable colored output"}
|
63
69
|
--nobar #{Log.color :yellow, "Disable progress report"}
|
64
70
|
--locate_file #{Log.color :yellow, "Report the location of the script instead of executing it"}
|
71
|
+
-ck--config_keys* #{Log.color :yellow, "Override some config keys"}
|
65
72
|
EOF
|
66
73
|
|
67
74
|
Log.nocolor = true if options[:nocolor]
|
@@ -84,6 +91,14 @@ else
|
|
84
91
|
end
|
85
92
|
end
|
86
93
|
|
94
|
+
if config_keys = options.delete(:config_keys)
|
95
|
+
config_keys.split(",").each do |config|
|
96
|
+
config = config.strip
|
97
|
+
Scout::Config.process_config config
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
87
102
|
$scout_command_dir = Scout.bin.scout
|
88
103
|
$scout_command_dir.path_maps[:scout_commands] = File.join(File.dirname(__dir__), "{PATH/bin\\/scout/scout_commands}")
|
89
104
|
|
@@ -217,7 +232,6 @@ begin
|
|
217
232
|
|
218
233
|
scout_usage($previous_commands)
|
219
234
|
exit_status = 0
|
220
|
-
exit exit_status
|
221
235
|
|
222
236
|
rescue ParameterException
|
223
237
|
puts
|
@@ -225,14 +239,11 @@ rescue ParameterException
|
|
225
239
|
print_error($!.message, $!.backtrace)
|
226
240
|
puts
|
227
241
|
exit_status = -1
|
228
|
-
exit exit_status
|
229
242
|
rescue SystemExit,CmdStop
|
230
243
|
exit_status = $!.status
|
231
|
-
exit exit_status
|
232
244
|
rescue Exception
|
233
245
|
Log.exception $!
|
234
246
|
exit_status = -1
|
235
|
-
exit exit_status
|
236
247
|
ensure
|
237
248
|
if options[:profile]
|
238
249
|
result = RubyProf.stop
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Path
|
2
|
+
===
|
3
|
+
|
4
|
+
```ruby
|
5
|
+
:current => '{PWD}/{TOPLEVEL}/{SUBPATH}',
|
6
|
+
:user => '{HOME}/.{PKGDIR}/{TOPLEVEL}/{SUBPATH}',
|
7
|
+
:global => '/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
8
|
+
:usr => '/usr/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
9
|
+
:local => '/usr/local/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
10
|
+
:fast => '/fast/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
11
|
+
:cache => '/cache/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
12
|
+
:bulk => '/bulk/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
13
|
+
:lib => '{LIBDIR}/{TOPLEVEL}/{SUBPATH}',
|
14
|
+
:scout_gear => File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}"),
|
15
|
+
:tmp => '/tmp/{PKGDIR}/{TOPLEVEL}/{SUBPATH}',
|
16
|
+
:default => :user
|
17
|
+
|
18
|
+
@@basic_map_order ||= %w(current workflow user local global lib fast cache bulk)
|
19
|
+
|
20
|
+
```
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
# tags
|
25
|
+
{PKGDIR}
|
26
|
+
{LIBDIR}
|
27
|
+
{RESOURCE}
|
28
|
+
{HOME}
|
29
|
+
{PWD}
|
30
|
+
{TOPLEVEL}
|
31
|
+
{SUBPATH}
|
32
|
+
{BASENAME}
|
33
|
+
{PATH}
|
34
|
+
{MAPNAME}
|
35
|
+
{REMOVE}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Task
|
2
|
+
====
|
3
|
+
|
4
|
+
```ruby
|
5
|
+
wf = Workflow.annonymous_workflow "TaskInputs" do
|
6
|
+
input :input1, :integer
|
7
|
+
task :step1 => :integer do |i| i end
|
8
|
+
|
9
|
+
dep :step1
|
10
|
+
input :input2, :integer, "Integer", 3
|
11
|
+
task :step2 => :integer do |i| i * step(:step1).load end
|
12
|
+
end
|
13
|
+
```
|
data/lib/scout/cmd.rb
CHANGED
@@ -14,9 +14,9 @@ module CMD
|
|
14
14
|
|
15
15
|
def self.conda(tool, env = nil, channel = 'bioconda')
|
16
16
|
if env
|
17
|
-
CMD.cmd("bash -l -c '(conda activate #{env} && conda install #{tool} -c #{channel})'")
|
17
|
+
CMD.cmd("bash -l -c '(conda activate #{env} && conda install #{tool} -c #{channel})'")
|
18
18
|
else
|
19
|
-
CMD.cmd("bash -l -c 'conda install #{tool} -c #{channel}'")
|
19
|
+
CMD.cmd("bash -l -c 'conda install #{tool} -c #{channel}'")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -61,6 +61,7 @@ module CMD
|
|
61
61
|
|
62
62
|
def self.scan_version_text(text, cmd = nil)
|
63
63
|
cmd = "NOCMDGIVE" if cmd.nil? || cmd.empty?
|
64
|
+
text = Misc.fixutf8 text
|
64
65
|
text.split("\n").each do |line|
|
65
66
|
next unless line =~ /\W#{cmd}\W/i
|
66
67
|
m = line.match(/(v(?:\d+\.)*\d+(?:-[a-z_]+)?)/i)
|
@@ -98,8 +99,8 @@ module CMD
|
|
98
99
|
|
99
100
|
option = "--" << option.to_s if add_dashes and option.to_s[0] != '-'
|
100
101
|
|
101
|
-
case
|
102
|
-
when value.nil? || FalseClass === value
|
102
|
+
case
|
103
|
+
when value.nil? || FalseClass === value
|
103
104
|
next
|
104
105
|
when TrueClass === value
|
105
106
|
string << "#{option} "
|
@@ -136,8 +137,8 @@ module CMD
|
|
136
137
|
dont_close_in = options.delete(:dont_close_in)
|
137
138
|
|
138
139
|
log = true if log.nil?
|
139
|
-
|
140
|
-
if cmd.nil? && ! Symbol === tool
|
140
|
+
|
141
|
+
if cmd.nil? && ! Symbol === tool
|
141
142
|
cmd = tool
|
142
143
|
else
|
143
144
|
tool = get_tool(tool)
|
@@ -163,7 +164,7 @@ module CMD
|
|
163
164
|
|
164
165
|
cmd_options = process_cmd_options options
|
165
166
|
if cmd =~ /'\{opt\}'/
|
166
|
-
cmd.sub!('\'{opt}\'', cmd_options)
|
167
|
+
cmd.sub!('\'{opt}\'', cmd_options)
|
167
168
|
else
|
168
169
|
cmd << " " << cmd_options
|
169
170
|
end
|
@@ -179,29 +180,28 @@ module CMD
|
|
179
180
|
end
|
180
181
|
pid = wait_thr.pid
|
181
182
|
|
182
|
-
Log.debug{"CMD: [#{pid}] #{cmd}" if log}
|
183
|
+
Log.debug{"CMD: [#{pid}] #{cmd}".strip if log}
|
183
184
|
|
184
185
|
if in_content.respond_to?(:read)
|
185
186
|
in_thread = Thread.new(Thread.current) do |parent|
|
186
|
-
Thread.current.report_on_exception = false if no_fail
|
187
187
|
begin
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
rescue EOFError
|
188
|
+
Thread.current.report_on_exception = false if no_fail
|
189
|
+
Thread.current["name"] = "CMD in"
|
190
|
+
while c = in_content.read(Open::BLOCK_SIZE)
|
191
|
+
sin << c
|
193
192
|
end
|
194
193
|
sin.close unless sin.closed?
|
195
194
|
|
196
195
|
unless dont_close_in
|
197
|
-
in_content.close unless in_content.closed?
|
198
|
-
in_content.join if in_content.respond_to? :join
|
196
|
+
in_content.close unless in_content.closed?
|
197
|
+
in_content.join if in_content.respond_to? :join
|
199
198
|
end
|
200
199
|
rescue
|
201
200
|
Log.error "Error in CMD [#{pid}] #{cmd}: #{$!.message}" unless no_fail
|
202
201
|
raise $!
|
203
202
|
end
|
204
203
|
end
|
204
|
+
Thread.pass until in_thread["name"]
|
205
205
|
else
|
206
206
|
in_thread = nil
|
207
207
|
sin.close
|
@@ -211,7 +211,7 @@ module CMD
|
|
211
211
|
|
212
212
|
if pipe
|
213
213
|
|
214
|
-
ConcurrentStream.setup sout, :pids => pids, :autojoin => autojoin, :no_fail => no_fail
|
214
|
+
ConcurrentStream.setup sout, :pids => pids, :autojoin => autojoin, :no_fail => no_fail
|
215
215
|
|
216
216
|
sout.callback = post if post
|
217
217
|
|
@@ -224,7 +224,7 @@ module CMD
|
|
224
224
|
sout.log = line
|
225
225
|
sout.std_err << line if save_stderr
|
226
226
|
Log.log "STDERR [#{pid}]: " + line, stderr if log
|
227
|
-
end
|
227
|
+
end
|
228
228
|
serr.close
|
229
229
|
rescue
|
230
230
|
Log.exception $!
|
@@ -244,8 +244,8 @@ module CMD
|
|
244
244
|
err = ""
|
245
245
|
err_thread = Thread.new do
|
246
246
|
while not serr.eof?
|
247
|
-
line = serr.gets
|
248
|
-
bar.process(line)
|
247
|
+
line = serr.gets
|
248
|
+
bar.process(line)
|
249
249
|
err << line if Integer === stderr and log
|
250
250
|
end
|
251
251
|
serr.close
|
@@ -254,18 +254,17 @@ module CMD
|
|
254
254
|
err = ""
|
255
255
|
err_thread = Thread.new do
|
256
256
|
while not serr.eof?
|
257
|
-
err << serr.gets
|
257
|
+
err << serr.gets
|
258
258
|
end
|
259
259
|
serr.close
|
260
260
|
end
|
261
261
|
else
|
262
262
|
Open.consume_stream(serr, true)
|
263
|
-
#serr.close
|
264
263
|
err_thread = nil
|
265
264
|
err = ""
|
266
265
|
end
|
267
266
|
|
268
|
-
ConcurrentStream.setup sout, :pids => pids, :threads => [in_thread, err_thread].compact, :autojoin => autojoin, :no_fail => no_fail
|
267
|
+
ConcurrentStream.setup sout, :pids => pids, :threads => [in_thread, err_thread].compact, :autojoin => autojoin, :no_fail => no_fail
|
269
268
|
|
270
269
|
begin
|
271
270
|
out = StringIO.new sout.read
|
@@ -324,7 +323,7 @@ module CMD
|
|
324
323
|
starting = true
|
325
324
|
line = "" if bar
|
326
325
|
end
|
327
|
-
end
|
326
|
+
end
|
328
327
|
begin
|
329
328
|
io.join
|
330
329
|
bar.remove if bar
|
@@ -12,13 +12,12 @@ module ConcurrentStream
|
|
12
12
|
attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin, :lock, :no_fail, :pair, :thread, :stream_exception, :log, :std_err, :next
|
13
13
|
|
14
14
|
def self.setup(stream, options = {}, &block)
|
15
|
-
|
16
15
|
threads, pids, callback, abort_callback, filename, autojoin, lock, no_fail, pair, next_stream = IndiferentHash.process_options options, :threads, :pids, :callback, :abort_callback, :filename, :autojoin, :lock, :no_fail, :pair, :next
|
17
16
|
stream.extend ConcurrentStream unless ConcurrentStream === stream
|
18
17
|
|
19
18
|
stream.threads ||= []
|
20
19
|
stream.pids ||= []
|
21
|
-
stream.threads.concat(Array === threads ? threads : [threads]) unless threads.nil?
|
20
|
+
stream.threads.concat(Array === threads ? threads : [threads]) unless threads.nil?
|
22
21
|
stream.pids.concat(Array === pids ? pids : [pids]) unless pids.nil? or pids.empty?
|
23
22
|
stream.autojoin = autojoin unless autojoin.nil?
|
24
23
|
stream.no_fail = no_fail unless no_fail.nil?
|
@@ -36,7 +35,7 @@ module ConcurrentStream
|
|
36
35
|
callback.call
|
37
36
|
end
|
38
37
|
else
|
39
|
-
stream.callback = callback
|
38
|
+
stream.callback = callback
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
@@ -48,7 +47,7 @@ module ConcurrentStream
|
|
48
47
|
abort_callback.call
|
49
48
|
end
|
50
49
|
else
|
51
|
-
stream.abort_callback = abort_callback
|
50
|
+
stream.abort_callback = abort_callback
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
@@ -80,7 +79,7 @@ module ConcurrentStream
|
|
80
79
|
|
81
80
|
def join_threads
|
82
81
|
if @threads
|
83
|
-
@threads.each do |t|
|
82
|
+
@threads.each do |t|
|
84
83
|
next if t == Thread.current
|
85
84
|
begin
|
86
85
|
t.join
|
@@ -101,7 +100,7 @@ module ConcurrentStream
|
|
101
100
|
Log.low "Not failing on exception joining thread in ConcurrenStream - #{filename} - #{$!.message}"
|
102
101
|
else
|
103
102
|
Log.low "Exception joining thread in ConcurrenStream #{Log.fingerprint self} - #{Log.fingerprint t} - #{$!.message}"
|
104
|
-
stream_raise_exception $!
|
103
|
+
stream_raise_exception $!
|
105
104
|
end
|
106
105
|
end
|
107
106
|
end
|
@@ -111,13 +110,13 @@ module ConcurrentStream
|
|
111
110
|
|
112
111
|
def join_pids
|
113
112
|
if @pids and @pids.any?
|
114
|
-
@pids.each do |pid|
|
113
|
+
@pids.each do |pid|
|
115
114
|
begin
|
116
115
|
Process.waitpid(pid, Process::WUNTRACED)
|
117
116
|
stream_raise_exception ConcurrentStreamProcessFailed.new(pid, "Error in waitpid", self) unless $?.success? or no_fail
|
118
117
|
rescue Errno::ECHILD
|
119
118
|
end
|
120
|
-
end
|
119
|
+
end
|
121
120
|
@pids = []
|
122
121
|
end
|
123
122
|
end
|
@@ -143,7 +142,7 @@ module ConcurrentStream
|
|
143
142
|
@joined = true
|
144
143
|
begin
|
145
144
|
lock.unlock if lock && lock.locked?
|
146
|
-
rescue
|
145
|
+
rescue
|
147
146
|
Log.exception $!
|
148
147
|
end
|
149
148
|
raise stream_exception if stream_exception
|
@@ -158,7 +157,7 @@ module ConcurrentStream
|
|
158
157
|
|
159
158
|
threads = @threads.dup
|
160
159
|
@threads.clear
|
161
|
-
threads.each do |t|
|
160
|
+
threads.each do |t|
|
162
161
|
next if t == Thread.current
|
163
162
|
next if t["aborted"]
|
164
163
|
t["aborted"] = true
|
@@ -166,14 +165,14 @@ module ConcurrentStream
|
|
166
165
|
Log.debug "Aborting thread #{Log.fingerprint(t)} with exception: #{exception}"
|
167
166
|
t.raise(exception)
|
168
167
|
t.join
|
169
|
-
end
|
168
|
+
end
|
170
169
|
end
|
171
170
|
|
172
171
|
def abort_pids
|
173
172
|
@pids.each do |pid|
|
174
|
-
begin
|
173
|
+
begin
|
175
174
|
Log.low "Killing PID #{pid} in ConcurrentStream #{filename}"
|
176
|
-
Process.kill :INT, pid
|
175
|
+
Process.kill :INT, pid
|
177
176
|
rescue Errno::ESRCH
|
178
177
|
end
|
179
178
|
end if @pids
|
@@ -189,7 +188,7 @@ module ConcurrentStream
|
|
189
188
|
Log.medium "Aborting stream #{Log.fingerprint self} [#{@aborted}]"
|
190
189
|
end
|
191
190
|
AbortedStream.setup(self, exception)
|
192
|
-
@aborted = true
|
191
|
+
@aborted = true
|
193
192
|
begin
|
194
193
|
@abort_callback.call exception if @abort_callback
|
195
194
|
|
@@ -207,7 +206,7 @@ module ConcurrentStream
|
|
207
206
|
close unless closed?
|
208
207
|
|
209
208
|
if lock and lock.locked?
|
210
|
-
lock.unlock
|
209
|
+
lock.unlock
|
211
210
|
end
|
212
211
|
end
|
213
212
|
end
|
@@ -218,7 +217,7 @@ module ConcurrentStream
|
|
218
217
|
super(*args)
|
219
218
|
rescue
|
220
219
|
self.abort
|
221
|
-
self.join
|
220
|
+
self.join
|
222
221
|
stream_raise_exception $!
|
223
222
|
ensure
|
224
223
|
self.join if ! @stream_exception && (self.closed? || self.eof?)
|
@@ -249,19 +248,37 @@ module ConcurrentStream
|
|
249
248
|
|
250
249
|
def add_callback(&block)
|
251
250
|
old_callback = callback
|
252
|
-
@callback = Proc.new do
|
251
|
+
@callback = Proc.new do
|
253
252
|
old_callback.call if old_callback
|
254
253
|
block.call
|
255
254
|
end
|
256
255
|
end
|
257
256
|
|
258
257
|
def stream_raise_exception(exception)
|
258
|
+
self.stream_exception = exception
|
259
259
|
threads.each do |thread|
|
260
260
|
thread.raise exception
|
261
261
|
end
|
262
|
-
self.stream_exception = exception
|
263
|
-
|
264
262
|
self.abort
|
265
263
|
end
|
266
264
|
|
265
|
+
def self.process_stream(stream, close: true, join: true, message: "process_stream", **kwargs, &block)
|
266
|
+
ConcurrentStream.setup(stream, **kwargs)
|
267
|
+
begin
|
268
|
+
begin
|
269
|
+
yield
|
270
|
+
ensure
|
271
|
+
stream.close if close && stream.respond_to?(:close) && ! (stream.respond_to?(:closed?) && stream.closed?)
|
272
|
+
stream.join if join && stream.respond_to?(:join) && ! stream.joined?
|
273
|
+
end
|
274
|
+
rescue Aborted
|
275
|
+
Log.low "Aborted #{message}: #{$!.message}"
|
276
|
+
stream.abort($!) if stream.respond_to?(:abort) && ! stream.aborted?
|
277
|
+
raise $!
|
278
|
+
rescue Exception
|
279
|
+
Log.low "Exception #{message}: #{$!.message}"
|
280
|
+
stream.abort($!) if stream.respond_to?(:abort) && ! stream.aborted?
|
281
|
+
raise $!
|
282
|
+
end
|
283
|
+
end
|
267
284
|
end
|
data/lib/scout/exceptions.rb
CHANGED
@@ -139,3 +139,13 @@ class SemaphoreInterrupted < TryAgain; end
|
|
139
139
|
#
|
140
140
|
#
|
141
141
|
class ResourceNotFound < ScoutException; end
|
142
|
+
|
143
|
+
class SSHProcessFailed < StandardError
|
144
|
+
attr_accessor :host, :cmd
|
145
|
+
def initialize(host, cmd)
|
146
|
+
@host = host
|
147
|
+
@cmd = cmd
|
148
|
+
message = "SSH server #{host} failed cmd '#{cmd}'"
|
149
|
+
super(message)
|
150
|
+
end
|
151
|
+
end
|
data/lib/scout/log/color.rb
CHANGED
@@ -10,8 +10,8 @@ module Colorize
|
|
10
10
|
|
11
11
|
def self.colors
|
12
12
|
@colors ||= IndiferentHash.setup(Hash[<<-EOF.split("\n").collect{|l| l.split(" ")}])
|
13
|
-
green #00cd00
|
14
|
-
red #cd0000
|
13
|
+
green #00cd00
|
14
|
+
red #cd0000
|
15
15
|
yellow #ffd700
|
16
16
|
blue #0000cd
|
17
17
|
path blue
|
@@ -49,26 +49,26 @@ EOF
|
|
49
49
|
when "black"
|
50
50
|
'#fff'
|
51
51
|
when 'green'
|
52
|
-
colors["green3"]
|
52
|
+
colors["green3"]
|
53
53
|
when 'red'
|
54
|
-
colors["red3"]
|
54
|
+
colors["red3"]
|
55
55
|
when 'yellow'
|
56
|
-
colors["gold1"]
|
56
|
+
colors["gold1"]
|
57
57
|
when 'blue'
|
58
|
-
colors["RoyalBlue"]
|
58
|
+
colors["RoyalBlue"]
|
59
59
|
else
|
60
60
|
colors[color.to_s] || color.to_s
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def self.continuous(array, start = "#40324F", eend = "#EABD5D", percent = false)
|
64
|
+
def self.continuous(array, start = "#40324F", eend = "#EABD5D", percent = false)
|
65
65
|
start_color = Color.new from_name(start)
|
66
66
|
end_color = Color.new from_name(eend)
|
67
67
|
|
68
68
|
if percent
|
69
69
|
array = array.collect{|v| n = v.to_f; n = n > 100 ? 100 : n; n < 0.001 ? 0.001 : n}
|
70
70
|
else
|
71
|
-
array = array.collect{|v| v.to_f }
|
71
|
+
array = array.collect{|v| v.to_f }
|
72
72
|
end
|
73
73
|
max = array.max
|
74
74
|
min = array.min
|
@@ -157,7 +157,7 @@ module Log
|
|
157
157
|
:workflow => yellow,
|
158
158
|
})
|
159
159
|
HIGHLIGHT = "\033[1m"
|
160
|
-
|
160
|
+
|
161
161
|
def self.uncolor(str)
|
162
162
|
"" << Term::ANSIColor.uncolor(str)
|
163
163
|
end
|
@@ -167,7 +167,7 @@ module Log
|
|
167
167
|
end
|
168
168
|
|
169
169
|
def self.color(color, str = nil, reset = false)
|
170
|
-
return str.dup || "" if nocolor
|
170
|
+
return str.dup || "" if nocolor
|
171
171
|
|
172
172
|
if (color == :integer || color == :float) && Numeric === str
|
173
173
|
color = if str < 0
|
@@ -179,7 +179,7 @@ module Log
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
-
if color == :status
|
182
|
+
if color == :status
|
183
183
|
color = case str.to_sym
|
184
184
|
when :done
|
185
185
|
:green
|
@@ -4,8 +4,7 @@ module Log
|
|
4
4
|
def print(io, str)
|
5
5
|
return if self.severity && self.severity < Log.severity
|
6
6
|
return if Log.no_bar
|
7
|
-
|
8
|
-
Log.logfile.puts str unless Log.logfile.nil?
|
7
|
+
Log.log_write str
|
9
8
|
Log::LAST.replace "progress"
|
10
9
|
end
|
11
10
|
|
@@ -57,9 +56,12 @@ module Log
|
|
57
56
|
thr = short_mean
|
58
57
|
else
|
59
58
|
thr = begin
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
d = Time.now - @start
|
60
|
+
if d == 0
|
61
|
+
1
|
62
|
+
else
|
63
|
+
(@ticks || 1) / d
|
64
|
+
end
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
@@ -74,6 +74,7 @@ module Log
|
|
74
74
|
BAR_MUTEX.synchronize do
|
75
75
|
REMOVE << bar
|
76
76
|
end
|
77
|
+
cleanup_bars
|
77
78
|
Log::LAST.replace "remove_bar" if Log::LAST == "progress"
|
78
79
|
end
|
79
80
|
|
@@ -128,6 +129,8 @@ module Log
|
|
128
129
|
nil
|
129
130
|
end
|
130
131
|
end
|
132
|
+
rescue Interrupt
|
133
|
+
raise $!
|
131
134
|
rescue Exception
|
132
135
|
nil
|
133
136
|
end
|
data/lib/scout/log/trap.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Log
|
2
2
|
def self.trap_std(msg = "STDOUT", msge = "STDERR", severity = 0, severity_err = nil)
|
3
|
-
sout, sin =
|
4
|
-
soute, sine =
|
3
|
+
sout, sin = Open.pipe
|
4
|
+
soute, sine = Open.pipe
|
5
5
|
backup_stderr = STDERR.dup
|
6
6
|
backup_stdout = STDOUT.dup
|
7
7
|
old_logfile = Log.logfile
|
@@ -38,7 +38,7 @@ module Log
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.trap_stderr(msg = "STDERR", severity = 0)
|
41
|
-
sout, sin =
|
41
|
+
sout, sin = Open.pipe
|
42
42
|
backup_stderr = STDERR.dup
|
43
43
|
old_logfile = Log.logfile
|
44
44
|
Log.logfile(backup_stderr)
|