sub_zero 0.0.4 → 0.0.5

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: 1d2f91d35235df49176ba39a8f3cd6bf5cbca454
4
- data.tar.gz: ada80f112ceff71a231d9bf2b05c05ce30cb66a2
3
+ metadata.gz: 41d022d98d371aa71c53fbe297f481015d5293f7
4
+ data.tar.gz: d6f1bdd5be50e6ed39640cafe7e350647e8f38e7
5
5
  SHA512:
6
- metadata.gz: 496a8f67eb47c3105724e05cab034f5efd519c120f7d6807de1173b2015c57692a622d6f25204fa11446be2a5fb84276d9c58dbe2727929108d79f85bcc11ac1
7
- data.tar.gz: 5d0dc86764da65b7eacff51daa6431fd091a7a2055864bc8c84377bf8f15488df15ebc569c382ea2505e1cdfb6103ccc33929fbfb43ff962b329d9d64bf25174
6
+ metadata.gz: 127f4ed3c1f8606bbdfb28203aefb15743cb4a54d5619e4c6033faab2bccc806c1bd9ca9be0f6c71da013c966c7e93bc913aea9deb5e68c8ba98a2e3e9068efa
7
+ data.tar.gz: af1707609bc526c600b64a60d909f97bce87b7e9731c3b72eaee9824d97161726517c5fd4319673905b4ab3cf4849ecf8cab63631427c6033eba52727cf30b28
@@ -1,7 +1,8 @@
1
1
  module SubZero
2
2
  module CLI
3
3
  class App < Thor
4
- register SubZero::CLI::New, 'new', 'new TYPE NAME', 'Creates a new TYPE (service/client) named NAME'
4
+ register SubZero::CLI::New, 'new', 'new TYPE NAME',
5
+ 'Creates a new TYPE (service/client) named NAME'
5
6
  end
6
7
  end
7
8
  end
@@ -1,12 +1,5 @@
1
- require 'active_support/string_inquirer'
2
- require 'active_support/hash_with_indifferent_access'
3
-
4
1
  module SubZero
5
2
  class Client
6
- autoload :Configuration, 'sub_zero/client/configuration'
7
- autoload :Socket, 'sub_zero/client/socket'
8
-
9
- include Socket
10
3
 
11
4
  attr_reader :sid, :config
12
5
 
@@ -15,11 +8,24 @@ module SubZero
15
8
  yield @config if block_given?
16
9
  end
17
10
 
11
+ def socket
12
+ Socket.new config
13
+ end
14
+
18
15
  def call verb, payload = {}, options = {}
19
16
  sz_verb = verb.to_s.upcase.gsub('_', '/')
20
- status, result = zeromq_fetch(sz_verb, payload, options)
21
- result = handle_result(status, result).with_indifferent_access
22
- block_given? ? yield(result) : result
17
+
18
+ request = Message.new(type: 'REQ', subtype: sid, verb: sz_verb,
19
+ payload: payload, options: options)
20
+
21
+ response = socket.call(request)
22
+
23
+ if block_given?
24
+ yield response
25
+ else
26
+ fail Error.new(response) if response.error?
27
+ response.payload
28
+ end
23
29
  end
24
30
 
25
31
  def call! verb, payload = {}, options = {}, &block
@@ -32,33 +38,24 @@ module SubZero
32
38
 
33
39
  def method_missing method, payload = {}, options = {}, &block
34
40
  if method.to_s.end_with? '!'
35
- call! method.delete('!'), payload, options, &block
41
+ call! method.to_s.delete('!'), payload, options, &block
36
42
  else
37
43
  call method, payload, options, &block
38
44
  end
39
45
  end
40
46
 
41
- def handle_result status, result
42
- case status
43
- when :ok
44
- result
45
- when :error
46
- fail Error.new(result['error'])
47
- end
48
- end
49
-
50
47
  class Error < ::StandardError
51
48
 
52
49
  attr_reader :result
53
50
 
54
- def initialize result
55
- super result['message']
51
+ def initialize response
52
+ super response.payload['message']
56
53
  set_backtrace caller
57
- @result = result
54
+ @result = response
58
55
  end
59
56
 
60
57
  def code
61
- result['code']
58
+ result.payload['code']
62
59
  end
63
60
 
64
61
  def status
@@ -0,0 +1,10 @@
1
+ module SubZero
2
+ module Configuration
3
+ extend self
4
+
5
+ def default
6
+ { ip: '127.0.0.1', port: 7777 }
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module SubZero
2
+ module Environment
3
+
4
+ def env
5
+ environment = ENV['SUBZERO_ENV'] || ENV['SZ_ENV'] || 'development'
6
+ ActiveSupport::StringInquirer.new environment
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,58 @@
1
+ require 'colorize'
2
+
3
+ module SubZero
4
+ module Loggable
5
+
6
+ COLORS = [:red, :green, :yellow, :blue, :magenta, :cyan,
7
+ :light_red, :light_green, :light_yellow, :light_blue, :light_magenta, :light_cyan]
8
+
9
+ SEVERITIES = [:info, :warn, :error, :debug]
10
+
11
+ SEVERITY_COLORS = { info: :light_blue }
12
+
13
+ SEVERITIES.each do |severity|
14
+ define_method severity do |message, context = {}|
15
+ log message, { severity: severity }.merge(context)
16
+ end
17
+ end
18
+
19
+ def error exception, message
20
+ super message, error: exception
21
+ end
22
+
23
+ def log message, context = {}
24
+ sender_class = self.kind_of?(Class) ? self : self.class
25
+ context.merge! sender_class: sender_class.to_s
26
+ context[:severity] ||= :info
27
+
28
+ puts log_colored_message(message, context)
29
+ end
30
+
31
+ def self.included(base)
32
+ base.extend self
33
+ end
34
+
35
+ private
36
+
37
+ def log_colored_message(message, context)
38
+ msg = log_colored_severity(context[:severity])
39
+ msg << " #{Time.now.strftime('%Y%m%d%H%M%S%L')}"
40
+
41
+ if sender_class = context.delete(:sender_class)
42
+ msg = log_colored_term(sender_class)
43
+ end
44
+
45
+ msg << " #{message}"
46
+ end
47
+
48
+ def log_colored_severity(severity)
49
+ severity.to_s.colorize SEVERITY_COLORS[severity.to_sym]
50
+ end
51
+
52
+ def log_colored_term(term)
53
+ index = Integer("0x#{Digest::MD5.hexdigest(term)[0, 2]}") % 12
54
+ term.colorize COLORS[index]
55
+ end
56
+
57
+ end
58
+ end
@@ -1,11 +1,10 @@
1
1
  module SubZero
2
2
  module Common
3
+ include SubZero::Environment
4
+
3
5
  def log msg, level='DEBUG'
4
6
  puts "#{level}: #{msg}"
5
7
  end
6
8
 
7
- def env
8
- ENV['SUBZERO_ENV'] || 'development'
9
- end
10
9
  end
11
- end
10
+ end
@@ -0,0 +1,65 @@
1
+ module SubZero
2
+ class Message
3
+ module Parser
4
+ extend ActiveSupport::Concern
5
+
6
+ def to_source
7
+ frames = []
8
+
9
+ if subtype.present?
10
+ frames << "#{type}:#{subtype}"
11
+ else
12
+ frames << type
13
+ end
14
+
15
+ frames << rid
16
+
17
+ if status.present?
18
+ frames << "#{verb}:#{status}"
19
+ else
20
+ frames << verb
21
+ end
22
+
23
+ frames << payload.to_msgpack
24
+ frames << options.to_msgpack
25
+
26
+ frames
27
+ end
28
+
29
+ module ClassMethods
30
+
31
+ def from_source source
32
+ type = source.shift
33
+
34
+ if type.index ':'
35
+ type, subtype = type.split(':')
36
+ end
37
+
38
+ rid = source.shift
39
+ verb = source.shift
40
+
41
+ if verb.index ':'
42
+ verb, status = verb.split(':')
43
+ end
44
+
45
+ payload = MessagePack.unpack(source.shift).with_indifferent_access
46
+
47
+ unless source.empty?
48
+ routing_info = MessagePack.unpack(source.shift).with_indifferent_access
49
+ end
50
+
51
+ new type: type, rid: rid, verb: verb, payload: payload,
52
+ subtype: subtype, status: status, routing_info: routing_info
53
+ end
54
+
55
+ def parse source, request = nil
56
+ from_source(source).tap do |m|
57
+ m.validate_response!(request) if request
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,29 @@
1
+ module SubZero
2
+ class Message
3
+ module Validations
4
+
5
+ def validate_response! request
6
+ broker_reply = type == 'BRO'
7
+ service_reply = type == 'REP' && subtype == request.sid
8
+
9
+ unless broker_reply || service_reply
10
+ fail Socket::Error, "unexpected result type: #{type}, " +
11
+ "subtype: #{subtype}. " + to_s
12
+ end
13
+
14
+ unless rid == request.rid
15
+ fail Socket::Error, "rid mismatch. sent: #{request.rid}, " +
16
+ "received: #{rid}. " + to_s
17
+ end
18
+
19
+ unless verb == request.verb && response?
20
+ fail Socket::Error, "reply verb mismatch: #{verb}, " +
21
+ "status: #{status}. " + to_s
22
+ end
23
+
24
+ true
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'message/parser'
2
+ require_relative 'message/validations'
3
+
4
+ module SubZero
5
+ class Message
6
+ include Parser
7
+ include Validations
8
+
9
+ attr_accessor :type,
10
+ :subtype,
11
+ :rid,
12
+ :verb,
13
+ :status,
14
+ :payload,
15
+ :options
16
+
17
+ def initialize args = {}
18
+ @type, @subtype = args.values_at(:type, :subtype)
19
+ @rid = args[:rid] || SecureRandom.uuid
20
+ @verb, @status = args.values_at(:verb, :status)
21
+ @payload = args[:payload] || {}
22
+ @options = args[:options] || {}
23
+ end
24
+
25
+ alias :sid :subtype
26
+ alias :routing_info :options
27
+
28
+ def heartbeat?
29
+ verb == 'PONG'
30
+ end
31
+
32
+ def request?
33
+ status.blank?
34
+ end
35
+
36
+ def response?
37
+ not request?
38
+ end
39
+
40
+ def success?
41
+ status == 'OK'
42
+ end
43
+
44
+ def error?
45
+ status == 'NOK'
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,30 @@
1
+ module SubZero
2
+ module Service
3
+ class Handler
4
+
5
+ attr_reader :message
6
+
7
+ delegate :rid, :verb, :payload, to: :message
8
+
9
+ alias :request_id :rid
10
+ alias :params :payload
11
+
12
+ def initialize message
13
+ @message = message
14
+ end
15
+
16
+ # verb, payload = nil
17
+ # payload (same verb with :OK)
18
+ def reply *args
19
+ end
20
+
21
+ def reply_with payload
22
+ reply verb, payload
23
+ end
24
+
25
+ def error code, message
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ require 'active_support/inflector'
2
+
3
+ module SubZero
4
+ module Service
5
+ module Router
6
+
7
+ def routes
8
+ @routes ||= {}
9
+ end
10
+
11
+ def route &block
12
+ instance_eval &block
13
+ end
14
+
15
+ def verb args
16
+ name, route = Hash[args].first
17
+ routes[name.to_s.upcase] = handler_caller(route)
18
+
19
+ true
20
+ end
21
+
22
+ private
23
+
24
+ def handler_caller route
25
+ handler, action = route.to_s.split('#')
26
+
27
+ begin
28
+ handler_name = "Handlers::#{handler.camelize}"
29
+ handler_class = const_get(handler_name)
30
+ rescue
31
+ fail "Handler not found: #{handler_name}"
32
+ end
33
+
34
+ proc { |message| handler_class.new(message).send action }
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,33 @@
1
+ module SubZero
2
+ module Runner
3
+
4
+ def run!
5
+ Daemons.run_proc sid, daemon_configuration do
6
+ start = Time.now
7
+ ping_at = start + 5
8
+
9
+ Signal.trap('INT') { socket.down!; exit }
10
+ Signal.trap('TERM') { socket.down!; exit }
11
+
12
+ socket.up!
13
+
14
+ loop do
15
+ socket.run &method(:resolve)
16
+
17
+ now = Time.now
18
+
19
+ if now >= ping_at
20
+ socket.ping
21
+ ping_at = now + 15
22
+ end
23
+
24
+ break if $stop_requested
25
+ end
26
+
27
+ socket.down!
28
+ exit 0
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'service/handler'
2
+ require_relative 'service/router'
3
+ require_relative 'service/runner'
4
+
5
+ module SubZero
6
+ module Service
7
+ include Router
8
+ include Loggable
9
+ include Runner
10
+
11
+ def sid service_id = nil
12
+ @sid = service_id.to_sym if service_id
13
+ @sid
14
+ end
15
+
16
+ def resolve message
17
+ if handler = routes[message.verb]
18
+ handler[message]
19
+ else
20
+ # TODO verb mismatch error
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def socket
27
+ Socket.new
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ module SubZero
2
+ class Socket
3
+ module Sender
4
+
5
+ def call request
6
+ response = nil
7
+ t = request.options.fetch(:timeout, 1000) / 1000.0
8
+
9
+ ::Timeout.timeout t do
10
+ context do |c|
11
+ socket c do |s|
12
+ send_message s, request
13
+ response = receive_message(s, request)
14
+ end
15
+ end
16
+ end
17
+
18
+ response
19
+ rescue ::Timeout::Error
20
+ raise SubZero::Socket::TimeoutError
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ module SubZero
2
+ class Socket
3
+ module Server
4
+
5
+ def run &handle_message
6
+ context do |c|
7
+ socket c do |s|
8
+ poll s do |m|
9
+ handle_message[m]
10
+ end
11
+ end
12
+ end
13
+ rescue => e
14
+ error e, 'failed while running server, going to retry'
15
+ retry
16
+ end
17
+
18
+ def up!
19
+ send_server_verb 'UP'
20
+ end
21
+
22
+ def down!
23
+ send_server_verb 'DOWN'
24
+ end
25
+
26
+ def ping
27
+ send_server_verb 'PING'
28
+ end
29
+
30
+ def send_server_verb verb
31
+ context do |c|
32
+ socket c do |s|
33
+ send_message s, Message.new(type: 'SRV', verb: verb)
34
+ end
35
+ end
36
+ end
37
+
38
+ def poll socket
39
+ ZMQ::Poller.new.tap do |p|
40
+ p.register socket, ZMQ::POLLIN
41
+ p.poll 1
42
+
43
+ p.readables.each do |s|
44
+ s.recv_strings source = []
45
+
46
+ begin
47
+ message = Message.parse(source)
48
+ rescue => e
49
+ error e, 'error parsing message'
50
+ end
51
+
52
+ yield message if message
53
+ end
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,65 @@
1
+ require 'ffi-rzmq'
2
+ require 'msgpack'
3
+
4
+ require_relative 'socket/sender'
5
+ require_relative 'socket/server'
6
+
7
+ module SubZero
8
+ class Socket
9
+ include Loggable
10
+ include Sender
11
+ include Server
12
+
13
+ class Error < StandardError; end
14
+ class TimeoutError < Socket::Error; end
15
+
16
+ attr_reader :config
17
+
18
+ def initialize config = Configuration.default
19
+ @config = config
20
+ end
21
+
22
+ def context
23
+ context = ZMQ::Context.create(1)
24
+ fail Socket::Error, 'failed to create context' unless context
25
+ yield context
26
+ check! context.terminate
27
+ rescue Socket::Error
28
+ check! context.terminate
29
+ raise
30
+ end
31
+
32
+ def socket context
33
+ socket = context.socket ZMQ::DEALER
34
+ socket.identity = SecureRandom.hex(10)
35
+ check! socket.connect("tcp://#{config[:ip]}:#{config[:port]}")
36
+ yield socket
37
+ check! socket.close
38
+ rescue Socket::Error
39
+ check! socket.close
40
+ raise
41
+ end
42
+
43
+ def send_message socket, message
44
+ frames = message.to_source
45
+ last = frames.pop
46
+ frames.each { |f| check! socket.send_string f.to_s, ZMQ::SNDMORE }
47
+ check! socket.send_string last
48
+ end
49
+
50
+ def receive_message socket, request
51
+ check! socket.recv_strings(frames = [])
52
+ Message.parse frames, request
53
+ end
54
+
55
+ def check! result_code
56
+ return if ZMQ::Util.resultcode_ok? result_code
57
+
58
+ fail Socket::Error, "operation failed, errno [#{ZMQ::Util.errno}], " +
59
+ "description [#{ZMQ::Util.error_string}]"
60
+ rescue
61
+ raise Socket::Error "operation failed, cannot have errno"
62
+ end
63
+
64
+ end
65
+ end
@@ -1,3 +1,3 @@
1
1
  module SubZero
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
data/lib/sub_zero.rb CHANGED
@@ -1,17 +1,30 @@
1
1
  require 'yaml'
2
2
  require 'securerandom'
3
3
  require 'timeout'
4
+ require 'digest/md5'
4
5
 
5
6
  require 'thor'
6
7
  require 'thor/group'
7
8
 
9
+ require 'active_support/string_inquirer'
10
+ require 'active_support/hash_with_indifferent_access'
11
+ require 'active_support/concern'
12
+ require 'active_support/core_ext/module/delegation'
13
+
8
14
  require_relative 'sub_zero/version'
15
+ require_relative 'sub_zero/environment'
9
16
  require_relative 'sub_zero/main'
10
17
 
11
18
  module SubZero
12
- autoload :CLI, 'sub_zero/cli'
13
- autoload :Client, 'sub_zero/client'
19
+ autoload :CLI, 'sub_zero/cli'
20
+ autoload :Client, 'sub_zero/client'
21
+ autoload :Configuration, 'sub_zero/configuration'
22
+ autoload :Loggable, 'sub_zero/loggable'
23
+ autoload :Message, 'sub_zero/message'
24
+ autoload :Service, 'sub_zero/service'
25
+ autoload :Socket, 'sub_zero/socket'
14
26
  extend self
27
+ extend Environment
15
28
 
16
29
  def client service_id
17
30
  block_given? ? Client.new(service_id, &block) : Client.new(service_id)
data/spec/spec_helper.rb CHANGED
@@ -0,0 +1,9 @@
1
+ ENV['SZ_ENV'] ||= 'test'
2
+
3
+ $:.push '.'
4
+
5
+ require 'rspec'
6
+ require 'pry'
7
+ require 'sub_zero'
8
+
9
+ Dir['spec/support/**/*.rb'].each &method(:require)
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe SubZero::Client do
4
+
5
+ subject { described_class.new :sid }
6
+
7
+ let(:config) { { ip: '127.0.0.1', port: 7777 } }
8
+
9
+ its(:sid) { should eq('SID') }
10
+ its(:config) { should eq(config) }
11
+
12
+ describe '#socket' do
13
+ let(:socket) { double :socket }
14
+
15
+ before do
16
+ SubZero::Socket.stub(:new).with(config) { socket }
17
+ end
18
+
19
+ its(:socket) { should eq(socket) }
20
+ end
21
+
22
+ describe '#call' do
23
+ let(:socket) { double :socket }
24
+ let(:response) { double :response, error?: false, payload: { found: true } }
25
+
26
+ before do
27
+ subject.stub(:socket) { socket }
28
+
29
+ socket.should_receive :call do |request|
30
+ request.type.should eq('REQ')
31
+ request.sid.should eq('SID')
32
+ request.verb.should eq('GET/USER')
33
+ request.payload.should eq(id: 2)
34
+ request.options.should eq(timeout: 30)
35
+ response
36
+ end
37
+ end
38
+
39
+ it 'returns response payload' do
40
+ subject.call(:get_user, { id: 2 }, { timeout: 30 }).should eq(found: true)
41
+ end
42
+
43
+ it 'injects full response in block' do
44
+ subject.call :get_user, { id: 2 }, { timeout: 30 } do |result|
45
+ result.should eq(response)
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '#[]' do
51
+ let(:response) { double :response }
52
+
53
+ it 'is a different way to do call' do
54
+ subject.should_receive(:call).with(:get_user) { response }
55
+ subject[:get_user].should eq(response)
56
+ end
57
+ end
58
+
59
+ describe 'calling verbs via method missing' do
60
+ let(:response) { double :response }
61
+ let(:args) { [{ id: 2 }, { timeout: 3000 }] }
62
+
63
+ it 'calls verb with method missing name' do
64
+ subject.should_receive(:call).with(:get_user, *args) { response }
65
+ subject.get_user(*args).should eq(response)
66
+
67
+ subject.should_receive(:call!).with('get_user', *args) { response }
68
+ subject.get_user!(*args).should eq(response)
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe SubZero::Environment do
4
+
5
+ subject do
6
+ Class.new { extend SubZero::Environment }
7
+ end
8
+
9
+ its(:env) { should eq('test') }
10
+
11
+ specify '#env?' do
12
+ subject.env.test?.should be_true
13
+ subject.env.development?.should be_false
14
+ end
15
+
16
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe SubZero::Service do
4
+
5
+ class Auditing
6
+ extend SubZero::Service
7
+
8
+ sid :auditing
9
+ end
10
+
11
+ class Auditing
12
+ module Handlers
13
+ class Logs < SubZero::Service::Handler
14
+ end
15
+ end
16
+ end
17
+
18
+ subject { Auditing }
19
+
20
+ describe '.sid' do
21
+ it 'retrieves sid' do
22
+ subject.sid.should eq(:auditing)
23
+ end
24
+ end
25
+
26
+ describe '.route' do
27
+ before do
28
+ subject.route do
29
+ verb list: 'logs#index'
30
+ end
31
+ end
32
+
33
+ it 'defines routes' do
34
+ subject.routes.key?('LIST').should be_true
35
+ end
36
+ end
37
+
38
+ end
data/sub_zero.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'sub_zero/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "sub_zero"
7
+ spec.name = 'sub_zero'
8
8
  spec.version = SubZero::VERSION
9
9
  spec.authors = ["Victor Rodrigues", "Bruno Antunes"]
10
10
  spec.email = ["victorc.rodrigues@gmail.com", "sardaukar.siet@gmail.com"]
@@ -21,9 +21,12 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency 'bundler', '~> 1.3'
22
22
  spec.add_development_dependency 'rake'
23
23
  spec.add_development_dependency 'rspec'
24
+ spec.add_development_dependency 'pry'
24
25
 
25
26
  spec.add_dependency 'thor'
26
27
  spec.add_dependency 'msgpack'
27
28
  spec.add_dependency 'ffi-rzmq'
28
29
  spec.add_dependency 'activesupport'
30
+ spec.add_dependency 'colorize'
31
+ spec.add_dependency 'daemons'
29
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sub_zero
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Rodrigues
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-29 00:00:00.000000000 Z
12
+ date: 2013-09-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -53,6 +53,20 @@ dependencies:
53
53
  - - '>='
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: pry
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: thor
58
72
  requirement: !ruby/object:Gem::Requirement
@@ -109,6 +123,34 @@ dependencies:
109
123
  - - '>='
110
124
  - !ruby/object:Gem::Version
111
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: colorize
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: daemons
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :runtime
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
112
154
  description: ZeroMQ SOA solution
113
155
  email:
114
156
  - victorc.rodrigues@gmail.com
@@ -148,12 +190,26 @@ files:
148
190
  - lib/sub_zero/cli/templates/ruby/service/verbs.tt
149
191
  - lib/sub_zero/cli/templates/ruby/service/version.tt
150
192
  - lib/sub_zero/client.rb
151
- - lib/sub_zero/client/configuration.rb
152
- - lib/sub_zero/client/socket.rb
193
+ - lib/sub_zero/configuration.rb
194
+ - lib/sub_zero/environment.rb
195
+ - lib/sub_zero/loggable.rb
153
196
  - lib/sub_zero/main.rb
154
197
  - lib/sub_zero/main/common.rb
198
+ - lib/sub_zero/message.rb
199
+ - lib/sub_zero/message/parser.rb
200
+ - lib/sub_zero/message/validations.rb
201
+ - lib/sub_zero/service.rb
202
+ - lib/sub_zero/service/handler.rb
203
+ - lib/sub_zero/service/router.rb
204
+ - lib/sub_zero/service/runner.rb
205
+ - lib/sub_zero/socket.rb
206
+ - lib/sub_zero/socket/sender.rb
207
+ - lib/sub_zero/socket/server.rb
155
208
  - lib/sub_zero/version.rb
156
209
  - spec/spec_helper.rb
210
+ - spec/sub_zero/client_spec.rb
211
+ - spec/sub_zero/environment_spec.rb
212
+ - spec/sub_zero/service_spec.rb
157
213
  - sub_zero.gemspec
158
214
  - thoughts.md
159
215
  homepage: ''
@@ -182,3 +238,6 @@ specification_version: 4
182
238
  summary: ZeroMQ GREAT SOA solution
183
239
  test_files:
184
240
  - spec/spec_helper.rb
241
+ - spec/sub_zero/client_spec.rb
242
+ - spec/sub_zero/environment_spec.rb
243
+ - spec/sub_zero/service_spec.rb
@@ -1,12 +0,0 @@
1
- module SubZero
2
- class Client
3
- module Configuration
4
- extend self
5
-
6
- def default
7
- { ip: '127.0.0.1', port: 7777 }
8
- end
9
-
10
- end
11
- end
12
- end
@@ -1,98 +0,0 @@
1
- require 'ffi-rzmq'
2
- require 'msgpack'
3
-
4
- module SubZero
5
- class Client
6
- module Socket
7
-
8
- class SocketError < StandardError; end
9
-
10
- private
11
-
12
- def zeromq_fetch verb, payload = {}, options = {}
13
- result = []
14
-
15
- timeout = options.fetch(:timeout, 1000) / 1000.0
16
-
17
- Timeout.timeout timeout do
18
- zeromq_context do |context|
19
- zeromq_socket context do |socket|
20
- rid = SecureRandom.uuid
21
- zeromq_send socket, "REQ:#{sid}", rid, verb, payload.to_msgpack, options.to_msgpack
22
- result = zeromq_result(socket, rid, verb)
23
- end
24
- end
25
- end
26
-
27
- result
28
- rescue Timeout::Error
29
- raise SubZero::Client::Error.new(code: 'timeout', message: "call timeout: #{timeout}s")
30
- end
31
-
32
- def zeromq_context
33
- context = ZMQ::Context.create(1)
34
- fail SocketError, 'failed to create context' unless context
35
- yield context
36
- ensure
37
- zcc!(context.terminate) if context
38
- end
39
-
40
- def zeromq_socket context
41
- socket = context.socket ZMQ::DEALER
42
- socket.identity = SecureRandom.hex(10)
43
- zcc! socket.connect("tcp://#{config[:ip]}:#{config[:port]}")
44
- yield socket
45
- ensure
46
- zcc! socket.close
47
- end
48
-
49
- def zeromq_send socket, *msgs
50
- last = msgs.pop
51
- msgs.each { |m| zcc! socket.send_string m, ZMQ::SNDMORE }
52
- zcc! socket.send_string last
53
- end
54
-
55
- def zeromq_check_code! result_code
56
- return if ZMQ::Util.resultcode_ok? result_code
57
-
58
- fail SocketError, "operation failed, errno [#{ZMQ::Util.errno}], " +
59
- "description [#{ZMQ::Util.error_string}]"
60
- end
61
-
62
- alias :zcc! :zeromq_check_code!
63
-
64
- def zeromq_result socket, rid, verb
65
- result = []
66
- zcc! socket.recv_strings(result)
67
-
68
- zeromq_validate_result! rid, verb, result
69
-
70
- routing_info = MessagePack.unpack(result.pop)
71
- payload = MessagePack.unpack(result.pop)
72
- rep_verb = result.pop
73
- status = rep_verb.end_with?('NOK') ? :error : :ok
74
-
75
- [status, payload]
76
- end
77
-
78
- def zeromq_validate_result! rid, verb, result
79
- type, rep_rid, rep_verb, payload = result
80
-
81
- common = "result: #{result}"
82
-
83
- unless type == "REP:#{sid}" || type == 'BRO'
84
- fail SocketError, "unexpected result type: #{type}. " + common
85
- end
86
-
87
- unless rid == rep_rid
88
- fail SocketError, "rid mismatch. sent: #{rid}, received: #{rep_id}. " + common
89
- end
90
-
91
- unless rep_verb == "#{verb}:OK" || rep_verb == "#{verb}:NOK"
92
- fail SocketError, "reply verb mismatch: #{rep_verb}. " + common
93
- end
94
- end
95
-
96
- end
97
- end
98
- end