robot-controller 0.3.0 → 0.3.2
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.
- data/README.md +2 -3
- data/VERSION +1 -1
- data/bin/controller +5 -4
- data/example/config/environments/robots_development.yml +44 -45
- data/lib/robot-controller/robots.rb +15 -43
- data/lib/robot-controller/tasks.rb +2 -0
- data/robot-controller.gemspec +1 -0
- metadata +51 -19
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -11,7 +11,6 @@ In your `Gemfile`, add:
|
|
11
11
|
|
12
12
|
In your `Rakefile`, add the following (if you don't want to include the environment unconditionally):
|
13
13
|
|
14
|
-
require 'resque/tasks'
|
15
14
|
require 'robot-controller/tasks'
|
16
15
|
|
17
16
|
Create the following configuration files based on the examples in `example/config`:
|
@@ -36,11 +35,11 @@ controller, then add:
|
|
36
35
|
Example:
|
37
36
|
% controller boot # start bluepilld and jobs
|
38
37
|
% controller status # check on status of jobs
|
39
|
-
% controller log
|
38
|
+
% controller log 1_dor_accessionWF_descriptive-metadata # view log for worker
|
40
39
|
% controller stop # stop jobs
|
41
40
|
% controller quit # stop bluepilld
|
42
41
|
|
43
42
|
Environment:
|
44
43
|
BLUEPILL_BASEDIR - where bluepill stores its state (default: run/bluepill)
|
45
44
|
BLUEPILL_LOGFILE - output log (default: log/bluepill.log)
|
46
|
-
ROBOT_ENVIRONMENT - (default: development)
|
45
|
+
ROBOT_ENVIRONMENT - (default: development)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2
|
data/bin/controller
CHANGED
@@ -12,7 +12,7 @@ Example:
|
|
12
12
|
% controller log dor_accessionWF_descriptive-metadata # view log for worker
|
13
13
|
% controller stop # stop jobs
|
14
14
|
% controller quit # stop bluepilld
|
15
|
-
|
15
|
+
|
16
16
|
Environment:
|
17
17
|
BLUEPILL_BASEDIR - where bluepill stores its state (default: run/bluepill)
|
18
18
|
BLUEPILL_LOGFILE - output log (default: log/bluepill.log)
|
@@ -38,11 +38,12 @@ if ARGV[0] == 'boot'
|
|
38
38
|
end
|
39
39
|
if File.file?(fn)
|
40
40
|
puts "Loading #{fn}"
|
41
|
-
|
42
|
-
|
41
|
+
exec "#{cmd} load #{fn}"
|
42
|
+
# NOTREACHED
|
43
43
|
end
|
44
44
|
puts "ERROR: Cannot find bluepill configuration file for #{ENV['ROBOT_ENVIRONMENT']}"
|
45
45
|
exit -1
|
46
46
|
else
|
47
|
-
|
47
|
+
exec "#{cmd} #{ARGV.join(' ')}"
|
48
|
+
# NOTREACHED
|
48
49
|
end
|
@@ -9,78 +9,77 @@
|
|
9
9
|
# where
|
10
10
|
# 1. robot is a single robot identifier (fully-qualified with
|
11
11
|
# REPO_SUITE_ROBOT, e.g., "dor_accessionWF_technical-metadata").
|
12
|
-
# 2. lane is
|
13
|
-
#
|
12
|
+
# 2. lane is
|
13
|
+
# - a single identifier ('A'), or
|
14
|
+
# - a list of identiers ('A,B,C'), or
|
15
|
+
# - an asterix (*).
|
14
16
|
# 3. instances is a single integer.
|
15
17
|
#
|
16
|
-
# Both lane and instances are optional. Lane defaults to
|
18
|
+
# Both lane and instances are optional. Lane defaults to 'default', and
|
17
19
|
# instances defaults to 1.
|
18
20
|
#
|
19
21
|
# When a robot is allocated to multiple lanes, it reads them in
|
20
|
-
# PRIORITY ORDER. That is, if a robot is listening to lanes
|
21
|
-
# it works on lane
|
22
|
-
# lane
|
22
|
+
# PRIORITY ORDER. That is, if a robot is listening to lanes A, B, and C,
|
23
|
+
# it works on lane A until empty, then lane B until empty, and then
|
24
|
+
# lane C until empty. In the meantime, if a job comes in on a 'faster'
|
23
25
|
# lane, it works on that after finishing it's current job (i.e., after
|
24
|
-
# working on a job in lane
|
25
|
-
# the robot will work on the lane
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# are dedicated lanes.
|
26
|
+
# working on a job in lane C, if a job comes in on lane A in the intermin,
|
27
|
+
# the robot will work on the lane A job next before returning to lane C).
|
28
|
+
# When using an asterix for the lane designator, the lanes are processed
|
29
|
+
# in alphabetical order.
|
29
30
|
#
|
30
31
|
# Note that the syntax is YAML, so the lists must not contain spaces or
|
31
32
|
# needs to be quoted.
|
32
33
|
#
|
33
34
|
# RIGHT
|
34
|
-
# - dor_accessionWF_technical-metadata:
|
35
|
-
# - 'dor_accessionWF_technical-metadata :
|
35
|
+
# - dor_accessionWF_technical-metadata:A:5
|
36
|
+
# - 'dor_accessionWF_technical-metadata : A : 5'
|
36
37
|
#
|
37
38
|
# WRONG
|
38
|
-
# - dor_accessionWF_technical-metadata :
|
39
|
-
# - dor_accessionWF_technical-metadata:
|
39
|
+
# - dor_accessionWF_technical-metadata : A : 5
|
40
|
+
# - dor_accessionWF_technical-metadata: A: 5
|
40
41
|
#
|
41
42
|
|
42
43
|
#
|
43
44
|
# Robot 1 (8 CPU) hosts shelving and publish only
|
44
45
|
#
|
45
46
|
sul-robots1-dev:
|
47
|
+
- dor_accessionWF_shelve:A # 1 robot for lane A
|
48
|
+
- dor_accessionWF_shelve:B:3 # 3 robots for lane B
|
49
|
+
- dor_accessionWF_shelve:C:3 # 3 robots for lane C
|
50
|
+
- dor_accessionWF_shelve:D:3 # 3 robots for lane D
|
51
|
+
- dor_accessionWF_shelve:E:3 # 3 robots for lane E
|
46
52
|
- dor_accessionWF_shelve:*:3 # 3 robots for all lanes
|
47
|
-
- dor_accessionWF_shelve
|
48
|
-
-
|
49
|
-
-
|
50
|
-
-
|
51
|
-
-
|
52
|
-
-
|
53
|
-
-
|
54
|
-
-
|
55
|
-
-
|
56
|
-
-
|
57
|
-
- dor_accessionWF_publish:10:3 # 3 robots for lane 10
|
58
|
-
- dor_accessionWF_publish:6,9 # 1 robot for lane 6 and 9
|
53
|
+
- dor_accessionWF_shelve::3 # 3 robots for default lane
|
54
|
+
- dor_accessionWF_publish:A,C:3 # 3 robots for lanes A and C
|
55
|
+
- dor_accessionWF_publish:B,D,E # 1 robot for lanes B, D and E
|
56
|
+
- dor_accessionWF_descriptive-metadata # 1 robot for all lanes
|
57
|
+
- dor_accessionWF_rights-metadata # 1 robot for all lanes
|
58
|
+
- dor_accessionWF_content-metadata # 1 robot for all lanes
|
59
|
+
- dor_accessionWF_remediate-object # 1 robot for all lanes
|
60
|
+
- dor_accessionWF_provenance-metadata # 1 robot for all lanes
|
61
|
+
- dor_accessionWF_sdr-ingest-transfer # 1 robot for all lanes
|
62
|
+
- dor_accessionWF_end-accession # 1 robot for all lanes
|
59
63
|
|
60
64
|
#
|
61
65
|
# Robot 2 (16 CPU) hosts technical metadata creation only
|
62
66
|
#
|
63
67
|
sul-robots2-dev:
|
64
|
-
- dor_accessionWF_technical-metadata:
|
65
|
-
- dor_accessionWF_technical-metadata:
|
66
|
-
- dor_accessionWF_technical-metadata:
|
67
|
-
- dor_accessionWF_technical-metadata:6:2 # 2 robots for lane 6
|
68
|
-
- dor_accessionWF_technical-metadata:7:2 # 2 robots for lane 7
|
69
|
-
- dor_accessionWF_technical-metadata:8:2 # 2 robots for lane 8
|
70
|
-
- dor_accessionWF_technical-metadata:9:2 # 2 robots for lane 9
|
71
|
-
- dor_accessionWF_technical-metadata:10:2 # 2 robots for lane 10
|
68
|
+
- dor_accessionWF_technical-metadata:A:5 # 5 robots for lane A
|
69
|
+
- dor_accessionWF_technical-metadata:B:5 # 5 robots for lane B
|
70
|
+
- dor_accessionWF_technical-metadata:C,D,E:5 # 5 robots for lanes C, D, and E
|
72
71
|
|
73
72
|
#
|
74
73
|
# Robot 3 (4 CPU) hosts helper robots for all accessioning workflows
|
75
74
|
#
|
76
75
|
sul-robots3-dev:
|
77
|
-
- dor_accessionWF_descriptive-metadata # 1 robot for
|
78
|
-
- dor_accessionWF_rights-metadata # 1 robot for
|
79
|
-
- dor_accessionWF_content-metadata # 1 robot for
|
80
|
-
- dor_accessionWF_technical-metadata # 1 robot for
|
81
|
-
- dor_accessionWF_remediate-object # 1 robot for
|
82
|
-
- dor_accessionWF_shelve
|
83
|
-
- dor_accessionWF_publish
|
84
|
-
- dor_accessionWF_provenance-metadata # 1 robot for
|
85
|
-
- dor_accessionWF_sdr-ingest-transfer # 1 robot for
|
86
|
-
- dor_accessionWF_end-accession # 1 robot for
|
76
|
+
- dor_accessionWF_descriptive-metadata # 1 robot for default lane
|
77
|
+
- dor_accessionWF_rights-metadata # 1 robot for default lane
|
78
|
+
- dor_accessionWF_content-metadata # 1 robot for default lane
|
79
|
+
- dor_accessionWF_technical-metadata # 1 robot for default lane
|
80
|
+
- dor_accessionWF_remediate-object # 1 robot for default lane
|
81
|
+
- dor_accessionWF_shelve # 1 robot for default lane
|
82
|
+
- dor_accessionWF_publish # 1 robot for default lane
|
83
|
+
- dor_accessionWF_provenance-metadata # 1 robot for default lane
|
84
|
+
- dor_accessionWF_sdr-ingest-transfer # 1 robot for default lane
|
85
|
+
- dor_accessionWF_end-accession # 1 robot for default lane
|
@@ -2,7 +2,6 @@ require 'yaml'
|
|
2
2
|
|
3
3
|
class RobotConfigParser
|
4
4
|
ROBOT_INSTANCE_MAX = 16
|
5
|
-
LANE_INSTANCE_MAX = 99 # sprintf("%02d") maximum
|
6
5
|
|
7
6
|
# parse_instances(1) == 1
|
8
7
|
# parse_instances(16) == 16
|
@@ -16,54 +15,27 @@ class RobotConfigParser
|
|
16
15
|
n
|
17
16
|
end
|
18
17
|
|
18
|
+
# parse_lanes('') == ['default']
|
19
|
+
# parse_lanes(' ') == ['default']
|
20
|
+
# parse_lanes(' , ') == ['default']
|
21
|
+
# parse_lanes(' , ,') == ['default']
|
19
22
|
# parse_lanes('*') == ['*']
|
20
|
-
# parse_lanes('
|
21
|
-
# parse_lanes('
|
22
|
-
# parse_lanes('
|
23
|
-
# parse_lanes('
|
24
|
-
# parse_lanes('
|
25
|
-
# parse_lanes('-1') == [0, 1]
|
26
|
-
# parse_lanes('100') == RuntimeException
|
23
|
+
# parse_lanes('1') == ['1']
|
24
|
+
# parse_lanes('A') == ['A']
|
25
|
+
# parse_lanes('A , B') == ['A', 'B']
|
26
|
+
# parse_lanes('A,B,C') == ['A','B','C']
|
27
|
+
# parse_lanes('A-C,E') == ['A-C', 'E']
|
27
28
|
def parse_lanes(lanes_spec)
|
28
|
-
|
29
|
-
|
30
|
-
# parse each comma-seperated specification
|
31
|
-
lanes_spec.split(/,/).each do |i|
|
32
|
-
# this is a range element
|
33
|
-
if i =~ /-/
|
34
|
-
x = i.split(/-/)
|
35
|
-
Range.new(x[0].to_i, x[1].to_i).each do |j|
|
36
|
-
lanes << j
|
37
|
-
end
|
38
|
-
# a wildcard
|
39
|
-
elsif i == '*'
|
40
|
-
lanes << '*'
|
41
|
-
# simple integer
|
42
|
-
else
|
43
|
-
lanes << i.to_i
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# verify that lanes are all within 1 .. LANE_INSTANCE_MAX
|
48
|
-
lanes.each do |j|
|
49
|
-
if j.is_a?(Integer)
|
50
|
-
if j > LANE_INSTANCE_MAX
|
51
|
-
raise RuntimeError, "SyntaxError: Lane #{j} > #{LANE_INSTANCE_MAX}"
|
52
|
-
elsif j < 0
|
53
|
-
raise RuntimeError, "SyntaxError: Lane #{j} < 0"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
lanes
|
29
|
+
return ['default'] if lanes_spec.split(/,/).collect {|l| l.strip}.join('') == ''
|
30
|
+
lanes_spec.split(/,/).collect {|l| l.strip }
|
58
31
|
end
|
59
32
|
|
60
|
-
# build_queues('
|
61
|
-
# build_queues('
|
62
|
-
# build_queues('a','1-3') => ['a_01', 'a_02', 'a_03']
|
33
|
+
# build_queues('z','A') => ['z_A']
|
34
|
+
# build_queues('z','A,C') => ['z_A', 'z_C']
|
63
35
|
def build_queues(robot, lanes)
|
64
36
|
queues = []
|
65
37
|
parse_lanes(lanes).each do |i|
|
66
|
-
queues << [robot, i
|
38
|
+
queues << [robot, i].join('_')
|
67
39
|
end
|
68
40
|
queues
|
69
41
|
end
|
@@ -92,7 +64,7 @@ class RobotConfigParser
|
|
92
64
|
# parse YAML lines for host where i is robot[:lane[:instances]]
|
93
65
|
r = []
|
94
66
|
robots[host].each do |i|
|
95
|
-
robot = i.split(/:/)
|
67
|
+
robot = i.split(/:/).collect {|j| j.strip}
|
96
68
|
robot.each do |j|
|
97
69
|
if j.strip == ''
|
98
70
|
raise RuntimeError, "SyntaxError: #{i}"
|
data/robot-controller.gemspec
CHANGED
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: robot-controller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Darren Hardy
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-
|
12
|
+
date: 2014-06-06 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bluepill
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,92 +22,121 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: 0.0.67
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: resque
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.25.2
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.25.2
|
27
46
|
- !ruby/object:Gem::Dependency
|
28
47
|
name: awesome_print
|
29
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
30
50
|
requirements:
|
31
|
-
- - '>='
|
51
|
+
- - ! '>='
|
32
52
|
- !ruby/object:Gem::Version
|
33
53
|
version: '0'
|
34
54
|
type: :development
|
35
55
|
prerelease: false
|
36
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
37
58
|
requirements:
|
38
|
-
- - '>='
|
59
|
+
- - ! '>='
|
39
60
|
- !ruby/object:Gem::Version
|
40
61
|
version: '0'
|
41
62
|
- !ruby/object:Gem::Dependency
|
42
63
|
name: pry
|
43
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
44
66
|
requirements:
|
45
|
-
- - '>='
|
67
|
+
- - ! '>='
|
46
68
|
- !ruby/object:Gem::Version
|
47
69
|
version: '0'
|
48
70
|
type: :development
|
49
71
|
prerelease: false
|
50
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
51
74
|
requirements:
|
52
|
-
- - '>='
|
75
|
+
- - ! '>='
|
53
76
|
- !ruby/object:Gem::Version
|
54
77
|
version: '0'
|
55
78
|
- !ruby/object:Gem::Dependency
|
56
79
|
name: rake
|
57
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
58
82
|
requirements:
|
59
|
-
- - '>='
|
83
|
+
- - ! '>='
|
60
84
|
- !ruby/object:Gem::Version
|
61
85
|
version: '0'
|
62
86
|
type: :development
|
63
87
|
prerelease: false
|
64
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
65
90
|
requirements:
|
66
|
-
- - '>='
|
91
|
+
- - ! '>='
|
67
92
|
- !ruby/object:Gem::Version
|
68
93
|
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: redcarpet
|
71
96
|
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
72
98
|
requirements:
|
73
|
-
- - '>='
|
99
|
+
- - ! '>='
|
74
100
|
- !ruby/object:Gem::Version
|
75
101
|
version: '0'
|
76
102
|
type: :development
|
77
103
|
prerelease: false
|
78
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
79
106
|
requirements:
|
80
|
-
- - '>='
|
107
|
+
- - ! '>='
|
81
108
|
- !ruby/object:Gem::Version
|
82
109
|
version: '0'
|
83
110
|
- !ruby/object:Gem::Dependency
|
84
111
|
name: version_bumper
|
85
112
|
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
86
114
|
requirements:
|
87
|
-
- - '>='
|
115
|
+
- - ! '>='
|
88
116
|
- !ruby/object:Gem::Version
|
89
117
|
version: '0'
|
90
118
|
type: :development
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
93
122
|
requirements:
|
94
|
-
- - '>='
|
123
|
+
- - ! '>='
|
95
124
|
- !ruby/object:Gem::Version
|
96
125
|
version: '0'
|
97
126
|
- !ruby/object:Gem::Dependency
|
98
127
|
name: yard
|
99
128
|
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
100
130
|
requirements:
|
101
|
-
- - '>='
|
131
|
+
- - ! '>='
|
102
132
|
- !ruby/object:Gem::Version
|
103
133
|
version: '0'
|
104
134
|
type: :development
|
105
135
|
prerelease: false
|
106
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
107
138
|
requirements:
|
108
|
-
- - '>='
|
139
|
+
- - ! '>='
|
109
140
|
- !ruby/object:Gem::Version
|
110
141
|
version: '0'
|
111
142
|
description:
|
@@ -136,26 +167,27 @@ homepage: http://github.com/sul-dlss/robot-controller
|
|
136
167
|
licenses:
|
137
168
|
- ALv2
|
138
169
|
- Stanford University
|
139
|
-
metadata: {}
|
140
170
|
post_install_message:
|
141
171
|
rdoc_options: []
|
142
172
|
require_paths:
|
143
173
|
- lib
|
144
174
|
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
+
none: false
|
145
176
|
requirements:
|
146
|
-
- - '>='
|
177
|
+
- - ! '>='
|
147
178
|
- !ruby/object:Gem::Version
|
148
179
|
version: '0'
|
149
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
150
182
|
requirements:
|
151
|
-
- - '>='
|
183
|
+
- - ! '>='
|
152
184
|
- !ruby/object:Gem::Version
|
153
185
|
version: 1.3.6
|
154
186
|
requirements: []
|
155
187
|
rubyforge_project:
|
156
|
-
rubygems_version:
|
188
|
+
rubygems_version: 1.8.25
|
157
189
|
signing_key:
|
158
|
-
specification_version:
|
190
|
+
specification_version: 3
|
159
191
|
summary: Monitors and controls running workflow robots off of priority queues and
|
160
192
|
within a cluster
|
161
193
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: c01c2e8362bea0af35c415127c35e2b6fd5a643d
|
4
|
-
data.tar.gz: 3bea75dfaa22001504e2a7db019ae406e4b81c00
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: e4c6de1781095edee97a52db140f4e6b9e7ca538ccaf66982ef0ce7f50467e2a998ac8c37334bc89fabd58dfe0420a7eb66604b51e593effd6a6870655f6bcf4
|
7
|
-
data.tar.gz: cc1b11f2655f960195a56ce760d19ebc39babd02e797002b19dce8ad3c4336213f2bb7a8ce7ad8b736ece255a259b2cf47db832fd1fcc2ffe4b8751dcc12160e
|