ripe 0.0.2 → 0.0.3
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/Guardfile +5 -0
- data/bin/ripe +1 -1
- data/lib/ripe/controller.rb +2 -1
- data/lib/ripe/version.rb +1 -1
- data/lib/ripe/worker.rb +1 -119
- data/lib/ripe/worker_controller.rb +130 -0
- data/lib/ripe.rb +2 -2
- data/ripe.gemspec +2 -1
- data/spec/block_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -3
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8c9495954bce6425a4043a52c79d40e8ea3945f
|
4
|
+
data.tar.gz: e8e3ab0a02addf1ac505aa8193e238d4eefd3020
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c494c400af63cf21c2c55a8d87cb6688e9175a0b029a7c6c91a8f4cb6cecc906a1c72509268b97c30f9d291036a24ef558565387ff688419f5203b6b8022ce67
|
7
|
+
data.tar.gz: 2e2ae3f075bd43b9a9e575a509c1276a549c0283d7453575aaf99ea2365ddb25411ebb8cbf0a8affdb365a55e9f10913b6c36ea315b1e67c5bfa98a9cb4d18fb
|
data/Guardfile
ADDED
data/bin/ripe
CHANGED
data/lib/ripe/controller.rb
CHANGED
@@ -2,6 +2,7 @@ require 'active_record'
|
|
2
2
|
require 'fileutils'
|
3
3
|
require_relative 'block'
|
4
4
|
require_relative 'worker'
|
5
|
+
require_relative 'worker_controller'
|
5
6
|
require_relative 'worker_migration'
|
6
7
|
require_relative 'working_block'
|
7
8
|
require_relative 'liquid_block'
|
@@ -45,7 +46,7 @@ module Ripe
|
|
45
46
|
end
|
46
47
|
|
47
48
|
def prepare(samples, callback, vars = {})
|
48
|
-
|
49
|
+
WorkerController.instance.prepare(samples, callback, vars)
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
data/lib/ripe/version.rb
CHANGED
data/lib/ripe/worker.rb
CHANGED
@@ -30,126 +30,8 @@ module Ripe
|
|
30
30
|
FileUtils.rm_r dir if Dir.exists? dir
|
31
31
|
end
|
32
32
|
|
33
|
-
def self.prepare(samples, callback, vars = {})
|
34
|
-
vars = {
|
35
|
-
wd: Dir.pwd,
|
36
|
-
mode: :patch,
|
37
|
-
group_num: 1,
|
38
|
-
}.merge(vars)
|
39
|
-
|
40
|
-
return if ![:patch, :force, :depend].include? vars[:mode].to_sym
|
41
|
-
|
42
|
-
samples = samples.map do |sample|
|
43
|
-
block = callback.call(sample, vars).prune(vars[:mode].to_sym == :force,
|
44
|
-
vars[:mode].to_sym == :depend)
|
45
|
-
if block != nil
|
46
|
-
puts "Preparing sample #{sample}"
|
47
|
-
[sample, block]
|
48
|
-
else
|
49
|
-
puts "Nothing to do for sample #{sample}"
|
50
|
-
nil
|
51
|
-
end
|
52
|
-
end
|
53
|
-
samples = samples.compact
|
54
|
-
|
55
|
-
samples.each_slice(vars[:group_num].to_i).map do |worker_samples|
|
56
|
-
worker = Worker.create(handle: vars[:handle])
|
57
|
-
|
58
|
-
blocks = worker_samples.map do |sample, block|
|
59
|
-
# Preorder traversal of blocks -- assign incremental numbers starting from
|
60
|
-
# 1 to each node as it is being traversed.
|
61
|
-
post_var_assign = lambda do |subblock|
|
62
|
-
if subblock.blocks.length == 0
|
63
|
-
task = worker.tasks.create({
|
64
|
-
sample: sample,
|
65
|
-
block: subblock.id,
|
66
|
-
})
|
67
|
-
subblock.vars.merge!(log: task.log)
|
68
|
-
else
|
69
|
-
subblock.blocks.each(&post_var_assign)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
post_var_assign.call(block)
|
74
|
-
block
|
75
|
-
end
|
76
|
-
|
77
|
-
vars = vars.merge({
|
78
|
-
name: worker.id,
|
79
|
-
stdout: worker.stdout,
|
80
|
-
stderr: worker.stderr,
|
81
|
-
command: SerialBlock.new(*blocks).command,
|
82
|
-
})
|
83
|
-
|
84
|
-
file = File.new(worker.sh, 'w')
|
85
|
-
file.puts LiquidBlock.new("#{PATH}/share/moab.sh", vars).command
|
86
|
-
file.close
|
87
|
-
|
88
|
-
worker.update({
|
89
|
-
status: :prepared,
|
90
|
-
ppn: vars[:ppn],
|
91
|
-
queue: vars[:queue],
|
92
|
-
walltime: vars[:walltime],
|
93
|
-
})
|
94
|
-
worker
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
33
|
def self.sync
|
99
|
-
|
100
|
-
lists = lists.map do |status, op|
|
101
|
-
showq = `showq -u $(whoami) #{op} | grep $(whoami)`.split("\n")
|
102
|
-
showq.map do |job|
|
103
|
-
{
|
104
|
-
moab_id: job[/^([0-9]+) /, 1],
|
105
|
-
time: job[/ ([0-9]{1,2}(\:[0-9]{2})+) /, 1],
|
106
|
-
status: status,
|
107
|
-
}
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# Update status
|
112
|
-
lists = lists.inject(&:+).each do |job|
|
113
|
-
moab_id = job[:moab_id]
|
114
|
-
time = job[:time]
|
115
|
-
status = job[:status]
|
116
|
-
worker = Worker.find_by(moab_id: moab_id)
|
117
|
-
|
118
|
-
if worker
|
119
|
-
worker.update(time: time)
|
120
|
-
unless ['cancelled', status].include? worker.status
|
121
|
-
checkjob = `checkjob #{moab_id}`
|
122
|
-
worker.update({
|
123
|
-
host: checkjob[/Allocated Nodes:\n\[(.*):[0-9]+\]\n/, 1],
|
124
|
-
status: status, # Queued jobs that appear become either idle, blocked or active
|
125
|
-
})
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# Mark workers that were previously in active, blocked or idle as completed
|
131
|
-
# if they cannot be found anymore.
|
132
|
-
jobs = lists.map { |job| job[:moab_id] }
|
133
|
-
Worker.where('status in (:statuses)',
|
134
|
-
:statuses => ['active', 'idle', 'blocked']).each do |worker|
|
135
|
-
if jobs.include? worker.moab_id
|
136
|
-
jobs.delete(worker.moab_id) # Remove from list
|
137
|
-
elsif (worker.status != 'cancelled')
|
138
|
-
if File.exists? worker.stdout
|
139
|
-
stdout = File.new(worker.stdout).readlines.join
|
140
|
-
else
|
141
|
-
stdout = ""
|
142
|
-
end
|
143
|
-
worker.update({
|
144
|
-
cpu_used: stdout[/Resources:[ \t]*cput=([0-9]{1,2}(\:[0-9]{2})+),/, 1],
|
145
|
-
exit_code: stdout[/Exit code:[ \t]*(.*)$/, 1],
|
146
|
-
host: stdout[/Nodes:[ \t]*(.*)$/, 1],
|
147
|
-
memory_used: stdout[/Resources:.*,mem=([0-9]*[a-zA-Z]*),/, 1],
|
148
|
-
time: stdout[/Resources:.*,walltime=([0-9]{1,2}(\:[0-9]{2})+)$/, 1],
|
149
|
-
status: :completed,
|
150
|
-
})
|
151
|
-
end
|
152
|
-
end
|
34
|
+
WorkerController.instance.sync
|
153
35
|
end
|
154
36
|
|
155
37
|
def start!
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require_relative 'worker'
|
3
|
+
|
4
|
+
module Ripe
|
5
|
+
class WorkerController
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def prepare(samples, callback, vars = {})
|
9
|
+
vars = {
|
10
|
+
wd: Dir.pwd,
|
11
|
+
mode: :patch,
|
12
|
+
group_num: 1,
|
13
|
+
}.merge(vars)
|
14
|
+
|
15
|
+
return if ![:patch, :force, :depend].include? vars[:mode].to_sym
|
16
|
+
|
17
|
+
samples = samples.map do |sample|
|
18
|
+
block = callback.call(sample, vars).prune(vars[:mode].to_sym == :force,
|
19
|
+
vars[:mode].to_sym == :depend)
|
20
|
+
if block != nil
|
21
|
+
puts "Preparing sample #{sample}"
|
22
|
+
[sample, block]
|
23
|
+
else
|
24
|
+
puts "Nothing to do for sample #{sample}"
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
samples = samples.compact
|
29
|
+
|
30
|
+
samples.each_slice(vars[:group_num].to_i).map do |worker_samples|
|
31
|
+
worker = Worker.create(handle: vars[:handle])
|
32
|
+
|
33
|
+
blocks = worker_samples.map do |sample, block|
|
34
|
+
# Preorder traversal of blocks -- assign incremental numbers starting from
|
35
|
+
# 1 to each node as it is being traversed.
|
36
|
+
post_var_assign = lambda do |subblock|
|
37
|
+
if subblock.blocks.length == 0
|
38
|
+
task = worker.tasks.create({
|
39
|
+
sample: sample,
|
40
|
+
block: subblock.id,
|
41
|
+
})
|
42
|
+
subblock.vars.merge!(log: task.log)
|
43
|
+
else
|
44
|
+
subblock.blocks.each(&post_var_assign)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
post_var_assign.call(block)
|
49
|
+
block
|
50
|
+
end
|
51
|
+
|
52
|
+
vars = vars.merge({
|
53
|
+
name: worker.id,
|
54
|
+
stdout: worker.stdout,
|
55
|
+
stderr: worker.stderr,
|
56
|
+
command: SerialBlock.new(*blocks).command,
|
57
|
+
})
|
58
|
+
|
59
|
+
file = File.new(worker.sh, 'w')
|
60
|
+
file.puts LiquidBlock.new("#{PATH}/share/moab.sh", vars).command
|
61
|
+
file.close
|
62
|
+
|
63
|
+
worker.update({
|
64
|
+
status: :prepared,
|
65
|
+
ppn: vars[:ppn],
|
66
|
+
queue: vars[:queue],
|
67
|
+
walltime: vars[:walltime],
|
68
|
+
})
|
69
|
+
worker
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def sync
|
74
|
+
lists = {idle: '-i', blocked: '-b', active: '-r'}
|
75
|
+
lists = lists.map do |status, op|
|
76
|
+
showq = `showq -u $(whoami) #{op} | grep $(whoami)`.split("\n")
|
77
|
+
showq.map do |job|
|
78
|
+
{
|
79
|
+
moab_id: job[/^([0-9]+) /, 1],
|
80
|
+
time: job[/ ([0-9]{1,2}(\:[0-9]{2})+) /, 1],
|
81
|
+
status: status,
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Update status
|
87
|
+
lists = lists.inject(&:+).each do |job|
|
88
|
+
moab_id = job[:moab_id]
|
89
|
+
time = job[:time]
|
90
|
+
status = job[:status]
|
91
|
+
worker = Worker.find_by(moab_id: moab_id)
|
92
|
+
|
93
|
+
if worker
|
94
|
+
worker.update(time: time)
|
95
|
+
unless ['cancelled', status].include? worker.status
|
96
|
+
checkjob = `checkjob #{moab_id}`
|
97
|
+
worker.update({
|
98
|
+
host: checkjob[/Allocated Nodes:\n\[(.*):[0-9]+\]\n/, 1],
|
99
|
+
status: status, # Queued jobs that appear become either idle, blocked or active
|
100
|
+
})
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Mark workers that were previously in active, blocked or idle as completed
|
106
|
+
# if they cannot be found anymore.
|
107
|
+
jobs = lists.map { |job| job[:moab_id] }
|
108
|
+
Worker.where('status in (:statuses)',
|
109
|
+
:statuses => ['active', 'idle', 'blocked']).each do |worker|
|
110
|
+
if jobs.include? worker.moab_id
|
111
|
+
jobs.delete(worker.moab_id) # Remove from list
|
112
|
+
elsif (worker.status != 'cancelled')
|
113
|
+
if File.exists? worker.stdout
|
114
|
+
stdout = File.new(worker.stdout).readlines.join
|
115
|
+
else
|
116
|
+
stdout = ""
|
117
|
+
end
|
118
|
+
worker.update({
|
119
|
+
cpu_used: stdout[/Resources:[ \t]*cput=([0-9]{1,2}(\:[0-9]{2})+),/, 1],
|
120
|
+
exit_code: stdout[/Exit code:[ \t]*(.*)$/, 1],
|
121
|
+
host: stdout[/Nodes:[ \t]*(.*)$/, 1],
|
122
|
+
memory_used: stdout[/Resources:.*,mem=([0-9]*[a-zA-Z]*),/, 1],
|
123
|
+
time: stdout[/Resources:.*,walltime=([0-9]{1,2}(\:[0-9]{2})+)$/, 1],
|
124
|
+
status: :completed,
|
125
|
+
})
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
data/lib/ripe.rb
CHANGED
data/ripe.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
|
4
|
+
require_relative 'lib/ripe/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "ripe"
|
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.2"
|
24
24
|
spec.add_development_dependency "rspec-nc", "~> 0.2"
|
25
|
+
spec.add_development_dependency "guard-rspec", "~> 4.5"
|
25
26
|
|
26
27
|
spec.add_runtime_dependency "activerecord", "~> 4.2"
|
27
28
|
spec.add_runtime_dependency "fileutils", "~> 0.7"
|
data/spec/block_spec.rb
ADDED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ripe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas De Jay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.5'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.5'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: activerecord
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +204,7 @@ files:
|
|
190
204
|
- ".ruby-version"
|
191
205
|
- ".travis.yml"
|
192
206
|
- Gemfile
|
207
|
+
- Guardfile
|
193
208
|
- LICENSE.txt
|
194
209
|
- README.md
|
195
210
|
- Rakefile
|
@@ -205,10 +220,12 @@ files:
|
|
205
220
|
- lib/ripe/task_migration.rb
|
206
221
|
- lib/ripe/version.rb
|
207
222
|
- lib/ripe/worker.rb
|
223
|
+
- lib/ripe/worker_controller.rb
|
208
224
|
- lib/ripe/worker_migration.rb
|
209
225
|
- lib/ripe/working_block.rb
|
210
226
|
- ripe.gemspec
|
211
227
|
- share/moab.sh
|
228
|
+
- spec/block_spec.rb
|
212
229
|
- spec/ripe_spec.rb
|
213
230
|
- spec/spec_helper.rb
|
214
231
|
homepage: https://github.com/ndejay/ripe
|
@@ -236,5 +253,6 @@ signing_key:
|
|
236
253
|
specification_version: 4
|
237
254
|
summary: Abstraction layer between the MOAB/Torque stack and your pipeline.
|
238
255
|
test_files:
|
256
|
+
- spec/block_spec.rb
|
239
257
|
- spec/ripe_spec.rb
|
240
258
|
- spec/spec_helper.rb
|