robot_sweatshop 0.4.6 → 0.4.7
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/.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
|
+

|
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
|
-
```
|