arbiter 1.0.0

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.
@@ -0,0 +1,25 @@
1
+ class Arbiter
2
+ def self.perform(message, metadata)
3
+ message = message.to_sym
4
+ if @message_table[message] and ! @message_table[message].empty?
5
+ @message_table[message].each do |listener|
6
+ listener.notify(message, metadata)
7
+ end
8
+ end
9
+ end
10
+
11
+ def self.set_listeners(listeners)
12
+ @message_table = {}
13
+ listeners.each do |listener|
14
+ listener.subscribe_to.each do |channel|
15
+ @message_table[channel] ||= []
16
+ @message_table[channel] << listener
17
+ end
18
+ end
19
+ end
20
+
21
+ def self.publish(message, metadata)
22
+ self.perform(message, metadata)
23
+ end
24
+ end
25
+
@@ -0,0 +1,9 @@
1
+ class Eventer
2
+
3
+ class << self; attr_accessor :bus end
4
+
5
+ def self.post(message, *args)
6
+ bus.publish(message, args) if bus
7
+ end
8
+
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'resque'
2
+ require 'arbiter'
3
+
4
+ class ResqueArbiter < Arbiter
5
+ @queue = :arbiter
6
+
7
+ def self.publish(message, metadata)
8
+ Resque.enqueue(ResqueArbiter, message, metadata)
9
+ end
10
+ end
@@ -0,0 +1,26 @@
1
+ require 'ffi-rzmq'
2
+
3
+ module Zeromq
4
+ class Proxy
5
+ def initialize(frontend, backend)
6
+ @frontend = frontend
7
+ @backend = backend
8
+ end
9
+
10
+ def execute
11
+ context = ZMQ::Context.new
12
+
13
+ frontend = context.socket(ZMQ::PULL)
14
+ bound = frontend.bind(@frontend)
15
+
16
+ raise 'Error starting frontend!' unless bound == 0
17
+
18
+ backend = context.socket(ZMQ::PUSH)
19
+ bound = backend.bind(@backend)
20
+
21
+ raise 'Error starting backend!' unless bound == 0
22
+
23
+ ZMQ::Device.new(ZMQ::QUEUE,frontend,backend)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,97 @@
1
+ require 'arbiter'
2
+ require 'ffi-rzmq'
3
+ require 'multi_json'
4
+
5
+ class ZeromqArbiter < Arbiter
6
+
7
+ class << self
8
+ attr_accessor :frontend, :logger
9
+ end
10
+
11
+ def self.publish(message, metadata)
12
+ context = ZMQ::Context.new
13
+
14
+ outbound = context.socket(ZMQ::PUSH)
15
+ outbound.connect(frontend)
16
+
17
+ outbound.send_string(
18
+ MultiJson.dump(
19
+ :message => message,
20
+ :metadata => metadata
21
+ )
22
+ )
23
+
24
+ outbound.close
25
+ end
26
+
27
+ def listen(proxy)
28
+ raise 'Must provide proxy location!' unless proxy
29
+
30
+ ctx = ZMQ::Context.new
31
+ socket = ctx.socket(ZMQ::PULL)
32
+ rc = socket.connect(proxy)
33
+
34
+ raise "Could not connect to #{proxy}!" unless rc == 0
35
+
36
+ log :info, "Connected to #{proxy}"
37
+
38
+ while true
39
+ msg = ''
40
+ rc = socket.recv_string(msg)
41
+
42
+ if error_check(rc)
43
+ break
44
+ else
45
+ process_message(msg)
46
+ end
47
+ end
48
+
49
+ socket.close
50
+ end
51
+
52
+ protected
53
+
54
+ def log(type, msg)
55
+ if self.class.logger
56
+ self.class.logger.send(type, msg)
57
+ end
58
+ end
59
+
60
+ def process_message(message)
61
+ message = MultiJson.decode(message)
62
+ log :info, "Processing: #{message}"
63
+
64
+ begin
65
+ self.class.perform(message['message'].to_sym, symbolize_nested_keys(message['metadata']))
66
+ rescue Exception => e
67
+ log :error, e
68
+ end
69
+ end
70
+
71
+ def error_check(rc)
72
+ if ZMQ::Util.resultcode_ok?(rc)
73
+ false
74
+ else
75
+ log :error, "Operation failed, errno [#{ZMQ::Util.errno}] description [#{ZMQ::Util.error_string}]"
76
+ caller(1).each { |callstack| log :error, callstack }
77
+ true
78
+ end
79
+ end
80
+
81
+ def symbolize_nested_keys(data)
82
+ case data
83
+ when Hash
84
+ data.map {|k, v|
85
+ {k.to_sym => symbolize_nested_keys(v)}
86
+ }.inject({}) { |coll, symbol_key_hash|
87
+ coll.merge(symbol_key_hash)
88
+ }
89
+ when Array
90
+ data.collect { |a|
91
+ symbolize_nested_keys(a)
92
+ }
93
+ else
94
+ data
95
+ end
96
+ end
97
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arbiter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sitter City
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-09 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email:
16
+ - dev@sittercity.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/arbiter.rb
22
+ - lib/eventer.rb
23
+ - lib/resque_arbiter.rb
24
+ - lib/zeromq/proxy.rb
25
+ - lib/zeromq_arbiter.rb
26
+ homepage: http://sittercity.com
27
+ licenses: []
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ - spec
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 1.8.24
48
+ signing_key:
49
+ specification_version: 3
50
+ summary: A simple eventing framework
51
+ test_files: []