radagast 0.0.1.pre.dev → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f007912a5b7b16f956098e6deb659ea4867c7716
4
- data.tar.gz: 51dd34ce29364443a50a5a40d36bb5adcb7fa9ec
3
+ metadata.gz: 560f233b948a123e0fb646dceeb36fcb04d59e70
4
+ data.tar.gz: 708db7870f7d5d310bc9075bd5a410d2e3892b1c
5
5
  SHA512:
6
- metadata.gz: 0fa4bcc392cc02f97951f8987ca09b036c8eb906eaee8a5e86f77d4fb44e8c97379427838c3692d9578f241c20db36defe0cccf60117d2d290d40e0d19816559
7
- data.tar.gz: 7dba764106400d4fbf9ab603763a69298af36f9348f405dd50420ae29c8d8b4a07c51998710795e07d9b65f1355f1a7ce1b42bd23cddcee588f387cc1c16363f
6
+ metadata.gz: 625289d4021c881f27e268fe41f202e02bddb279bb9cbdf7426444440382bc28d7f14964074c3d7811120b1e1bcfeb86ed46951d41fe378af41876017c9197b2
7
+ data.tar.gz: bcdd6fabb52f4dee4e4fa2aeae653ca6059554011cc41f410ced512b9d4ebb141012e98117b378b3b9be92eea7e2717bf270f3c1def0403f85857bfd8e2c70ae
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ docker stop rabbit-radagast
4
+ docker rm rabbit-radagast
5
+
6
+ docker run -d \
7
+ --hostname rabbit-radagast \
8
+ --name rabbit-radagast \
9
+ -p 5672:5672 \
10
+ -p 15672:15672 \
11
+ -e RABBITMQ_ERLANG_COOKIE='radagast' \
12
+ rabbitmq:3
13
+
14
+ sleep 3
15
+ docker exec rabbit-radagast rabbitmq-plugins enable rabbitmq_management
16
+ docker restart rabbit-radagast
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ docker stop rabbit-radagast
4
+ docker rm rabbit-radagast
data/bin/radagast CHANGED
@@ -1,3 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- puts "Nothing here yet"
3
+ require_relative '../lib/radagast/config'
4
+ require_relative '../lib/radagast/worker'
5
+
6
+ config = Radagast::Config.parse_argv
7
+ worker = Radagast::Worker.new config
8
+
9
+ begin
10
+ worker.start
11
+ rescue SystemExit, Interrupt
12
+ worker.finish
13
+ end
@@ -0,0 +1,22 @@
1
+ require 'optparse'
2
+ require 'logger'
3
+
4
+ module Radagast
5
+ Config = Struct.new(:key, :rabbit, :log_level) do
6
+ def initialize
7
+ self.key = 'default'
8
+ self.rabbit = 'amqp://guest:guest@127.0.0.1:5672'
9
+ self.log_level = Logger::UNKNOWN
10
+ end
11
+
12
+ def self.parse_argv(argv = ARGV)
13
+ config = new
14
+ OptionParser.new do |opt|
15
+ opt.on('--key KEY') { |o| config.key = o }
16
+ opt.on('--rabbit RABBIT') { |o| config.rabbit = o }
17
+ opt.on('--log_level LOG_LEVEL') { |o| config.log_level = const_get(o) }
18
+ end.parse!(argv)
19
+ config
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,58 @@
1
+ require_relative 'config'
2
+ require_relative 'rabbit_helper'
3
+ require_relative 'result'
4
+
5
+ module Radagast
6
+ # Dispatches tasks and aggregates the results
7
+ class Manager < RabbitHelper
8
+ def initialize(config)
9
+ super(
10
+ queue_name: "results-#{config.key}",
11
+ routing_key: "tasks-#{config.key}",
12
+ config: config
13
+ )
14
+ @callbacks = {}
15
+ @processed_cnt = 0
16
+ @published_cnt = 0
17
+ @all_results = []
18
+ end
19
+
20
+ def task(cmd, &blk)
21
+ logger.info 'Publishing task'
22
+ @published_cnt += 1
23
+ @callbacks[cmd] = blk
24
+ publish(cmd: cmd)
25
+ end
26
+
27
+ def process_callback(data)
28
+ logger.info "Result #{@processed_cnt}/#{@published_cnt} is here: #{data}"
29
+ result = Result.new
30
+ result.exit_code = data['exitstatus']
31
+ result.stderr = data['stderr'].strip
32
+ result.stdout = data['stdout'].strip
33
+ result.meta = { cmd: data['cmd'] }
34
+ @callbacks[data['cmd']].call result
35
+ end
36
+
37
+ def finish
38
+ logger.info 'Finishing manager'
39
+ @t.join
40
+ yield @all_results if block_given?
41
+ end
42
+
43
+ def start
44
+ @t = Thread.new do
45
+ logger.info 'Manager subscribe to results queue'
46
+ subscribe do |data|
47
+ @processed_cnt += 1
48
+ process_callback data
49
+ @all_results << data
50
+ if @processed_cnt == @published_cnt
51
+ logger.info "All #{@processed_cnt} messages have been processed"
52
+ cleanup
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ require 'bunny'
2
+ require 'json'
3
+ require 'logger'
4
+
5
+ module Radagast
6
+ # Wraps RabbitMQ internals to provide simple API to Worker and Manager
7
+ class RabbitHelper
8
+ attr_reader :logger
9
+
10
+ def initialize(queue_name:, routing_key:, config:)
11
+ @rabbit = Bunny.new config.rabbit
12
+ @rabbit.start
13
+ @routing_key = routing_key
14
+ @channel = @rabbit.create_channel
15
+ @exchange = @channel.default_exchange
16
+ @queue = @channel.queue(queue_name, auto_delete: true)
17
+ @logger = Logger.new(STDOUT)
18
+ @logger.level = config.log_level
19
+ end
20
+
21
+ def cleanup
22
+ @rabbit.close
23
+ end
24
+
25
+ def publish(data)
26
+ logger.info "publishing #{data}"
27
+ @exchange.publish(JSON.generate(data), routing_key: @routing_key)
28
+ end
29
+
30
+ def subscribe
31
+ @queue.subscribe(block: true) do |_delivery_info, _metadata, payload|
32
+ data = JSON.parse(payload)
33
+ logger.info "processing #{data}"
34
+ yield data
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Radagast
2
+ Result = Struct.new(:exit_code, :stdout, :stderr, :meta)
3
+ end
@@ -0,0 +1,38 @@
1
+ require 'json'
2
+ require 'open3'
3
+
4
+ require_relative 'config'
5
+ require_relative 'rabbit_helper'
6
+
7
+ module Radagast
8
+ # Fetches the task, processes it and returns the result
9
+ class Worker < RabbitHelper
10
+ def initialize(config)
11
+ super(
12
+ queue_name: "tasks-#{config.key}",
13
+ routing_key: "results-#{config.key}",
14
+ config: config
15
+ )
16
+ end
17
+
18
+ def start
19
+ logger.info 'Worker setup, subscribing to tasks queue'
20
+ subscribe do |data|
21
+ stdout, stderr, status = Open3.capture3(data['cmd'])
22
+ response = {
23
+ cmd: data['cmd'],
24
+ meta: data['meta'],
25
+ stdout: stdout,
26
+ stderr: stderr,
27
+ exitstatus: status.exitstatus
28
+ }
29
+ publish(response)
30
+ end
31
+ end
32
+
33
+ def finish
34
+ logger.info 'Finishing worker'
35
+ cleanup
36
+ end
37
+ end
38
+ end
data/lib/radagast.rb ADDED
@@ -0,0 +1,4 @@
1
+ require_relative 'radagast/config'
2
+ require_relative 'radagast/manager'
3
+ require_relative 'radagast/worker'
4
+ require_relative 'radagast/result'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radagast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre.dev
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bartek Wilczek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-16 00:00:00.000000000 Z
11
+ date: 2017-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -24,15 +24,38 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.6'
27
- description: Use docker swarm and rabbitmq to distribute tasks. Designed for faster
28
- test execution.
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.7'
41
+ description: |-
42
+ Use docker swarm and rabbitmq to distribute tasks. \
43
+ Designed for faster test execution.
29
44
  email: bwilczek@gmail.com
30
45
  executables:
31
46
  - radagast
32
47
  extensions: []
33
48
  extra_rdoc_files: []
34
49
  files:
50
+ - bin/rabbit-restart.sh
51
+ - bin/rabbit-stop.sh
35
52
  - bin/radagast
53
+ - lib/radagast.rb
54
+ - lib/radagast/config.rb
55
+ - lib/radagast/manager.rb
56
+ - lib/radagast/rabbit_helper.rb
57
+ - lib/radagast/result.rb
58
+ - lib/radagast/worker.rb
36
59
  homepage: https://github.com/bwilczek/radagast
37
60
  licenses:
38
61
  - MIT
@@ -48,9 +71,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
48
71
  version: '2.0'
49
72
  required_rubygems_version: !ruby/object:Gem::Requirement
50
73
  requirements:
51
- - - ">"
74
+ - - ">="
52
75
  - !ruby/object:Gem::Version
53
- version: 1.3.1
76
+ version: '0'
54
77
  requirements: []
55
78
  rubyforge_project:
56
79
  rubygems_version: 2.6.8