sub_zero 0.0.1 → 0.0.3

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +20 -0
  3. data/README.md +1 -1
  4. data/bin/sub_zero +6 -0
  5. data/example/auditing/Gemfile +4 -0
  6. data/example/auditing/README.md +5 -0
  7. data/example/auditing/Rakefile +2 -0
  8. data/example/auditing/auditing.gemspec +25 -0
  9. data/example/auditing/config.yml +2 -0
  10. data/example/auditing/lib/auditing/handlers/logs.rb +30 -0
  11. data/example/auditing/lib/auditing/handlers/status.rb +29 -0
  12. data/example/auditing/lib/auditing/version.rb +3 -0
  13. data/example/auditing/lib/auditing.rb +21 -0
  14. data/example/auditing-client/run.rb +42 -0
  15. data/lib/sub_zero/cli/app.rb +7 -0
  16. data/lib/sub_zero/cli/new.rb +89 -0
  17. data/lib/sub_zero/cli/templates/ruby/client/client.tt +2 -0
  18. data/lib/sub_zero/cli/templates/ruby/service/Gemfile +8 -0
  19. data/lib/sub_zero/cli/templates/ruby/service/bin.tt +44 -0
  20. data/lib/sub_zero/cli/templates/ruby/service/handler.tt +1 -0
  21. data/lib/sub_zero/cli/templates/ruby/service/lib.tt +47 -0
  22. data/lib/sub_zero/cli/templates/ruby/service/rvmrc.tt +1 -0
  23. data/lib/sub_zero/cli/templates/ruby/service/serviceyml.tt +12 -0
  24. data/lib/sub_zero/cli/templates/ruby/service/verbs.tt +1 -0
  25. data/lib/sub_zero/cli/templates/ruby/service/version.tt +3 -0
  26. data/lib/sub_zero/cli.rb +6 -0
  27. data/lib/sub_zero/client/configuration.rb +12 -0
  28. data/lib/sub_zero/client/socket.rb +92 -0
  29. data/lib/sub_zero/client.rb +70 -0
  30. data/lib/sub_zero/main/common.rb +11 -0
  31. data/lib/sub_zero/main.rb +64 -0
  32. data/lib/sub_zero/version.rb +1 -1
  33. data/lib/sub_zero.rb +16 -2
  34. data/spec/spec_helper.rb +0 -0
  35. data/sub_zero.gemspec +10 -4
  36. data/thoughts.md +60 -0
  37. metadata +110 -6
  38. data/LICENSE.txt +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a5592345c5e4af640cd01b216b282ed95f8d7d5
4
- data.tar.gz: 84a3ad5d2d34919792a6273213391dc7172005bd
3
+ metadata.gz: 0c3d06f3806bd38f972069cccc381a5e14a10552
4
+ data.tar.gz: 201442b45283cc753950167905a088a450ec613a
5
5
  SHA512:
6
- metadata.gz: a3d8f3de9e64d9c380f8329c916663eec6230b13edf321a5a4a4d52be2d6d6ef0bb741e407885392973a696c08639874922fd317a9c401750d2b1d3bee1b58f4
7
- data.tar.gz: 8f1d4fec8c5f7994ee4671593096e3512518fc67107b3c583b5a6aa8328a0599ca4ae9436bf2ff6f662f944cfda6a045b153a3020bf89536535d0035cb00fcc7
6
+ metadata.gz: 59833793e76d2543ad4ed8948f852b7a8b13b0db67e44352cf55c4df36044b16669f84cd8a6e5df9e8134a7c20f36a245bbe760b7fd3c5a30696ebe61b56dacf
7
+ data.tar.gz: 2aee09d0ea9f147d2acf510203f0b71d7619876b8dbe5750d32f6153f1710ce0e6aad0cdfdd1d96013a96643928c36a11becfc4c5f7b02e61efc2ce1eed31b3c
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 ClubJudge B.V.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SubZero
2
2
 
3
- TODO: Write a gem description
3
+
4
4
 
5
5
  ## Installation
6
6
 
data/bin/sub_zero ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require_relative '../lib/sub_zero.rb'
5
+
6
+ SubZero::CLI::App.start
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sub_zero.gemspec
4
+ gemspec
@@ -0,0 +1,5 @@
1
+ # SubZero: Example App
2
+
3
+ An app can be created using:
4
+
5
+ subzero new appname
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'sub_zero/service/tasks'
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'auditing/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'auditing'
8
+ spec.version = Auditing::VERSION
9
+ spec.authors = ['Victor Rodrigues']
10
+ spec.email = ['victorc.rodrigues@gmail.com']
11
+ spec.description = %q{SubZero app example}
12
+ spec.summary = %q{SubZero app example}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'rake'
23
+
24
+ spec.add_dependency 'sub_zero'
25
+ end
@@ -0,0 +1,2 @@
1
+ broker:
2
+ uri: 'localhost:5560'
@@ -0,0 +1,30 @@
1
+ module Auditing
2
+ module Handlers
3
+ class Logs < SubZero::Service::Handler
4
+
5
+ def create
6
+ Log.create params
7
+ reply :ok
8
+ end
9
+
10
+ def index
11
+ reply_with Log.all
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+
18
+ __END__
19
+
20
+ #params is the message payload desserialized from messagepack
21
+
22
+ #request_id is accessible through here
23
+
24
+ #reply(verb, payload = nil)
25
+
26
+ #reply_with(content) => same verb
27
+ #reply_with(verb, content) => other verb
28
+ (both serialize content to msgpack)
29
+
30
+ #logger might be very useful
@@ -0,0 +1,29 @@
1
+ module Auditing
2
+ module Handlers
3
+ class Status < SubZero::Service::Handler
4
+
5
+ def show
6
+ reply :working
7
+ end
8
+
9
+ def count
10
+ reply_with Log.count
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+
17
+ __END__
18
+
19
+ #params is the message payload desserialized from messagepack
20
+
21
+ #request_id is accessible through here
22
+
23
+ #reply(verb, payload = nil)
24
+
25
+ #reply_with(content) => same verb
26
+ #reply_with(verb, content) => other verb
27
+ (both serialize content to msgpack)
28
+
29
+ #logger might be very useful
@@ -0,0 +1,3 @@
1
+ module Auditing
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+
3
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
4
+
5
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
6
+
7
+ module Auditing
8
+ extend SubZero::Service
9
+
10
+ sid :auditing
11
+
12
+ verbs log: 'logs#create',
13
+ retrieve: 'logs#index',
14
+ status: 'status#show',
15
+ 'status/count' => 'status#count'
16
+
17
+ end
18
+
19
+ __END__
20
+
21
+ verbs targets classes will try to be required / constantized from auditing/ or auditing/handlers as they are declared
@@ -0,0 +1,42 @@
1
+ require 'sub_zero'
2
+
3
+ Auditing = SubZero.client(:auditing)
4
+
5
+ # or
6
+
7
+ Auditing = SubZero.client :auditing do |c|
8
+ c.timeout = 5000
9
+ # what else? retry?
10
+ end
11
+
12
+ # fire and forget, just waits the Broker ACK to not care anymore, opens a thread
13
+ Auditing.log! author: 'Pedro Alvares Cabral', action: 'discovered Brazil.. heh.'
14
+
15
+ # waits for reply
16
+ ronconcon_logs = Auditing.index(author: 'Marques de Pombal')
17
+
18
+ # for more complex verbs, the base method call:
19
+
20
+ Auditing.call! 'bugs/report', error: 'error while trying to log'
21
+
22
+ Auditing.call 'stats/count'
23
+
24
+ Auditing.stats_count
25
+
26
+ # some sugar to sync call might be
27
+
28
+ Auditing['stats/count']
29
+
30
+
31
+ Auditing.stats! do |stats|
32
+ DeveloperChatRoom.push "Availabilty: #{stats[:availability]}"
33
+ end
34
+
35
+
36
+ # reply:
37
+
38
+ # ACK:NOK { error: { message: '', code: '', … } } (BROKER)
39
+ # STATS/COUNT:OK
40
+ # STATS/COUNT:NOK { error: { message: '', code: '', … }}
41
+ # retry strategy
42
+
@@ -0,0 +1,7 @@
1
+ module SubZero
2
+ module CLI
3
+ class App < Thor
4
+ register SubZero::CLI::New, 'new', 'new TYPE NAME', 'Creates a new TYPE (service/client) named NAME'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,89 @@
1
+ module SubZero
2
+ module CLI
3
+ class New < ::Thor
4
+ include ::Thor::Actions
5
+
6
+ attr_accessor :name
7
+
8
+ def self.source_root
9
+ File.dirname(__FILE__)
10
+ end
11
+
12
+ class_option :language, desc: 'language template to use', default: 'ruby', type: :string
13
+ class_option :test_framework, desc: 'test framework to use', default: 'rspec'
14
+ class_option :with_rvm, desc: 'include .rvmrc', default: true
15
+
16
+ desc 'service NAME', 'Creates a SubZero service'
17
+ def service name=nil
18
+ if name.nil?
19
+ say "You must supply a name!"
20
+ exit 1
21
+ end
22
+
23
+ say "Creating #{name} service..."
24
+ create_service name, options
25
+ end
26
+
27
+ desc 'client NAME', 'Creates a SubZero client'
28
+ def client name=nil
29
+ if name.nil?
30
+ say "You must supply a name!"
31
+ exit 1
32
+ end
33
+
34
+ say "Creating #{name} client..."
35
+ create_client name, options
36
+ end
37
+
38
+ #######
39
+ private
40
+ #######
41
+
42
+ def create_client name, options
43
+ self.name = name # ERB ... :/
44
+ template("templates/#{options[:language]}/client.tt", "#{name}/lib/#{name}.rb")
45
+
46
+ # TODO
47
+ end
48
+
49
+ def create_service name, options
50
+ # |-- Gemfile
51
+ # |-- bin
52
+ # | `-- name
53
+ # |-- config
54
+ # | |-- service.yml
55
+ # | `-- verbs.rb
56
+ # |-- lib
57
+ # | |-- handlers
58
+ # | | `-- handler.rb
59
+ # | `-- name.rb
60
+ # |-- rvmrc
61
+ # `-- spec
62
+ # `-- name_spec.rb
63
+
64
+ name = name.downcase
65
+ self.name = name # ERB ... :/
66
+ template("templates/#{options[:language]}/service/Gemfile", "#{name}/Gemfile")
67
+ template("templates/#{options[:language]}/service/bin.tt", "#{name}/bin/#{name}")
68
+ chmod("#{name}/bin/#{name}", 0755)
69
+ template("templates/#{options[:language]}/service/serviceyml.tt", "#{name}/config/service.yml")
70
+ template("templates/#{options[:language]}/service/verbs.tt", "#{name}/config/verbs.rb")
71
+ template("templates/#{options[:language]}/service/lib.tt", "#{name}/lib/#{name}.rb")
72
+ template("templates/#{options[:language]}/service/version.tt", "#{name}/lib/#{name}/version.rb")
73
+ template("templates/#{options[:language]}/service/handler.tt", "#{name}/lib/handlers/handler.rb")
74
+
75
+ test = options[:test_framework] == "rspec" ? :spec : :test
76
+ create_file "#{name}/#{test}/#{name}_#{test}.rb"
77
+
78
+ if options[:with_rvm]
79
+ template("templates/#{options[:language]}/service/rvmrc.tt", "#{name}/.rvmrc")
80
+ end
81
+
82
+ empty_directory "#{name}/doc"
83
+
84
+ say "all done! you can start a development server with bin/#{name} run"
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,2 @@
1
+ class <%= name.capitalize %>
2
+ end
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'daemons'
4
+ gem 'em-zeromq'
5
+ gem 'msgpack'
6
+
7
+ gem 'pry'
8
+ gem 'sub_zero', :path => '/Users/bruno/Code/1WORK/sub_zero'
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require 'rubygems' unless defined?(Gem)
5
+
6
+ require 'bundler/setup'
7
+ Bundler.require
8
+
9
+ require_relative '../lib/<%= name.downcase %>.rb'
10
+
11
+ service = SubZero::Main.boot ARGV
12
+
13
+ daemon_opts = {
14
+ multiple: false,
15
+ dir_mode: :normal,
16
+ dir: service.cli_args[:pid_path], # FIXME
17
+ log_output: true,
18
+ stop_proc: lambda { $stop_requested = true }
19
+ }
20
+
21
+ Daemons.run_proc '<%= name %>', daemon_opts do
22
+ daemon = <%= name.capitalize %>::Main.new service
23
+
24
+ start = Time.now
25
+ ping_at = start + 5
26
+
27
+ Signal.trap('INT') { daemon.do_exit_cleanup; exit }
28
+
29
+ loop do
30
+ daemon.poll_sockets
31
+
32
+ now = Time.now
33
+ if now >= ping_at
34
+ daemon.ping
35
+ ping_at = now + 15
36
+ end
37
+
38
+ break if $stop_requested
39
+
40
+ end
41
+
42
+ daemon.do_exit_cleanup
43
+ exit 0
44
+ end
@@ -0,0 +1,47 @@
1
+ require_relative "<%= name.capitalize %>/version"
2
+
3
+ module <%= name.capitalize %>
4
+ class Main
5
+ include SubZero::Common
6
+
7
+ def initialize service
8
+ @config = service.config
9
+ log "INITing socket"
10
+ end
11
+
12
+ def poll_sockets
13
+ print '.'
14
+ sleep 1
15
+ end
16
+
17
+ def ping
18
+ log "ping..."
19
+ end
20
+
21
+ #######
22
+ private
23
+ #######
24
+
25
+ def send_announce_packet
26
+ $sent = Time.now
27
+ @socket.send_string "SRV", ZMQ::SNDMORE
28
+ @socket.send_string 0.to_s, ZMQ::SNDMORE
29
+ @socket.send_string "UP", ZMQ::SNDMORE
30
+
31
+ payload = { id: @config['service']['id'], sid: @config['service']['sid'] }.to_msgpack
32
+ @socket.send_string payload
33
+ end
34
+
35
+ def init_socket
36
+ @context = ZMQ::Context.new
37
+
38
+ @socket = @context.socket ZMQ::DEALER
39
+ @socket.identity = @config['service']['id']
40
+ @socket.connect "tcp://#{@config['service']['broker_host']}:#{@config['service']['broker_port']}"
41
+
42
+ @poller = ZMQ::Poller.new
43
+ @poller.register @socket, ZMQ::POLLIN
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1 @@
1
+ rvm use 2.0@<%= name.capitalize %> --create
@@ -0,0 +1,12 @@
1
+ defaults: &defaults
2
+ service:
3
+ broker_host: "local.clubjudge.com"
4
+ broker_port: 7777
5
+ sid: "new_service"
6
+ id: "<%= ::SecureRandom.hex(10) %>"
7
+
8
+ development:
9
+ <<: *defaults
10
+
11
+ test:
12
+ <<: *defaults
@@ -0,0 +1,3 @@
1
+ module <%= name.capitalize %>
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ module SubZero
2
+ module CLI
3
+ autoload :App, 'sub_zero/cli/app'
4
+ autoload :New, 'sub_zero/cli/new'
5
+ end
6
+ end
@@ -0,0 +1,12 @@
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
@@ -0,0 +1,92 @@
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
+ zeromq_context do |context|
16
+ zeromq_socket context do |socket|
17
+ rid = SecureRandom.uuid
18
+ zeromq_send socket, "REQ:#{sid}", rid, verb, payload.to_msgpack, options.to_msgpack
19
+ result = zeromq_result(socket, rid, verb)
20
+ end
21
+ end
22
+
23
+ result
24
+ end
25
+
26
+ def zeromq_context
27
+ context = ZMQ::Context.create(1)
28
+ fail SocketError, 'failed to create context' unless context
29
+ yield context
30
+ ensure
31
+ zcc!(context.terminate) if context
32
+ end
33
+
34
+ def zeromq_socket context
35
+ socket = context.socket ZMQ::DEALER
36
+ socket.identity = SecureRandom.hex(10)
37
+ zcc! socket.connect("tcp://#{config[:ip]}:#{config[:port]}")
38
+ yield socket
39
+ ensure
40
+ zcc! socket.close
41
+ end
42
+
43
+ def zeromq_send socket, *msgs
44
+ last = msgs.pop
45
+ msgs.each { |m| zcc! socket.send_string m, ZMQ::SNDMORE }
46
+ zcc! socket.send_string last
47
+ end
48
+
49
+ def zeromq_check_code! result_code
50
+ return if ZMQ::Util.resultcode_ok? result_code
51
+
52
+ fail SocketError, "operation failed, errno [#{ZMQ::Util.errno}], " +
53
+ "description [#{ZMQ::Util.error_string}]"
54
+ end
55
+
56
+ alias :zcc! :zeromq_check_code!
57
+
58
+ def zeromq_result socket, rid, verb
59
+ result = []
60
+ zcc! socket.recv_strings(result)
61
+
62
+ zeromq_validate_result! rid, verb, result
63
+
64
+ routing_info = MessagePack.unpack(result.pop)
65
+ payload = MessagePack.unpack(result.pop)
66
+ rep_verb = result.pop
67
+ status = rep_verb.end_with?('NOK') ? :error : :ok
68
+
69
+ [status, payload]
70
+ end
71
+
72
+ def zeromq_validate_result! rid, verb, result
73
+ type, rep_rid, rep_verb, payload = result
74
+
75
+ common = "result: #{result}"
76
+
77
+ unless type == "REP:#{sid}" || type == 'BRO'
78
+ fail SocketError, "unexpected result type: #{type}. " + common
79
+ end
80
+
81
+ unless rid == rep_rid
82
+ fail SocketError, "rid mismatch. sent: #{rid}, received: #{rep_id}. " + common
83
+ end
84
+
85
+ unless rep_verb == "#{verb}:OK" || rep_verb == "#{verb}:NOK"
86
+ fail SocketError, "reply verb mismatch: #{rep_verb}. " + common
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,70 @@
1
+ require 'active_support/string_inquirer'
2
+
3
+ module SubZero
4
+ class Client
5
+ autoload :Configuration, 'sub_zero/client/configuration'
6
+ autoload :Socket, 'sub_zero/client/socket'
7
+
8
+ include Socket
9
+
10
+ attr_reader :sid, :config
11
+
12
+ def initialize sid
13
+ @sid, @config = sid.to_s.upcase, Configuration.default
14
+ yield @config if block_given?
15
+ end
16
+
17
+ def call verb, payload = {}, options = {}
18
+ sz_verb = verb.to_s.upcase.gsub('_', '/')
19
+ status, result = zeromq_fetch(sz_verb, payload, options)
20
+ result = handle_result(status, result)
21
+ block_given? ? yield(result) : result
22
+ end
23
+
24
+ def call! verb, payload = {}, options = {}, &block
25
+ call verb, payload, options, &block
26
+ end
27
+
28
+ def [] verb
29
+ call verb
30
+ end
31
+
32
+ def method_missing method, payload = {}, options = {}, &block
33
+ if method.to_s.end_with? '!'
34
+ call! method.delete('!'), payload, options, &block
35
+ else
36
+ call method, payload, options, &block
37
+ end
38
+ end
39
+
40
+ def handle_result status, result
41
+ case status
42
+ when :ok
43
+ result
44
+ when :error
45
+ fail Error.new(result['error'])
46
+ end
47
+ end
48
+
49
+ class Error < ::StandardError
50
+
51
+ attr_reader :result
52
+
53
+ def initialize result
54
+ super result['message']
55
+ set_backtrace caller
56
+ @result = result
57
+ end
58
+
59
+ def code
60
+ result['code']
61
+ end
62
+
63
+ def status
64
+ ActiveSupport::StringInquirer.new self.code.to_s.downcase
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ module SubZero
2
+ module Common
3
+ def log msg, level='DEBUG'
4
+ puts "#{level}: #{msg}"
5
+ end
6
+
7
+ def env
8
+ ENV['SUBZERO_ENV'] || 'development'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,64 @@
1
+ require_relative 'main/common'
2
+
3
+ module SubZero
4
+ module Main
5
+ include Common
6
+ extend self
7
+
8
+ attr_accessor :config, :cli_args
9
+
10
+ def boot cli_args
11
+ log "booting..."
12
+
13
+ log "\tloading service.yml"
14
+ @config = load_config
15
+ log "\tparsing CLI args"
16
+ @cli_args = parse_cli_args cli_args
17
+
18
+ self
19
+ end
20
+
21
+ #######
22
+ private
23
+ #######
24
+
25
+
26
+ def usage(s)
27
+ $stderr.puts "<%= name %> v#{SubZero::VERSION}" # change to const for the service!
28
+ $stderr.puts s
29
+ $stderr.puts "Usage: #{File.basename($0)}: [-p port] [-l log_path] [-pp pid_path]"
30
+ exit(1)
31
+ end
32
+
33
+ def parse_cli_args args
34
+ opts = {}
35
+
36
+ port = @config['service']['broker_port']
37
+ pid_path = log_path = File.join( File.dirname(__FILE__), '..')
38
+
39
+ loop { case ARGV[0]
40
+ when '-p' then ARGV.shift; port = ARGV.shift
41
+ when '-l' then ARGV.shift; log_path = ARGV.shift
42
+ when '-pp' then ARGV.shift; pid_path = ARGV.shift
43
+ when /^-/ then usage("Unknown option: #{ARGV[0].inspect}")
44
+ else break
45
+ end; }
46
+
47
+ opts[:port] = port
48
+ opts[:log_path] = log_path
49
+ opts[:pid_path] = pid_path
50
+
51
+ opts
52
+ end
53
+
54
+ def load_config
55
+ begin
56
+ YAML.load_file('config/service.yml')[env]
57
+ rescue => ex
58
+ log "could not load config file! (#{ex.message})", 'ERROR'
59
+ exit 1
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -1,3 +1,3 @@
1
1
  module SubZero
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/sub_zero.rb CHANGED
@@ -1,5 +1,19 @@
1
- require "sub_zero/version"
1
+ require 'yaml'
2
+ require 'securerandom'
3
+
4
+ require 'thor'
5
+ require 'thor/group'
6
+
7
+ require_relative 'sub_zero/version'
8
+ require_relative 'sub_zero/main'
2
9
 
3
10
  module SubZero
4
- # Your code goes here...
11
+ autoload :CLI, 'sub_zero/cli'
12
+ autoload :Client, 'sub_zero/client'
13
+ extend self
14
+
15
+ def client service_id
16
+ block_given? ? Client.new(service_id, &block) : Client.new(service_id)
17
+ end
18
+
5
19
  end
File without changes
data/sub_zero.gemspec CHANGED
@@ -6,8 +6,8 @@ require 'sub_zero/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "sub_zero"
8
8
  spec.version = SubZero::VERSION
9
- spec.authors = ["Victor Rodrigues"]
10
- spec.email = ["victorc.rodrigues@gmail.com"]
9
+ spec.authors = ["Victor Rodrigues", "Bruno Antunes"]
10
+ spec.email = ["victorc.rodrigues@gmail.com", "sardaukar.siet@gmail.com"]
11
11
  spec.description = %q{ZeroMQ SOA solution}
12
12
  spec.summary = %q{ZeroMQ GREAT SOA solution}
13
13
  spec.homepage = ""
@@ -18,6 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec'
24
+
25
+ spec.add_dependency 'thor'
26
+ spec.add_dependency 'msgpack'
27
+ spec.add_dependency 'ffi-rzmq'
28
+ spec.add_dependency 'activesupport'
23
29
  end
data/thoughts.md ADDED
@@ -0,0 +1,60 @@
1
+ SubZero is meant to be a way for us to dab into polyglot architectures.
2
+
3
+ SubZero itself is made up of 3 parts:
4
+
5
+ Broker
6
+ ======
7
+
8
+ The traffic cop of the scheme. The Broker mediates requests between Services and Clients. Clients and Services cannot talk directly. Responsabilities:
9
+
10
+ - route messages between components
11
+ - know of active instances of certain Services
12
+ - have a TTL scheme to guess when components are down
13
+ - manage retries
14
+
15
+ Services
16
+ ========
17
+
18
+ Services exchange messages with clients. When a service boots up, it must register with the Broker before accepting work.
19
+
20
+ Clients
21
+ =======
22
+
23
+ Cients send requests to the Broker for specific Service IDs (but not instances of Services).
24
+
25
+ Messages
26
+ --------
27
+
28
+ There are two types of messages: Broker to Client( or Service) and Client (or Service) to Broker. Since the Broker has a DEALER socket, all of its outgoing messages are prefixed with an ID.
29
+
30
+ Typical envelope:
31
+
32
+ <pre>
33
+ ID - string matching the ZMQ identity of a socket (only for outgoing messages from the Broker)
34
+ RID - UUID that is preserved on all messages pertaining to this request
35
+ TYPE and optionally SUBTYPE after ':' - examples:
36
+ BRO (when Broker replies to PINGs from services)
37
+ SRV (when Service boots up and announces itself)
38
+ CLI:SID (Client asking for a Service reply)
39
+ REQ:ID (Broker forwarding Client request to Service)
40
+ SRV:ID (Service replying to Broker about client request)
41
+ REP:SID (Broker forwards Service reply to Clent)
42
+ VERB - can be PING, PONG, UP, ACK, SORT, TAG, etc. Victor suggested subverbs and I agree or else we'll have huge verb handlers on all Services
43
+ PAYLOAD - a MessagePack serialized hash
44
+ </pre>
45
+
46
+
47
+ Intended flow for Service authoring
48
+ ===================================
49
+
50
+ 1. sub_zero new service X
51
+ 2. cd X
52
+ 3. edit config.yml to set broker options (URI, port, etc.)
53
+ 4. add routes to verbs.rb
54
+ 5. create class with handlers (subclass of SubZero::Handler ?)
55
+ 6. when production-ready, run cap deploy to install it on /services (or whatever) in PRD
56
+ 7. call /etc/init.d/sub_zero start X in PRD to start service
57
+
58
+ Variations:
59
+ - sub_zero new service X --lang=scala ? To use different file templates?
60
+
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sub_zero
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Rodrigues
8
+ - Bruno Antunes
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-07-17 00:00:00.000000000 Z
12
+ date: 2013-08-26 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bundler
@@ -38,21 +39,123 @@ dependencies:
38
39
  - - '>='
39
40
  - !ruby/object:Gem::Version
40
41
  version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: thor
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: msgpack
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: ffi-rzmq
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: activesupport
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
41
112
  description: ZeroMQ SOA solution
42
113
  email:
43
114
  - victorc.rodrigues@gmail.com
44
- executables: []
115
+ - sardaukar.siet@gmail.com
116
+ executables:
117
+ - sub_zero
45
118
  extensions: []
46
119
  extra_rdoc_files: []
47
120
  files:
48
121
  - .gitignore
49
122
  - Gemfile
50
- - LICENSE.txt
123
+ - LICENSE
51
124
  - README.md
52
125
  - Rakefile
126
+ - bin/sub_zero
127
+ - example/auditing-client/run.rb
128
+ - example/auditing/Gemfile
129
+ - example/auditing/README.md
130
+ - example/auditing/Rakefile
131
+ - example/auditing/auditing.gemspec
132
+ - example/auditing/config.yml
133
+ - example/auditing/lib/auditing.rb
134
+ - example/auditing/lib/auditing/handlers/logs.rb
135
+ - example/auditing/lib/auditing/handlers/status.rb
136
+ - example/auditing/lib/auditing/version.rb
53
137
  - lib/sub_zero.rb
138
+ - lib/sub_zero/cli.rb
139
+ - lib/sub_zero/cli/app.rb
140
+ - lib/sub_zero/cli/new.rb
141
+ - lib/sub_zero/cli/templates/ruby/client/client.tt
142
+ - lib/sub_zero/cli/templates/ruby/service/Gemfile
143
+ - lib/sub_zero/cli/templates/ruby/service/bin.tt
144
+ - lib/sub_zero/cli/templates/ruby/service/handler.tt
145
+ - lib/sub_zero/cli/templates/ruby/service/lib.tt
146
+ - lib/sub_zero/cli/templates/ruby/service/rvmrc.tt
147
+ - lib/sub_zero/cli/templates/ruby/service/serviceyml.tt
148
+ - lib/sub_zero/cli/templates/ruby/service/verbs.tt
149
+ - lib/sub_zero/cli/templates/ruby/service/version.tt
150
+ - lib/sub_zero/client.rb
151
+ - lib/sub_zero/client/configuration.rb
152
+ - lib/sub_zero/client/socket.rb
153
+ - lib/sub_zero/main.rb
154
+ - lib/sub_zero/main/common.rb
54
155
  - lib/sub_zero/version.rb
156
+ - spec/spec_helper.rb
55
157
  - sub_zero.gemspec
158
+ - thoughts.md
56
159
  homepage: ''
57
160
  licenses:
58
161
  - MIT
@@ -73,8 +176,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
176
  version: '0'
74
177
  requirements: []
75
178
  rubyforge_project:
76
- rubygems_version: 2.0.3
179
+ rubygems_version: 2.0.7
77
180
  signing_key:
78
181
  specification_version: 4
79
182
  summary: ZeroMQ GREAT SOA solution
80
- test_files: []
183
+ test_files:
184
+ - spec/spec_helper.rb
data/LICENSE.txt DELETED
@@ -1,22 +0,0 @@
1
- Copyright (c) 2013 Victor Rodrigues
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.