radagast 0.0.1.pre.dev → 0.0.1

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