robot_sweatshop 0.4.6 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +3 -3
- data/bin/sweatshop +6 -6
- data/bin/sweatshop-assembler +12 -11
- data/bin/sweatshop-conveyor +2 -3
- data/bin/sweatshop-job-dictionary +4 -4
- data/bin/sweatshop-payload-parser +9 -13
- data/bin/sweatshop-worker +3 -5
- data/docs/README.md +71 -0
- data/docs/architecture.dot +22 -0
- data/docs/architecture.gif +0 -0
- data/lib/robot_sweatshop/cli/common.rb +4 -3
- data/lib/robot_sweatshop/cli/config.rb +23 -3
- data/lib/robot_sweatshop/cli/job.rb +11 -1
- data/lib/robot_sweatshop/cli/start.rb +3 -11
- data/lib/robot_sweatshop/config.rb +3 -3
- data/lib/robot_sweatshop/connections.rb +3 -2
- data/lib/robot_sweatshop/create-config-directories.rb +4 -11
- data/robot_sweatshop.eye +2 -1
- data/robot_sweatshop.gemspec +1 -1
- data/test/shared/helpers.rb +1 -1
- metadata +5 -3
- data/lib/README.md +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f1852d96c663c8d61e07123a2bf84162ba15698
|
4
|
+
data.tar.gz: 5b592ff4da66bb363625e9beeeb3dd0c64c8e85c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecdb8c16cbee4b20c667745c251953edc3850b59110ed850413a62c9454102c7455021c599af4b3b780f5acf3488d93b3d88c04d48877be6cd57b5c4a488aca8
|
7
|
+
data.tar.gz: ee78994a812f67a8623051e77f4252ea3c8b8f9746230861494e74f18bdb9a2718ab76dc4552b5eb296244993879b70b61980b74cba1e147310e683f651e459e
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -40,13 +40,13 @@ You probably don't want to run Robot Sweatshop as a sudo user. Create a testing
|
|
40
40
|
|
41
41
|
1.0
|
42
42
|
|
43
|
-
- Docs on architecture
|
44
|
-
- Easier way to run multiple workers
|
45
43
|
- Mascot
|
46
44
|
|
47
45
|
1.1
|
48
46
|
|
49
|
-
-
|
47
|
+
- Easier way to run multiple workers
|
48
|
+
- Push/pull out node that worker streams output to
|
49
|
+
- Add worker tags to output so it can all go to one file
|
50
50
|
|
51
51
|
Beyond
|
52
52
|
|
data/bin/sweatshop
CHANGED
@@ -7,7 +7,7 @@ require 'robot_sweatshop/config'
|
|
7
7
|
require 'robot_sweatshop/create-config-directories'
|
8
8
|
|
9
9
|
program :name, 'Robot Sweatshop'
|
10
|
-
program :version, '0.4.
|
10
|
+
program :version, '0.4.7'
|
11
11
|
program :description, 'A lightweight, nonopinionated CI server'
|
12
12
|
program :help, 'Author', 'Justin Scott <jvscott@gmail.com>'
|
13
13
|
|
@@ -16,8 +16,8 @@ command :job do |c|
|
|
16
16
|
c.description = 'Creates and edits jobs.'
|
17
17
|
c.option '--auto', 'Create the file without opening the editor.'
|
18
18
|
c.action do |args, options|
|
19
|
-
options.default :
|
20
|
-
|
19
|
+
options.default auto: false
|
20
|
+
fail 'Specify a job name as the command argument.' if args.count < 1
|
21
21
|
job_file = CLI::Job.path_for args.first
|
22
22
|
CLI.create job_file, with_contents: CLI::Job.default
|
23
23
|
CLI.edit job_file unless options.auto
|
@@ -27,7 +27,7 @@ end
|
|
27
27
|
command :'job-list' do |c|
|
28
28
|
c.syntax = 'sweatshop job-list'
|
29
29
|
c.description = 'Lists available job configurations.'
|
30
|
-
c.action do
|
30
|
+
c.action do
|
31
31
|
CLI::Job.list
|
32
32
|
end
|
33
33
|
end
|
@@ -37,7 +37,7 @@ command :config do |c|
|
|
37
37
|
c.description = 'Creates and edits the user configuration file.'
|
38
38
|
c.option '--auto', 'Create the file without opening the editor.'
|
39
39
|
c.action do |args, options|
|
40
|
-
options.default :
|
40
|
+
options.default auto: false
|
41
41
|
for_scope = args.first || 'local'
|
42
42
|
config_file = CLI::Config.path for_scope
|
43
43
|
CLI.create config_file, with_contents: CLI::Config.default
|
@@ -50,7 +50,7 @@ command :start do |c|
|
|
50
50
|
c.description = 'Start the Sweatshop.'
|
51
51
|
c.option '--testing', 'Load the testing Eye configuration.'
|
52
52
|
c.action do |_args, options|
|
53
|
-
options.default :
|
53
|
+
options.default testing: false
|
54
54
|
environment = options.testing ? 'testing' : 'production'
|
55
55
|
CLI::Start.sweatshop for_environment: environment
|
56
56
|
end
|
data/bin/sweatshop-assembler
CHANGED
@@ -12,8 +12,8 @@ using ExtendedEZMQ
|
|
12
12
|
Contract Hash => Hash
|
13
13
|
def sanitize(data)
|
14
14
|
return {} if data.empty?
|
15
|
-
data = data.map { |key, value| {key => value.to_s} }
|
16
|
-
data.reduce
|
15
|
+
data = data.map { |key, value| { key => value.to_s } }
|
16
|
+
data.reduce :merge
|
17
17
|
end
|
18
18
|
|
19
19
|
Contract Hash => String
|
@@ -40,11 +40,11 @@ def assemble(job, payload, definition)
|
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
|
-
Contract None =>
|
43
|
+
Contract None => Maybe[Hash]
|
44
44
|
def request_job
|
45
|
-
job_id = @sockets[:conveyor].request
|
45
|
+
job_id = @sockets[:conveyor].request method: 'dequeue'
|
46
46
|
return nil if job_id.nil?
|
47
|
-
raw_job = @sockets[:conveyor].request
|
47
|
+
raw_job = @sockets[:conveyor].request method: 'lookup', data: job_id
|
48
48
|
puts "Assembling: '#{raw_job}'"
|
49
49
|
raw_job.merge job_id: job_id
|
50
50
|
end
|
@@ -52,7 +52,7 @@ end
|
|
52
52
|
Contract EZMQ::Socket, Any => Hash
|
53
53
|
def request(socket, data)
|
54
54
|
response = socket.request data, {}
|
55
|
-
|
55
|
+
fail response[:error] unless response[:error].empty?
|
56
56
|
response[:data]
|
57
57
|
end
|
58
58
|
|
@@ -63,19 +63,20 @@ def request_data_for(job)
|
|
63
63
|
[payload, definition]
|
64
64
|
end
|
65
65
|
|
66
|
-
Contract
|
66
|
+
Contract Maybe[Array], Maybe[String] => nil
|
67
67
|
def check_whitelist(whitelist, branch)
|
68
68
|
return if whitelist.nil?
|
69
|
-
|
69
|
+
fail 'Branch not whitelisted' unless whitelist.include? branch
|
70
70
|
end
|
71
71
|
|
72
72
|
Contract Fixnum => Bool
|
73
73
|
def finish(job_id)
|
74
|
-
@sockets[:conveyor].request
|
74
|
+
@sockets[:conveyor].request method: 'finish', data: job_id
|
75
75
|
end
|
76
76
|
|
77
77
|
job_search = Fiber.new do
|
78
|
-
# TODO: profiler to get a better idea of how long we should
|
78
|
+
# TODO: profiler to get a better idea of how long we should
|
79
|
+
# wait based on historical information
|
79
80
|
timer = ExponentialBackoff.new 0.1, 3
|
80
81
|
loop do
|
81
82
|
sleep timer.next_interval
|
@@ -101,7 +102,7 @@ loop do
|
|
101
102
|
payload, definition = request_data_for job
|
102
103
|
check_whitelist definition['branch_whitelist'], payload['branch']
|
103
104
|
assembled_job = assemble job, payload, definition
|
104
|
-
@sockets[:worker].send
|
105
|
+
@sockets[:worker].send assembled_job
|
105
106
|
rescue RuntimeError => error
|
106
107
|
puts error.message
|
107
108
|
finish job[:job_id]
|
data/bin/sweatshop-conveyor
CHANGED
@@ -21,9 +21,9 @@ def enqueue(item)
|
|
21
21
|
@items.enqueue item
|
22
22
|
end
|
23
23
|
|
24
|
-
Contract None =>
|
24
|
+
Contract None => Maybe[Fixnum]
|
25
25
|
def dequeue
|
26
|
-
puts
|
26
|
+
puts 'dequeue'
|
27
27
|
@items.dequeue
|
28
28
|
end
|
29
29
|
|
@@ -46,7 +46,6 @@ end
|
|
46
46
|
|
47
47
|
Contract Hash => Any
|
48
48
|
def complete(request)
|
49
|
-
arguments = []
|
50
49
|
return send(request[:method], request[:data]) if request[:data]
|
51
50
|
send(request[:method])
|
52
51
|
end
|
@@ -16,12 +16,12 @@ end
|
|
16
16
|
Contract String => Or[Hash, nil]
|
17
17
|
def load_if_exists(config_path)
|
18
18
|
puts "Reading job configuration from #{config_path}"
|
19
|
-
YAML.load_file config_path if File.
|
19
|
+
YAML.load_file config_path if File.exist? config_path
|
20
20
|
end
|
21
21
|
|
22
22
|
Contract None => Hash
|
23
23
|
def empty_config
|
24
|
-
puts
|
24
|
+
puts 'Job configuration not found or empty'
|
25
25
|
{}
|
26
26
|
end
|
27
27
|
|
@@ -31,8 +31,8 @@ def load_config_for(job_name)
|
|
31
31
|
end
|
32
32
|
|
33
33
|
Contract Hash, Hash => Hash
|
34
|
-
def formatted(payload={}, error:'')
|
35
|
-
{data: payload, error: error}
|
34
|
+
def formatted(payload = {}, error: '')
|
35
|
+
{ data: payload, error: error }
|
36
36
|
end
|
37
37
|
|
38
38
|
Contract String => Hash
|
@@ -11,12 +11,10 @@ using ExtendedEZMQ
|
|
11
11
|
|
12
12
|
Contract String => Bool
|
13
13
|
def json?(string)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
false
|
19
|
-
end
|
14
|
+
Oj.load string
|
15
|
+
true
|
16
|
+
rescue Oj::ParseError
|
17
|
+
false
|
20
18
|
end
|
21
19
|
|
22
20
|
Contract String => Bool
|
@@ -40,16 +38,14 @@ end
|
|
40
38
|
|
41
39
|
Contract String, String => Or[Hash, nil]
|
42
40
|
def payload_hash_from(payload, format)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
nil
|
47
|
-
end
|
41
|
+
Object.const_get("#{format}Payload").new(payload).to_hash
|
42
|
+
rescue NameError
|
43
|
+
nil
|
48
44
|
end
|
49
45
|
|
50
46
|
Contract Hash, Hash => Hash
|
51
|
-
def formatted(payload={}, error:'')
|
52
|
-
{data: payload, error: error}
|
47
|
+
def formatted(payload = {}, error:'')
|
48
|
+
{ data: payload, error: error }
|
53
49
|
end
|
54
50
|
|
55
51
|
Contract String, String => Hash
|
data/bin/sweatshop-worker
CHANGED
@@ -30,10 +30,8 @@ end
|
|
30
30
|
Contract Hash, String => Maybe[IO]
|
31
31
|
def stream_command(context, command)
|
32
32
|
command = ensure_shell_for command
|
33
|
-
IO.popen(context, command) do |
|
34
|
-
|
35
|
-
puts line
|
36
|
-
end
|
33
|
+
IO.popen(context, command) do |stream|
|
34
|
+
puts stream.gets until stream.eof? # TODO: stdout not being tested properly
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
@@ -50,7 +48,7 @@ end
|
|
50
48
|
|
51
49
|
Contract Fixnum => nil
|
52
50
|
def finish(id)
|
53
|
-
@sockets[:conveyor].request({method: 'finish', data: id}, {})
|
51
|
+
@sockets[:conveyor].request({ method: 'finish', data: id }, {})
|
54
52
|
puts "Job finished.\n\n"
|
55
53
|
end
|
56
54
|
|
data/docs/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Process Architecture
|
2
|
+
|
3
|
+
![Robot Sweatshop Processes](architecture.gif)
|
4
|
+
|
5
|
+
# Message Data Schema
|
6
|
+
|
7
|
+
## input
|
8
|
+
|
9
|
+
```
|
10
|
+
PUSH {
|
11
|
+
payload Hash
|
12
|
+
user_agent String
|
13
|
+
job_name String
|
14
|
+
}
|
15
|
+
```
|
16
|
+
|
17
|
+
## conveyor
|
18
|
+
|
19
|
+
```
|
20
|
+
REQ {
|
21
|
+
method String
|
22
|
+
data String
|
23
|
+
}
|
24
|
+
```
|
25
|
+
|
26
|
+
method | parameters | reply
|
27
|
+
-------|------------|-------
|
28
|
+
enqueue|item |id Fixnum
|
29
|
+
dequeue|- |id Fixnum
|
30
|
+
lookup |id |item Hash
|
31
|
+
finish |id |true Bool
|
32
|
+
|
33
|
+
## payload-parser
|
34
|
+
|
35
|
+
```
|
36
|
+
REQ {
|
37
|
+
payload String
|
38
|
+
user_agent String
|
39
|
+
}
|
40
|
+
|
41
|
+
REP {
|
42
|
+
payload Hash
|
43
|
+
}
|
44
|
+
```
|
45
|
+
|
46
|
+
## job-dictionary
|
47
|
+
|
48
|
+
```
|
49
|
+
REQ {
|
50
|
+
job_name String
|
51
|
+
}
|
52
|
+
|
53
|
+
REP {
|
54
|
+
definition Hash
|
55
|
+
}
|
56
|
+
```
|
57
|
+
|
58
|
+
## assembler
|
59
|
+
|
60
|
+
```
|
61
|
+
PUSH {
|
62
|
+
context Hash
|
63
|
+
commands Array
|
64
|
+
job_name String
|
65
|
+
job_id Fixnum
|
66
|
+
}
|
67
|
+
```
|
68
|
+
|
69
|
+
# Notes
|
70
|
+
|
71
|
+
Context is passed around with string keys because it's user provided. Everything else is passed with symbol keys
|
@@ -0,0 +1,22 @@
|
|
1
|
+
digraph architecture {
|
2
|
+
label="Robot Sweatshop Processes"
|
3
|
+
labelloc="top"
|
4
|
+
|
5
|
+
I [label="Input"]
|
6
|
+
A [label="Assembler"]
|
7
|
+
W [label="Worker"]
|
8
|
+
subgraph cluster_0 {
|
9
|
+
label="Req/Rep Services"
|
10
|
+
labelloc="bottom"
|
11
|
+
style="dashed"
|
12
|
+
C [label="Conveyor"]
|
13
|
+
P [label="Payload Parser"]
|
14
|
+
D [label="Job Dictionary"]
|
15
|
+
}
|
16
|
+
|
17
|
+
I->C [taillabel="1..*"]
|
18
|
+
A->C [dir="both"]
|
19
|
+
A->P [dir="both"]
|
20
|
+
A->D [dir="both"]
|
21
|
+
A->W [headlabel="1..*",labeldistance=2]
|
22
|
+
}
|
Binary file
|
@@ -2,6 +2,7 @@ require 'fileutils'
|
|
2
2
|
require 'robot_sweatshop/config'
|
3
3
|
require 'terminal-announce'
|
4
4
|
|
5
|
+
# Methods common to every CLI command
|
5
6
|
module CLI
|
6
7
|
def self.edit(file)
|
7
8
|
editor = ENV['EDITOR']
|
@@ -9,8 +10,8 @@ module CLI
|
|
9
10
|
Announce.info "Manually editing file '#{file}'"
|
10
11
|
system editor, file
|
11
12
|
else
|
12
|
-
Announce.warning
|
13
|
-
Announce.info
|
13
|
+
Announce.warning 'No editor specified in $EDITOR environment variable'
|
14
|
+
Announce.info 'Displaying file contents instead'
|
14
15
|
system 'cat', file
|
15
16
|
end
|
16
17
|
end
|
@@ -18,7 +19,7 @@ module CLI
|
|
18
19
|
def self.create(file, with_contents: '')
|
19
20
|
file = File.expand_path file
|
20
21
|
if File.file?(file)
|
21
|
-
|
22
|
+
Announce.info "'#{file}' already exists"
|
22
23
|
else
|
23
24
|
FileUtils.mkdir_p File.dirname(file)
|
24
25
|
File.write file, with_contents
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
require 'robot_sweatshop/config'
|
2
3
|
|
3
4
|
module CLI
|
5
|
+
# Methods for configuring Robot Sweatshop
|
4
6
|
module Config
|
5
7
|
def self.default
|
6
8
|
File.read "#{__dir__}/../../../config.defaults.yaml"
|
@@ -9,12 +11,30 @@ module CLI
|
|
9
11
|
def self.path(scope)
|
10
12
|
case scope
|
11
13
|
when 'system'
|
12
|
-
|
14
|
+
'/etc/robot_sweatshop/config.yaml'
|
13
15
|
when 'user'
|
14
|
-
|
16
|
+
'~/.robot_sweatshop/config.yaml'
|
15
17
|
else
|
16
|
-
|
18
|
+
'.robot_sweatshop/config.yaml'
|
17
19
|
end
|
18
20
|
end
|
21
|
+
|
22
|
+
def self.expand_paths_in(config_hash)
|
23
|
+
config_hash.each do |key, value|
|
24
|
+
config_hash[key] = File.expand_path value if key.to_s.match(/_path/)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.write(config_hash)
|
29
|
+
config_home = File.expand_path('~/.robot_sweatshop')
|
30
|
+
FileUtils.mkpath config_home
|
31
|
+
File.write "#{config_home}/compiled_config.yaml", config_hash.to_yaml
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.compile_to_file
|
35
|
+
config = expand_paths_in configatron.to_h
|
36
|
+
config[:working_path] = Dir.pwd
|
37
|
+
write config
|
38
|
+
end
|
19
39
|
end
|
20
40
|
end
|
@@ -1,9 +1,19 @@
|
|
1
1
|
require 'robot_sweatshop/config'
|
2
2
|
|
3
3
|
module CLI
|
4
|
+
# Methods for creating and editing jobs
|
4
5
|
module Job
|
5
6
|
def self.default
|
6
|
-
"
|
7
|
+
"---
|
8
|
+
# branch_whitelist:
|
9
|
+
# - master
|
10
|
+
|
11
|
+
commands:
|
12
|
+
- echo \"Hello $WORLD!\"
|
13
|
+
|
14
|
+
environment:
|
15
|
+
WORLD: Earth
|
16
|
+
"
|
7
17
|
end
|
8
18
|
|
9
19
|
def self.path_for(job)
|
@@ -3,21 +3,13 @@ require 'terminal-announce'
|
|
3
3
|
require 'robot_sweatshop/config'
|
4
4
|
|
5
5
|
module CLI
|
6
|
+
# Methods for starting Robot Sweatshop
|
6
7
|
module Start
|
7
|
-
def self.store_config_for_eye
|
8
|
-
config = configatron.to_h
|
9
|
-
config = config.each do |key, value|
|
10
|
-
config[key] = File.expand_path value if key.to_s.match /_path/
|
11
|
-
end
|
12
|
-
config[:working_path] = Dir.pwd
|
13
|
-
File.write '/tmp/.robot_sweatshop-eye-config.yaml', config.to_yaml
|
14
|
-
end
|
15
|
-
|
16
8
|
def self.sweatshop(for_environment:)
|
17
|
-
|
9
|
+
Config.compile_to_file
|
18
10
|
eye_config = File.expand_path "#{__dir__}/../../../robot_sweatshop.eye"
|
19
11
|
output = `eye load #{eye_config}`
|
20
|
-
|
12
|
+
fail output if $?.exitstatus != 0
|
21
13
|
Announce.success "Robot Sweatshop loaded with a #{for_environment} configuration"
|
22
14
|
Announce.info `eye restart robot_sweatshop`
|
23
15
|
Announce.info 'Run \'eye --help\' for more info on debugging'
|
@@ -5,9 +5,9 @@ configatron.reset!
|
|
5
5
|
|
6
6
|
configurations = [
|
7
7
|
"#{__dir__}/../../config.defaults.yaml",
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
'/etc/robot_sweatshop/config.yaml',
|
9
|
+
'~/.robot_sweatshop/config.yaml',
|
10
|
+
'.robot_sweatshop/config.yaml'
|
11
11
|
]
|
12
12
|
|
13
13
|
configurations.each do |config_path|
|
@@ -2,6 +2,7 @@ require 'ezmq'
|
|
2
2
|
require 'oj'
|
3
3
|
require 'robot_sweatshop/config'
|
4
4
|
|
5
|
+
# Add some common methods to ZMQ sockets that get repeated everywhere
|
5
6
|
module ExtendedEZMQ
|
6
7
|
refine EZMQ::Socket do
|
7
8
|
def serialize_with_json!
|
@@ -10,8 +11,8 @@ module ExtendedEZMQ
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def close
|
13
|
-
|
14
|
-
|
14
|
+
socket.close
|
15
|
+
context.terminate
|
15
16
|
end
|
16
17
|
end
|
17
18
|
end
|
@@ -1,19 +1,12 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
|
3
3
|
def create_path(path)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
puts "Permission denied to create '#{path}'"
|
8
|
-
end
|
4
|
+
FileUtils.mkdir_p path
|
5
|
+
rescue Errno::EACCES
|
6
|
+
puts "Permission denied to create '#{path}'"
|
9
7
|
end
|
10
8
|
|
11
9
|
config = configatron.to_h
|
12
10
|
config.each do |key, value|
|
13
|
-
if key.to_s.match
|
14
|
-
create_path File.expand_path(value)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
%w(pidfile_path logfile_path).each do |path|
|
18
|
-
create_path File.expand_path("#{configatron[path]}/gears")
|
11
|
+
create_path File.expand_path(value) if key.to_s.match(/_path/)
|
19
12
|
end
|
data/robot_sweatshop.eye
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
# TODO: per-user temp file
|
4
|
-
|
4
|
+
CONFIG_PATH = File.expand_path '~/.robot_sweatshop/compiled_config.yaml'
|
5
|
+
CONFIG = YAML.load_file CONFIG_PATH
|
5
6
|
PID_PATH = CONFIG[:pidfile_path]
|
6
7
|
LOG_PATH = CONFIG[:logfile_path]
|
7
8
|
|
data/robot_sweatshop.gemspec
CHANGED
data/test/shared/helpers.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: robot_sweatshop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Scott
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -276,7 +276,9 @@ files:
|
|
276
276
|
- bin/sweatshop-payload-parser
|
277
277
|
- bin/sweatshop-worker
|
278
278
|
- config.defaults.yaml
|
279
|
-
-
|
279
|
+
- docs/README.md
|
280
|
+
- docs/architecture.dot
|
281
|
+
- docs/architecture.gif
|
280
282
|
- lib/robot_sweatshop.rb
|
281
283
|
- lib/robot_sweatshop/cli.rb
|
282
284
|
- lib/robot_sweatshop/cli/common.rb
|
data/lib/README.md
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# Job Lifecycle
|
2
|
-
|
3
|
-
```
|
4
|
-
input -> conveyor
|
5
|
-
{ payload:, user_agent:, job_name: }
|
6
|
-
|
7
|
-
assembler <-> conveyor
|
8
|
-
{ method:, data: } <-> data
|
9
|
-
|
10
|
-
assembler <-> payload-parser
|
11
|
-
{ payload:, user_agent: } <-> { payload:, error: }
|
12
|
-
|
13
|
-
assembler <-> job-dictionary
|
14
|
-
{ job_name: } <-> { payload:, error: }
|
15
|
-
|
16
|
-
assembler -> worker
|
17
|
-
{ context:, commands:, job_name:, job_id }
|
18
|
-
```
|
19
|
-
|
20
|
-
context is passed around with string keys because it's user provided
|
21
|
-
everything else is passed with symbol keys
|
22
|
-
|
23
|
-
# Services
|
24
|
-
|
25
|
-
sweatshop-conveyor
|
26
|
-
```
|
27
|
-
{ method:, data: }
|
28
|
-
|
29
|
-
id = enqueue(item)
|
30
|
-
id = dequeue
|
31
|
-
item = lookup(id)
|
32
|
-
something = finish(id)
|
33
|
-
```
|
34
|
-
|
35
|
-
sweatshop-payload-parser
|
36
|
-
```
|
37
|
-
req: { payload:, user_agent: }
|
38
|
-
rep: { data:, error: }
|
39
|
-
```
|
40
|
-
|
41
|
-
sweatshop-job-dictionary
|
42
|
-
```
|
43
|
-
req: { job_name: }
|
44
|
-
rep: { data:, error: }
|
45
|
-
```
|