zoomq 0.1.1 → 0.2.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.
- data/Gemfile +2 -0
- data/lib/zoomq/cli.rb +1 -1
- data/lib/zoomq/client/connection.rb +18 -0
- data/lib/zoomq/client.rb +32 -20
- data/lib/zoomq/console.rb +34 -0
- data/lib/zoomq/server/{request_handler.rb → connection.rb} +10 -11
- data/lib/zoomq/server/worker.rb +14 -16
- data/lib/zoomq/server.rb +14 -11
- data/lib/zoomq/socket.rb +43 -0
- data/lib/zoomq/zookeeper.rb +2 -2
- data/templates/client.rb.tt +4 -10
- data/templates/console.rb.tt +4 -23
- data/templates/ping_request.rb.tt +5 -3
- data/templates/protocol.proto.tt +1 -1
- data/templates/server.rb.tt +2 -12
- data/zoomq.gemspec +2 -1
- metadata +22 -5
- data/lib/zoomq/handler.rb +0 -13
- data/lib/zoomq/jeromq-0.3.0-20130721.175323-20.jar +0 -0
data/Gemfile
CHANGED
data/lib/zoomq/cli.rb
CHANGED
@@ -73,7 +73,7 @@ module ZooMQ
|
|
73
73
|
"lib/#{name}/client.rb" => "client.rb",
|
74
74
|
"lib/#{name}/console.rb" => "console.rb",
|
75
75
|
"#{name}/server.rb" => "server.rb",
|
76
|
-
"#{name}/
|
76
|
+
"#{name}/protocol/ping_request.rb" => "ping_request.rb",
|
77
77
|
}.each do |dest, source|
|
78
78
|
puts " * #{dest}"
|
79
79
|
source = File.join(@root, 'templates', "#{source}.tt")
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ZooMQ
|
2
|
+
class Client
|
3
|
+
class Connection < ZMachine::Connection
|
4
|
+
|
5
|
+
attr_accessor :client
|
6
|
+
|
7
|
+
def receive_data(msg)
|
8
|
+
msg.unwrap # strip origin
|
9
|
+
# TODO: unwrap data to string from bytes to_i wtf
|
10
|
+
request_id = String.from_java_bytes(msg.unwrap.data).to_i
|
11
|
+
cls = String.from_java_bytes(msg.pop.data).constantize
|
12
|
+
obj = cls.parse(String.from_java_bytes(msg.pop.data))
|
13
|
+
@client.response(request_id, obj)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/zoomq/client.rb
CHANGED
@@ -1,25 +1,28 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
java_import org.zeromq.ZMQ
|
5
|
-
java_import org.zeromq.ZContext
|
6
|
-
java_import org.zeromq.ZMsg
|
7
|
-
java_import org.zeromq.ZFrame
|
3
|
+
require 'zmachine'
|
8
4
|
|
9
5
|
require 'zoomq/zookeeper'
|
6
|
+
require 'zoomq/client/connection'
|
7
|
+
|
8
|
+
java_import org.zeromq.ZFrame
|
9
|
+
java_import java.util.concurrent.atomic.AtomicInteger
|
10
10
|
|
11
11
|
module ZooMQ
|
12
|
-
class
|
12
|
+
class ServerUnavailableError < StandardError; end
|
13
|
+
class TimeoutError < StandardError; end
|
13
14
|
|
14
15
|
class Client
|
15
16
|
|
16
17
|
attr_reader :servers
|
17
18
|
|
18
|
-
def initialize
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
19
|
+
def initialize
|
20
|
+
@requests = {}
|
21
|
+
@request_id = AtomicInteger.new
|
22
|
+
@zk = Zookeeper.new(service_name)
|
23
|
+
@channel = ZMachine.connect(nil, ZMQ::ROUTER, Connection) do |connection|
|
24
|
+
connection.client = self
|
25
|
+
end
|
23
26
|
watch
|
24
27
|
refresh
|
25
28
|
end
|
@@ -31,27 +34,36 @@ module ZooMQ
|
|
31
34
|
def refresh
|
32
35
|
@servers = @zk.servers
|
33
36
|
@servers.each do |server|
|
34
|
-
|
37
|
+
$log.debug("#{service_name}:connect", server: server)
|
38
|
+
@channel.connect("tcp://#{server}")
|
35
39
|
sleep(0.1)
|
36
40
|
end
|
37
41
|
@cycle = @servers.cycle
|
38
42
|
end
|
39
43
|
|
40
|
-
def
|
44
|
+
def request(obj)
|
41
45
|
if @servers.empty?
|
42
|
-
raise
|
46
|
+
raise ServerUnavailableError.new("no servers are online, please try again later")
|
43
47
|
end
|
44
48
|
|
45
49
|
server = @cycle.next
|
46
50
|
|
47
|
-
|
51
|
+
deferred = ZMachine::DefaultDeferrable.new
|
52
|
+
deferred.callback { |result| yield result } if block_given?
|
53
|
+
|
54
|
+
request_id = @request_id.increment_and_get
|
55
|
+
msg = ZMsg.new_string_msg(obj.class.to_s, obj.to_s)
|
56
|
+
msg.wrap(ZFrame.new(request_id.to_s))
|
48
57
|
msg.wrap(ZFrame.new(server))
|
49
|
-
|
58
|
+
$log.debug("#{service_name}:request", id: request_id, obj: obj.inspect)
|
59
|
+
@channel.send_data(msg)
|
60
|
+
|
61
|
+
@requests[request_id] = deferred
|
62
|
+
end
|
50
63
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
cls.parse(String.from_java_bytes(msg.pop.data))
|
64
|
+
def response(request_id, obj)
|
65
|
+
$log.debug("#{service_name}:response", id: request_id, obj: obj.inspect)
|
66
|
+
@requests[request_id].succeed(obj)
|
55
67
|
end
|
56
68
|
|
57
69
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'ap'
|
2
|
+
require 'irb'
|
3
|
+
require 'ripl'
|
4
|
+
|
5
|
+
Ripl::Shell.class_eval do
|
6
|
+
def format_result(result)
|
7
|
+
ap(result)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ZooMQ
|
12
|
+
class Console
|
13
|
+
def initialize
|
14
|
+
$log.level = :info
|
15
|
+
Thread.new { zmachine }
|
16
|
+
Ripl.start(binding: binding)
|
17
|
+
end
|
18
|
+
|
19
|
+
def zmachine
|
20
|
+
ZMachine.run { client }
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(name, *args, &block)
|
24
|
+
result = nil
|
25
|
+
df = @client.send(name, *args, &block)
|
26
|
+
df.callback { |response| result = response }
|
27
|
+
df.errback { |error| result = error }
|
28
|
+
while result.nil?
|
29
|
+
sleep(0.1)
|
30
|
+
end
|
31
|
+
result
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,24 +1,23 @@
|
|
1
1
|
java_import org.zeromq.ZMsg
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'zmachine/connection'
|
4
4
|
|
5
5
|
module ZooMQ
|
6
6
|
class Server
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
class Connection < ZMachine::Connection
|
8
|
+
|
9
|
+
attr_accessor :server
|
10
|
+
|
11
|
+
def receive_data(msg)
|
12
|
+
origin = msg.unwrap
|
13
|
+
request_id = msg.unwrap
|
11
14
|
result = handle_msg(msg)
|
15
|
+
result.wrap(request_id)
|
12
16
|
result.wrap(origin)
|
13
|
-
result
|
17
|
+
send_data(result)
|
14
18
|
return 0
|
15
19
|
end
|
16
20
|
|
17
|
-
def recv_msg(socket)
|
18
|
-
msg = ZMsg.recvMsg(socket)
|
19
|
-
[msg.unwrap, msg]
|
20
|
-
end
|
21
|
-
|
22
21
|
def handle_msg(msg)
|
23
22
|
cls = String.from_java_bytes(msg.pop.data).constantize
|
24
23
|
request = cls.parse(String.from_java_bytes(msg.pop.data))
|
data/lib/zoomq/server/worker.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
java_import org.zeromq.ZMQ
|
2
|
-
java_import org.zeromq.ZContext
|
3
|
-
java_import org.zeromq.ZLoop
|
4
2
|
|
5
|
-
require '
|
3
|
+
require 'zmachine'
|
4
|
+
require 'zoomq/server/connection'
|
6
5
|
|
7
6
|
module ZooMQ
|
8
7
|
class Server
|
@@ -12,23 +11,22 @@ module ZooMQ
|
|
12
11
|
|
13
12
|
def initialize(server)
|
14
13
|
@server = server
|
15
|
-
@zloop = ZLoop.new
|
16
|
-
@zloop.verbose(true)
|
17
|
-
initialize_socket
|
18
14
|
end
|
19
15
|
|
20
|
-
def
|
21
|
-
|
22
|
-
@port = @socket.bind("tcp://*:*")
|
23
|
-
RequestHandler.new(@socket).register(@zloop, self)
|
24
|
-
Thread.current.name = "#{@server.fqdn}:#{@port}"
|
25
|
-
@socket.identity = Thread.current[:name].to_java_bytes
|
16
|
+
def run
|
17
|
+
ZMachine.run { initialize_socket }
|
26
18
|
end
|
27
19
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
20
|
+
def initialize_socket
|
21
|
+
$log.info("zoomq:server:worker", bind: "tcp://*:*")
|
22
|
+
ZMachine.start_server("tcp://*:*", ZMQ::ROUTER, Connection) do |handler|
|
23
|
+
identity = "#{@server.fqdn}:#{handler.channel.port}"
|
24
|
+
$log.info("zoomq:server:worker", announce: identity)
|
25
|
+
Thread.current.name = "ZMQ::Server::Worker (#{identity})"
|
26
|
+
handler.channel.identity = identity
|
27
|
+
handler.server = @server
|
28
|
+
@server.announce(identity)
|
29
|
+
end
|
32
30
|
end
|
33
31
|
|
34
32
|
end
|
data/lib/zoomq/server.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'zoomq/jeromq-0.3.0-20130721.175323-20.jar'
|
4
|
-
java_import org.zeromq.ZMQ
|
5
|
-
|
6
3
|
require 'forwardable'
|
4
|
+
require 'socket'
|
5
|
+
require 'zmachine'
|
7
6
|
|
8
7
|
require 'zoomq/zookeeper'
|
9
8
|
require 'zoomq/server/worker'
|
@@ -13,25 +12,29 @@ module ZooMQ
|
|
13
12
|
|
14
13
|
extend Forwardable
|
15
14
|
def_delegators :@zk, :globals, :locals, :announce
|
16
|
-
def_delegators :@ctx, :create_socket
|
17
15
|
|
18
|
-
attr_reader :
|
16
|
+
attr_reader :fqdn, :port
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
$log.info("#{service_name}:initialize #{RUBY_DESCRIPTION}")
|
20
|
+
$log.info("#{service_name}:initialize", {
|
21
|
+
env: Env.mode,
|
22
|
+
})
|
19
23
|
|
20
|
-
def initialize(service_name, zookeeper_uri, log)
|
21
24
|
Signal.register_shutdown_handler { shutdown }
|
22
|
-
@
|
23
|
-
@zk = Zookeeper.new(
|
24
|
-
@ctx = ZContext.new
|
25
|
-
@fqdn = Socket.gethostbyname(Socket.gethostname).first
|
25
|
+
@fqdn = ::Socket.gethostbyname(::Socket.gethostname).first
|
26
|
+
@zk = Zookeeper.new(service_name)
|
26
27
|
end
|
27
28
|
|
28
29
|
def run
|
30
|
+
# TODO: make it multi-threaded
|
31
|
+
$log.info("#{service_name}:run", workers: 1)
|
29
32
|
Worker.new(self).run
|
30
33
|
end
|
31
34
|
|
32
35
|
def shutdown
|
33
|
-
@ctx.destroy if @ctx
|
34
36
|
@zk.close if @zk
|
37
|
+
ZMachine.stop_event_loop
|
35
38
|
end
|
36
39
|
|
37
40
|
end
|
data/lib/zoomq/socket.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
java_import org.zeromq.ZMQ
|
2
|
+
|
3
|
+
require 'zmachine/connection'
|
4
|
+
|
5
|
+
module ZooMQ
|
6
|
+
class Socket < ZMachine::Connection
|
7
|
+
READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ, ZMQ::PAIR ]
|
8
|
+
WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ, ZMQ::PAIR ]
|
9
|
+
|
10
|
+
def initialize(socket, socket_type, server)
|
11
|
+
@socket, @socket_type, @server = socket, socket_type, server
|
12
|
+
self.notify_readable = true if READABLES.include?(socket_type)
|
13
|
+
#self.notify_writable = true if WRITABLES.include?(socket_type)
|
14
|
+
end
|
15
|
+
|
16
|
+
def notify_readable
|
17
|
+
# Not sure if this is actually necessary. I suppose it prevents us
|
18
|
+
# from having to to instantiate a ZMQ::Message unnecessarily.
|
19
|
+
# I'm leaving this in because its in the docs, but it could probably
|
20
|
+
# be taken out.
|
21
|
+
return unless readable?
|
22
|
+
handle_readable
|
23
|
+
end
|
24
|
+
|
25
|
+
#def notify_writable
|
26
|
+
# return unless writable?
|
27
|
+
|
28
|
+
# # once a writable event is successfully received the socket
|
29
|
+
# # should be accepting messages again so stop triggering
|
30
|
+
# # write events
|
31
|
+
# self.notify_writable = false
|
32
|
+
# handle_writable
|
33
|
+
#end
|
34
|
+
|
35
|
+
def readable?
|
36
|
+
(@socket.events & ZMQ::Poller::POLLIN) == ZMQ::Poller::POLLIN
|
37
|
+
end
|
38
|
+
|
39
|
+
def writable?
|
40
|
+
(@socket.events & ZMQ::Poller::POLLOUT) == ZMQ::Poller::POLLOUT
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/zoomq/zookeeper.rb
CHANGED
@@ -7,8 +7,8 @@ module ZooMQ
|
|
7
7
|
attr_reader :globals
|
8
8
|
attr_reader :locals
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@zk = ZK.new(
|
10
|
+
def initialize(service_name)
|
11
|
+
@zk = ZK.new("#{$conf.zookeeper}/#{service_name}")
|
12
12
|
@zk.mkdir_p("/alive")
|
13
13
|
@globals = KeySpace.new(:global, @zk)
|
14
14
|
end
|
data/templates/client.rb.tt
CHANGED
@@ -1,24 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'forwardable'
|
4
3
|
require 'zoomq/client'
|
5
4
|
|
6
5
|
require '<%=config[:name]%>/protocol'
|
7
6
|
|
8
7
|
module <%=config[:constant_name]%>
|
9
|
-
class Client
|
8
|
+
class Client < ZooMQ::Client
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(zookeeper, log)
|
14
|
-
@client = ZooMQ::Client.new(<%=config[:name].inspect%>, zookeeper, log)
|
10
|
+
def service_name
|
11
|
+
<%=config[:name].inspect%>
|
15
12
|
end
|
16
13
|
|
17
|
-
def_delegators :@client, :servers
|
18
|
-
|
19
14
|
def ping
|
20
|
-
request
|
21
|
-
@client.handle(request)
|
15
|
+
request(PingRequest.new)
|
22
16
|
end
|
23
17
|
|
24
18
|
end
|
data/templates/console.rb.tt
CHANGED
@@ -1,29 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require 'irb'
|
3
|
-
require 'ripl'
|
4
|
-
require 'forwardable'
|
5
|
-
|
1
|
+
require 'zoomq/console'
|
6
2
|
require '<%=config[:name]%>/client'
|
7
3
|
|
8
|
-
Ripl::Shell.class_eval do
|
9
|
-
def format_result(result)
|
10
|
-
ap(result)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
4
|
module <%=config[:constant_name]%>
|
15
|
-
class Console
|
16
|
-
|
17
|
-
|
18
|
-
def initialize
|
19
|
-
$log.level = :info
|
20
|
-
@client = Client.new($conf.zookeeper, $log)
|
21
|
-
Ripl.start(binding: binding)
|
22
|
-
end
|
23
|
-
|
24
|
-
def method_missing(name, *args, &block)
|
25
|
-
@client.__send__(name, *args, &block)
|
5
|
+
class Console < ZooMQ::Console
|
6
|
+
def client
|
7
|
+
@client = Client.new
|
26
8
|
end
|
27
|
-
|
28
9
|
end
|
29
10
|
end
|
data/templates/protocol.proto.tt
CHANGED
data/templates/server.rb.tt
CHANGED
@@ -9,18 +9,8 @@ end
|
|
9
9
|
module <%=config[:constant_name]%>
|
10
10
|
class Server
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
$log.info("<%=config[:name]%>:initialize", {
|
15
|
-
env: Env.mode,
|
16
|
-
})
|
17
|
-
|
18
|
-
@server = ZooMQ::Server.new(<%=config[:name].inspect%>, $conf.zookeeper, $log)
|
19
|
-
end
|
20
|
-
|
21
|
-
def run
|
22
|
-
$log.info("<%=config[:name]%>:run")
|
23
|
-
@server.run
|
12
|
+
def service_name
|
13
|
+
<%=config[:name].inspect%>
|
24
14
|
end
|
25
15
|
|
26
16
|
end
|
data/zoomq.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "zoomq"
|
5
|
-
spec.version = "0.
|
5
|
+
spec.version = "0.2.0"
|
6
6
|
spec.authors = ["madvertise Mobile Advertising GmbH"]
|
7
7
|
spec.email = ["tech@madvertise.com"]
|
8
8
|
spec.description = %q{ØMQ ROUTER/ROUTER coordinated by Zookeeper}
|
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_dependency "multi_json"
|
22
22
|
spec.add_dependency "ruby-protocol-buffers"
|
23
23
|
spec.add_dependency "zk"
|
24
|
+
spec.add_dependency "zmachine"
|
24
25
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zoomq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: erubis
|
@@ -107,6 +107,22 @@ dependencies:
|
|
107
107
|
none: false
|
108
108
|
prerelease: false
|
109
109
|
type: :runtime
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: zmachine
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
none: false
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
none: false
|
124
|
+
prerelease: false
|
125
|
+
type: :runtime
|
110
126
|
description: ØMQ ROUTER/ROUTER coordinated by Zookeeper
|
111
127
|
email:
|
112
128
|
- tech@madvertise.com
|
@@ -123,11 +139,12 @@ files:
|
|
123
139
|
- bin/zoomq
|
124
140
|
- lib/zoomq/cli.rb
|
125
141
|
- lib/zoomq/client.rb
|
126
|
-
- lib/zoomq/
|
127
|
-
- lib/zoomq/
|
142
|
+
- lib/zoomq/client/connection.rb
|
143
|
+
- lib/zoomq/console.rb
|
128
144
|
- lib/zoomq/server.rb
|
129
|
-
- lib/zoomq/server/
|
145
|
+
- lib/zoomq/server/connection.rb
|
130
146
|
- lib/zoomq/server/worker.rb
|
147
|
+
- lib/zoomq/socket.rb
|
131
148
|
- lib/zoomq/zookeeper.rb
|
132
149
|
- templates/Gemfile.tt
|
133
150
|
- templates/LICENSE.txt.tt
|
data/lib/zoomq/handler.rb
DELETED
Binary file
|