arbiter 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []