em-zeromq 0.1.2 → 0.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +14 -0
- data/Gemfile +5 -0
- data/README.md +33 -20
- data/Rakefile +5 -18
- data/em-zeromq.gemspec +21 -28
- data/example/simple.rb +26 -12
- data/lib/em-zeromq.rb +0 -6
- data/lib/em-zeromq/connection.rb +111 -31
- data/lib/em-zeromq/context.rb +73 -0
- data/lib/em-zeromq/version.rb +4 -0
- data/spec/context_spec.rb +25 -0
- data/spec/pub_sub_spec.rb +7 -24
- data/spec/push_pull_spec.rb +3 -21
- data/spec/spec_helper.rb +2 -1
- data/spec/xreq_xrep_spec.rb +15 -25
- metadata +76 -34
- data/.Rakefile.swo +0 -0
- data/bin/em-zeromq +0 -7
- data/lib/em-zeromq/.connection.rb.swp +0 -0
- data/lib/em-zeromq/.zeromq.rb.swp +0 -0
- data/lib/em-zeromq/zeromq.rb +0 -20
- data/spec/.spec_helper.rb.swp +0 -0
- data/spec/.xreq_xrep_spec.rb.swp +0 -0
- data/test/test_em-zeromq.rb +0 -0
- data/version.txt +0 -1
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Low level event machine support for ZeroMQ
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
WARNING THIS IS ALPHA QUALITY AT THE MOMENT
|
5
|
+
FOR NOW BUILD EVENTMACHINE FROM HEAD OR YOU WILL FIND A PAINFUL BUG
|
8
6
|
|
9
|
-
|
10
|
-
It needs work for sure, for instance, you cannot remove a socket yet
|
7
|
+
## Description: ##
|
11
8
|
|
9
|
+
This seems to work fine, no memory leaks, and it runs fast.
|
10
|
+
It may not be perfect though, and the API is extremely minimal, just the bare minumum
|
11
|
+
to make ZeroMQ work with EventMachine.
|
12
12
|
|
13
13
|
## Using: ##
|
14
14
|
|
15
|
-
You must use either rubinius, jruby, or 1.9.x
|
15
|
+
You must use either rubinius, jruby, or 1.9.x. 1.8.7 does not work with libzmq.
|
16
16
|
|
17
17
|
If you use 1.9.x, be sure to install the ffi gem first.
|
18
18
|
|
@@ -23,10 +23,9 @@ Build+Install ZeroMQ 2.1 from HEAD ( https://github.com/zeromq/zeromq2 )
|
|
23
23
|
|
24
24
|
Run the specs, see specs for examples
|
25
25
|
|
26
|
-
Want to help out? Ask!
|
26
|
+
Want to help out? Ask!
|
27
27
|
|
28
28
|
## Example ##
|
29
|
-
|
30
29
|
require 'rubygems'
|
31
30
|
require 'em-zeromq'
|
32
31
|
|
@@ -40,25 +39,39 @@ Want to help out? Ask! Much work to be done here
|
|
40
39
|
end
|
41
40
|
end
|
42
41
|
end
|
43
|
-
|
44
|
-
def on_writable(socket)
|
45
|
-
end
|
46
|
-
end
|
42
|
+
|
47
43
|
EM.run do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
ctx = EM::ZeroMQ::Context.new(1)
|
45
|
+
|
46
|
+
# setup push sockets
|
47
|
+
push_socket1 = ctx.bind( ZMQ::PUSH, 'tcp://127.0.0.1:2091')
|
48
|
+
push_socket2 = ctx.bind( ZMQ::PUSH, 'ipc:///tmp/a')
|
49
|
+
push_socket3 = ctx.bind( ZMQ::PUSH, 'inproc://simple_test')
|
50
|
+
|
51
|
+
# setup one pull sockets listening to both push sockets
|
52
|
+
pull_socket = ctx.connect( ZMQ::PULL, 'tcp://127.0.0.1:2091', EMTestPullHandler.new)
|
53
|
+
pull_socket.connect('ipc:///tmp/a')
|
54
|
+
pull_socket.connect('inproc://simple_test')
|
55
|
+
|
56
|
+
n = 0
|
57
|
+
|
58
|
+
# push_socket.hwm = 40
|
59
|
+
# puts push_socket.hwm
|
60
|
+
# puts pull_socket.hwm
|
61
|
+
|
62
|
+
EM::PeriodicTimer.new(0.1) do
|
63
|
+
puts '.'
|
64
|
+
push_socket1.send_msg("t#{n += 1}_")
|
65
|
+
push_socket2.send_msg("i#{n += 1}_")
|
66
|
+
push_socket3.send_msg("p#{n += 1}_")
|
67
|
+
end
|
55
68
|
end
|
56
69
|
|
57
70
|
## License: ##
|
58
71
|
|
59
72
|
(The MIT License)
|
60
73
|
|
61
|
-
Copyright (c)
|
74
|
+
Copyright (c) 2011
|
62
75
|
|
63
76
|
Permission is hereby granted, free of charge, to any person obtaining
|
64
77
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -1,20 +1,7 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
1
3
|
|
2
|
-
|
3
|
-
|
4
|
-
rescue LoadError
|
5
|
-
abort '### Please install the "bones" gem ###'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
6
6
|
end
|
7
|
-
|
8
|
-
#task :default => 'test:run'
|
9
|
-
task 'gem:release' => 'test:run'
|
10
|
-
|
11
|
-
#depend_on 'ffi-rzmq', '0.7.0'
|
12
|
-
#depend_on 'eventmachine'
|
13
|
-
|
14
|
-
Bones {
|
15
|
-
name 'em-zeromq'
|
16
|
-
authors 'Andrew Cholakian'
|
17
|
-
email 'andrew@andrewvc.com'
|
18
|
-
url 'https://github.com/andrewvc/em-zeromq'
|
19
|
-
}
|
20
|
-
|
7
|
+
task :default => :spec
|
data/em-zeromq.gemspec
CHANGED
@@ -1,36 +1,29 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "em-zeromq/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
4
|
-
s.name
|
5
|
-
s.version
|
6
|
-
|
7
|
-
s.
|
8
|
-
s.
|
9
|
-
s.
|
10
|
-
s.
|
6
|
+
s.name = "em-zeromq"
|
7
|
+
s.version = EmZeromq::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Andrew Cholakian"]
|
10
|
+
s.email = ["andrew@andrewvc.com"]
|
11
|
+
s.homepage = "https://github.com/andrewvc/em-zeromq"
|
12
|
+
s.summary = %q{Low level event machine support for ZeroMQ}
|
11
13
|
s.description = %q{Low level event machine support for ZeroMQ}
|
12
|
-
s.email = %q{andrew@andrewvc.com}
|
13
|
-
s.executables = ["em-zeromq"]
|
14
|
-
s.extra_rdoc_files = ["History.txt", "bin/em-zeromq", "lib/em-zeromq/.connection.rb.swp", "version.txt"]
|
15
|
-
s.files = [".Rakefile.swo", ".bnsignore", "History.txt", "README.md", "Rakefile", "bin/em-zeromq", "example/simple.rb", "lib/em-zeromq.rb", "lib/em-zeromq/.connection.rb.swp", "lib/em-zeromq/connection.rb", "lib/em-zeromq/zeromq.rb", "spec/.pub_sub_spec.rb.swp", "spec/pub_sub_spec.rb", "spec/push_pull_spec.rb", "spec/spec_helper.rb", "test/test_em-zeromq.rb", "version.txt"]
|
16
|
-
s.homepage = %q{https://github.com/andrewvc/em-zeromq}
|
17
14
|
s.rdoc_options = ["--main", "README.md"]
|
18
|
-
s.require_paths = ["lib"]
|
19
|
-
s.rubyforge_project = %q{em-zeromq}
|
20
|
-
s.rubygems_version = %q{1.3.7}
|
21
|
-
s.summary = %q{Low level event machine support for ZeroMQ}
|
22
|
-
s.test_files = ["test/test_em-zeromq.rb"]
|
23
15
|
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
s.rubyforge_project = "em-zeromq"
|
17
|
+
|
18
|
+
s.add_dependency 'eventmachine', '>= 0.12.11'
|
19
|
+
s.add_dependency 'ffi-rzmq', '>= 0.7.2'
|
20
|
+
s.add_dependency 'ffi' if RUBY_PLATFORM != "java" &&
|
21
|
+
defined?(RUBY_ENGINE) && RUBY_ENGINE != 'rbx'
|
22
|
+
s.add_development_dependency 'rspec', '>= 2.5.0'
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
else
|
34
|
-
s.add_dependency(%q<bones>, [">= 3.5.4"])
|
35
|
-
end
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
|
+
s.require_paths = ["lib"]
|
36
28
|
end
|
29
|
+
|
data/example/simple.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
$LOAD_PATH << File.expand_path('../../lib', __FILE__)
|
2
3
|
require 'em-zeromq'
|
3
4
|
|
4
5
|
Thread.abort_on_exception = true
|
@@ -11,17 +12,30 @@ class EMTestPullHandler
|
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
14
|
-
|
15
|
-
def on_writable(socket)
|
16
|
-
end
|
17
|
-
end
|
15
|
+
|
18
16
|
EM.run do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
ctx = EM::ZeroMQ::Context.new(1)
|
18
|
+
|
19
|
+
# setup push sockets
|
20
|
+
push_socket1 = ctx.bind( ZMQ::PUSH, 'tcp://127.0.0.1:2091')
|
21
|
+
push_socket2 = ctx.bind( ZMQ::PUSH, 'ipc:///tmp/a')
|
22
|
+
push_socket3 = ctx.bind( ZMQ::PUSH, 'inproc://simple_test')
|
23
|
+
|
24
|
+
# setup one pull sockets listening to both push sockets
|
25
|
+
pull_socket = ctx.connect( ZMQ::PULL, 'tcp://127.0.0.1:2091', EMTestPullHandler.new)
|
26
|
+
pull_socket.connect('ipc:///tmp/a')
|
27
|
+
pull_socket.connect('inproc://simple_test')
|
28
|
+
|
29
|
+
n = 0
|
30
|
+
|
31
|
+
# push_socket.hwm = 40
|
32
|
+
# puts push_socket.hwm
|
33
|
+
# puts pull_socket.hwm
|
34
|
+
|
35
|
+
EM::PeriodicTimer.new(0.1) do
|
36
|
+
puts '.'
|
37
|
+
push_socket1.send_msg("t#{n += 1}_")
|
38
|
+
push_socket2.send_msg("i#{n += 1}_")
|
39
|
+
push_socket3.send_msg("p#{n += 1}_")
|
40
|
+
end
|
26
41
|
end
|
27
|
-
|
data/lib/em-zeromq.rb
CHANGED
@@ -8,12 +8,6 @@ module EmZeromq
|
|
8
8
|
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
9
9
|
# :startdoc:
|
10
10
|
|
11
|
-
# Returns the version string for the library.
|
12
|
-
#
|
13
|
-
def self.version
|
14
|
-
@version ||= File.read(path('version.txt')).strip
|
15
|
-
end
|
16
|
-
|
17
11
|
# Returns the library path for the module. If any arguments are given,
|
18
12
|
# they will be joined to the end of the libray path using
|
19
13
|
# <tt>File.join</tt>.
|
data/lib/em-zeromq/connection.rb
CHANGED
@@ -10,13 +10,109 @@ module EventMachine
|
|
10
10
|
@handler = handler
|
11
11
|
@address = address
|
12
12
|
end
|
13
|
+
|
14
|
+
def self.map_sockopt(opt, name)
|
15
|
+
define_method(name){ @socket.getsockopt(opt) }
|
16
|
+
define_method("#{name}="){|val| @socket.setsockopt(opt, val) }
|
17
|
+
end
|
18
|
+
|
19
|
+
map_sockopt(ZMQ::HWM, :hwm)
|
20
|
+
map_sockopt(ZMQ::SWAP, :swap)
|
21
|
+
map_sockopt(ZMQ::IDENTITY, :identity)
|
22
|
+
map_sockopt(ZMQ::AFFINITY, :affinity)
|
23
|
+
map_sockopt(ZMQ::SNDBUF, :sndbuf)
|
24
|
+
map_sockopt(ZMQ::RCVBUF, :rcvbuf)
|
25
|
+
|
26
|
+
# pgm
|
27
|
+
map_sockopt(ZMQ::RATE, :rate)
|
28
|
+
map_sockopt(ZMQ::RECOVERY_IVL, :recovery_ivl)
|
29
|
+
map_sockopt(ZMQ::MCAST_LOOP, :mcast_loop)
|
30
|
+
|
31
|
+
# User method
|
32
|
+
def bind(address)
|
33
|
+
@socket.bind(address)
|
34
|
+
end
|
35
|
+
|
36
|
+
def connect(address)
|
37
|
+
@socket.connect(address)
|
38
|
+
end
|
39
|
+
|
40
|
+
def subscribe(what = '')
|
41
|
+
raise "only valid on sub socket type (was #{@socket.name})" unless @socket.name == 'SUB'
|
42
|
+
@socket.setsockopt(ZMQ::SUBSCRIBE, what)
|
43
|
+
end
|
44
|
+
|
45
|
+
def unsubscribe(what)
|
46
|
+
raise "only valid on sub socket type (was #{@socket.name})" unless @socket.name == 'SUB'
|
47
|
+
@socket.setsockopt(ZMQ::UNSUBSCRIBE, what)
|
48
|
+
end
|
49
|
+
|
50
|
+
# send a non blocking message
|
51
|
+
# parts: if only one argument is given a signle part message is sent
|
52
|
+
# if more than one arguments is given a multipart message is sent
|
53
|
+
#
|
54
|
+
# return: true is message was queued, false otherwise
|
55
|
+
#
|
56
|
+
def send_msg(*parts)
|
57
|
+
parts = Array(parts[0]) if parts.size == 0
|
58
|
+
sent = true
|
59
|
+
|
60
|
+
# multipart
|
61
|
+
parts[0...-1].each do |msg|
|
62
|
+
sent = @socket.send_string(msg, ZMQ::NOBLOCK | ZMQ::SNDMORE)
|
63
|
+
if sent == false
|
64
|
+
break
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if sent
|
69
|
+
# all the previous parts were queued, send
|
70
|
+
# the last one
|
71
|
+
@socket.send_string(parts[-1], ZMQ::NOBLOCK)
|
72
|
+
true
|
73
|
+
else
|
74
|
+
# error while sending the previous parts
|
75
|
+
# register the socket for writability
|
76
|
+
self.notify_writable = true
|
77
|
+
false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def setsockopt(opt, value)
|
82
|
+
@socket.setsockopt(opt, value)
|
83
|
+
end
|
84
|
+
|
85
|
+
# cleanup when ending loop
|
86
|
+
def unbind
|
87
|
+
detach_and_close
|
88
|
+
end
|
89
|
+
|
90
|
+
# Make this socket available for reads
|
91
|
+
def register_readable
|
92
|
+
# Since ZMQ is event triggered I think this is necessary
|
93
|
+
if readable?
|
94
|
+
notify_readable
|
95
|
+
end
|
96
|
+
# Subscribe to EM read notifications
|
97
|
+
self.notify_readable = true
|
98
|
+
end
|
13
99
|
|
100
|
+
# Trigger on_readable when socket is readable
|
101
|
+
def register_writable
|
102
|
+
# Subscribe to EM write notifications
|
103
|
+
self.notify_writable = true
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
# internal methods
|
14
108
|
def readable?
|
15
109
|
(@socket.getsockopt(ZMQ::EVENTS) & ZMQ::POLLIN) == ZMQ::POLLIN
|
16
110
|
end
|
17
111
|
|
18
112
|
def writable?
|
19
|
-
|
113
|
+
return true
|
114
|
+
# ZMQ::EVENTS has issues in ZMQ HEAD, we'll ignore this till they're fixed
|
115
|
+
# (@socket.getsockopt(ZMQ::EVENTS) & ZMQ::POLLOUT) == ZMQ::POLLOUT
|
20
116
|
end
|
21
117
|
|
22
118
|
def notify_readable
|
@@ -40,46 +136,30 @@ module EventMachine
|
|
40
136
|
end
|
41
137
|
end
|
42
138
|
|
43
|
-
@handler.on_readable(
|
139
|
+
@handler.on_readable(self, msg_parts)
|
44
140
|
else
|
45
141
|
break
|
46
142
|
end
|
47
143
|
end
|
48
144
|
end
|
49
145
|
|
50
|
-
def get_message
|
51
|
-
msg = ZMQ::Message.new
|
52
|
-
msg_recvd = @socket.recv(msg, ZMQ::NOBLOCK)
|
53
|
-
msg_recvd ? msg : nil
|
54
|
-
end
|
55
|
-
|
56
146
|
def notify_writable
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
# Stop triggering on_writable when socket is writable
|
63
|
-
def deregister_writable
|
147
|
+
return unless writable?
|
148
|
+
|
149
|
+
# one a writable event is successfully received the socket
|
150
|
+
# should be accepting messages again so stop triggering
|
151
|
+
# write events
|
64
152
|
self.notify_writable = false
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
def register_readable
|
69
|
-
# Since ZMQ is event triggered I think this is necessary
|
70
|
-
if (@socket.getsockopt(ZMQ::EVENTS) & ZMQ::POLLIN) == ZMQ::POLLIN
|
71
|
-
notify_readable
|
153
|
+
|
154
|
+
if @handler.respond_to?(:on_writable)
|
155
|
+
@handler.on_writable(self)
|
72
156
|
end
|
73
|
-
self.notify_readable = true
|
74
157
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
notify_writable
|
81
|
-
end
|
82
|
-
self.notify_writable = true
|
158
|
+
|
159
|
+
def get_message
|
160
|
+
msg = ZMQ::Message.new
|
161
|
+
msg_recvd = @socket.recv(msg, ZMQ::NOBLOCK)
|
162
|
+
msg_recvd ? msg : nil
|
83
163
|
end
|
84
164
|
|
85
165
|
# Detaches the socket from the EM loop,
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# different ways to create a socket:
|
3
|
+
# ctx.bind(:xreq, 'tcp://127.0.0.1:6666')
|
4
|
+
# ctx.bind('xreq', 'tcp://127.0.0.1:6666')
|
5
|
+
# ctx.bind(ZMQ::XREQ, 'tcp://127.0.0.1:6666')
|
6
|
+
#
|
7
|
+
module EventMachine
|
8
|
+
module ZeroMQ
|
9
|
+
class Context
|
10
|
+
READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::XREQ, ZMQ::XREP, ZMQ::REP, ZMQ::REQ ]
|
11
|
+
WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::XREQ, ZMQ::XREP, ZMQ::REP, ZMQ::REQ ]
|
12
|
+
|
13
|
+
def initialize(threads_or_context)
|
14
|
+
if threads_or_context.is_a?(ZMQ::Context)
|
15
|
+
@context = threads_or_context
|
16
|
+
else
|
17
|
+
@context = ZMQ::Context.new(threads_or_context)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def bind(socket_type, address, handler = nil, opts = {})
|
22
|
+
create(socket_type, :bind, address, handler, opts)
|
23
|
+
end
|
24
|
+
|
25
|
+
def connect(socket_type, address, handler = nil, opts = {})
|
26
|
+
create(socket_type, :connect, address, handler, opts)
|
27
|
+
end
|
28
|
+
|
29
|
+
def create(socket_type, bind_or_connect, address, handler, opts = {})
|
30
|
+
socket_type = find_type(socket_type)
|
31
|
+
socket = @context.socket(socket_type)
|
32
|
+
|
33
|
+
ident = opts.delete(:identity)
|
34
|
+
if ident
|
35
|
+
socket.setsockopt(ZMQ::IDENTITY, ident)
|
36
|
+
end
|
37
|
+
|
38
|
+
unless opts.empty?
|
39
|
+
raise "unknown keys: #{opts.keys.join(', ')}"
|
40
|
+
end
|
41
|
+
|
42
|
+
if bind_or_connect == :bind
|
43
|
+
socket.bind(address)
|
44
|
+
else
|
45
|
+
socket.connect(address)
|
46
|
+
end
|
47
|
+
|
48
|
+
conn = EM.watch(socket.getsockopt(ZMQ::FD), EventMachine::ZeroMQ::Connection, socket, socket_type, address, handler)
|
49
|
+
|
50
|
+
if READABLES.include?(socket_type)
|
51
|
+
conn.register_readable
|
52
|
+
end
|
53
|
+
|
54
|
+
if WRITABLES.include?(socket_type)
|
55
|
+
conn.register_writable
|
56
|
+
end
|
57
|
+
|
58
|
+
conn
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def find_type(type)
|
63
|
+
if type.is_a?(Symbol) or type.is_a?(String)
|
64
|
+
ZMQ.const_get(type.to_s.upcase)
|
65
|
+
else
|
66
|
+
type
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[spec_helper])
|
2
|
+
|
3
|
+
describe 'Context' do
|
4
|
+
before do
|
5
|
+
@ctx = EM::ZeroMQ::Context.new(1)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'can be created with a context' do
|
9
|
+
zmq_ctx = ZMQ::Context.new(1)
|
10
|
+
ctx = EM::ZeroMQ::Context.new( zmq_ctx )
|
11
|
+
ctx.instance_variable_get('@context').should == zmq_ctx
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'can create socket' do
|
15
|
+
EM::run do
|
16
|
+
s1 = @ctx.bind(:xreq, 'tcp://127.0.0.1:5555')
|
17
|
+
s2 = @ctx.bind('xreq', 'tcp://127.0.0.1:5556')
|
18
|
+
s3 = @ctx.bind(ZMQ::XREQ, 'tcp://127.0.0.1:5557')
|
19
|
+
|
20
|
+
s1.instance_variable_get('@socket').name.should == 'XREQ'
|
21
|
+
EM::stop_event_loop
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/spec/pub_sub_spec.rb
CHANGED
@@ -10,30 +10,11 @@ describe EventMachine::ZeroMQ do
|
|
10
10
|
@received += messages
|
11
11
|
end
|
12
12
|
end
|
13
|
-
class EMTestPubHandler
|
14
|
-
def initialize(&block)
|
15
|
-
@on_writable_callback = block
|
16
|
-
end
|
17
|
-
def on_writable(socket)
|
18
|
-
@on_writable_callback.call(socket) if @on_writable_callback
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def make_sub(addr, b_or_c, handler=EMTestSubHandler.new)
|
23
|
-
conn = EM::ZeroMQ.create SPEC_CTX, ZMQ::SUB, b_or_c, addr, handler
|
24
|
-
conn.socket.setsockopt(ZMQ::SUBSCRIBE,'')
|
25
|
-
conn.register_readable
|
26
|
-
conn
|
27
|
-
end
|
28
|
-
|
29
|
-
def make_pub(addr, b_or_c, handler=EMTestPubHandler.new)
|
30
|
-
EM::ZeroMQ.create SPEC_CTX, ZMQ::PUB, b_or_c, addr, handler
|
31
|
-
end
|
32
13
|
|
33
14
|
it "Should instantiate a connection given valid opts" do
|
34
15
|
sub_conn = nil
|
35
|
-
run_reactor(
|
36
|
-
sub_conn =
|
16
|
+
run_reactor(1) do
|
17
|
+
sub_conn = SPEC_CTX.bind(ZMQ::PUB, rand_addr, EMTestSubHandler.new)
|
37
18
|
end
|
38
19
|
sub_conn.should be_a(EventMachine::ZeroMQ::Connection)
|
39
20
|
end
|
@@ -45,8 +26,10 @@ describe EventMachine::ZeroMQ do
|
|
45
26
|
|
46
27
|
run_reactor(0.5) do
|
47
28
|
results[:sub_hndlr] = pull_hndlr = EMTestSubHandler.new
|
48
|
-
sub_conn =
|
49
|
-
|
29
|
+
sub_conn = SPEC_CTX.bind(ZMQ::SUB, rand_addr, pull_hndlr)
|
30
|
+
sub_conn.subscribe('')
|
31
|
+
|
32
|
+
pub_conn = SPEC_CTX.connect(ZMQ::PUB, sub_conn.address, EMTestSubHandler.new)
|
50
33
|
|
51
34
|
pub_conn.socket.send_string test_message, ZMQ::NOBLOCK
|
52
35
|
|
@@ -55,7 +38,7 @@ describe EventMachine::ZeroMQ do
|
|
55
38
|
|
56
39
|
@results = results
|
57
40
|
end
|
58
|
-
|
41
|
+
|
59
42
|
it "should run completely" do
|
60
43
|
@results[:specs_ran].should be_true
|
61
44
|
end
|
data/spec/push_pull_spec.rb
CHANGED
@@ -10,29 +10,11 @@ describe EventMachine::ZeroMQ do
|
|
10
10
|
@received += messages
|
11
11
|
end
|
12
12
|
end
|
13
|
-
class EMTestPushHandler
|
14
|
-
def initialize(&block)
|
15
|
-
@on_writable_callback = block
|
16
|
-
end
|
17
|
-
def on_writable(socket)
|
18
|
-
@on_writable_callback.call(socket) if @on_writable_callback
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def make_pull(addr, b_or_c, handler=EMTestPullHandler.new)
|
23
|
-
conn = EM::ZeroMQ.create SPEC_CTX, ZMQ::PULL, b_or_c, addr, handler
|
24
|
-
conn.register_readable
|
25
|
-
conn
|
26
|
-
end
|
27
|
-
|
28
|
-
def make_push(addr, b_or_c, handler=EMTestPushHandler.new)
|
29
|
-
conn = EM::ZeroMQ.create SPEC_CTX, ZMQ::PUSH, b_or_c, addr, handler
|
30
|
-
end
|
31
13
|
|
32
14
|
it "Should instantiate a connection given valid opts" do
|
33
15
|
pull_conn = nil
|
34
16
|
run_reactor do
|
35
|
-
pull_conn =
|
17
|
+
pull_conn = SPEC_CTX.bind(ZMQ::PULL, rand_addr, EMTestPullHandler.new)
|
36
18
|
end
|
37
19
|
pull_conn.should be_a(EventMachine::ZeroMQ::Connection)
|
38
20
|
end
|
@@ -44,8 +26,8 @@ describe EventMachine::ZeroMQ do
|
|
44
26
|
|
45
27
|
run_reactor(0.5) do
|
46
28
|
results[:pull_hndlr] = pull_hndlr = EMTestPullHandler.new
|
47
|
-
pull_conn
|
48
|
-
push_conn =
|
29
|
+
pull_conn = SPEC_CTX.bind(ZMQ::PULL, rand_addr, pull_hndlr)
|
30
|
+
push_conn = SPEC_CTX.connect(ZMQ::PUSH, pull_conn.address)
|
49
31
|
|
50
32
|
push_conn.socket.send_string test_message, ZMQ::NOBLOCK
|
51
33
|
|
data/spec/spec_helper.rb
CHANGED
data/spec/xreq_xrep_spec.rb
CHANGED
@@ -10,6 +10,7 @@ describe EventMachine::ZeroMQ do
|
|
10
10
|
@received += messages
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
13
14
|
class EMTestXREPHandler
|
14
15
|
attr_reader :received
|
15
16
|
def initialize(&block)
|
@@ -21,29 +22,17 @@ describe EventMachine::ZeroMQ do
|
|
21
22
|
end
|
22
23
|
def on_readable(socket, messages)
|
23
24
|
ident, delim, message = messages.map(&:copy_out_string)
|
25
|
+
ident.should == "req1"
|
24
26
|
@received += [ident, delim, message].map {|s| ZMQ::Message.new(s)}
|
25
|
-
|
26
|
-
socket.
|
27
|
-
socket.send_string message
|
27
|
+
|
28
|
+
socket.send_msg(ident, delim, "re:#{message}")
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
|
-
def make_xreq(addr, b_or_c, handler=EMTestXREQHandler.new)
|
32
|
-
conn = EM::ZeroMQ.create SPEC_CTX, ZMQ::XREQ, b_or_c, addr, handler
|
33
|
-
conn.register_readable
|
34
|
-
conn
|
35
|
-
end
|
36
|
-
|
37
|
-
def make_xrep(addr, b_or_c, handler=EMTestXREPHandler.new)
|
38
|
-
conn = EM::ZeroMQ.create SPEC_CTX, ZMQ::XREP, b_or_c, addr, handler
|
39
|
-
conn.register_readable
|
40
|
-
conn
|
41
|
-
end
|
42
|
-
|
43
32
|
it "Should instantiate a connection given valid opts" do
|
44
33
|
xreq_conn = nil
|
45
34
|
run_reactor(1) do
|
46
|
-
xreq_conn =
|
35
|
+
xreq_conn = SPEC_CTX.bind(ZMQ::XREQ, rand_addr, EMTestXREQHandler.new)
|
47
36
|
end
|
48
37
|
xreq_conn.should be_a(EventMachine::ZeroMQ::Connection)
|
49
38
|
end
|
@@ -51,18 +40,19 @@ describe EventMachine::ZeroMQ do
|
|
51
40
|
describe "sending/receiving a single message via Xreq/Xrep" do
|
52
41
|
before(:all) do
|
53
42
|
results = {}
|
54
|
-
@test_message = test_message = "
|
43
|
+
@test_message = test_message = "M#{rand(999)}"
|
55
44
|
|
56
|
-
run_reactor(
|
45
|
+
run_reactor(0.5) do
|
57
46
|
results[:xrep_hndlr] = xrep_hndlr = EMTestXREPHandler.new
|
58
47
|
results[:xreq_hndlr] = xreq_hndlr = EMTestXREQHandler.new
|
59
|
-
xreq_conn
|
60
|
-
|
61
|
-
|
62
|
-
xreq_conn.
|
63
|
-
xreq_conn.socket.send_string test_message
|
48
|
+
xreq_conn = SPEC_CTX.connect(ZMQ::XREQ, rand_addr, xreq_hndlr, :identity => "req1")
|
49
|
+
xreq_conn.send_msg('', test_message)
|
50
|
+
|
51
|
+
xrep_conn = SPEC_CTX.bind(ZMQ::XREP, xreq_conn.address, xrep_hndlr, :identity => "rep1")
|
64
52
|
|
65
|
-
EM::Timer.new(0.1)
|
53
|
+
EM::Timer.new(0.1) do
|
54
|
+
results[:specs_ran] = true
|
55
|
+
end
|
66
56
|
end
|
67
57
|
|
68
58
|
@results = results
|
@@ -81,7 +71,7 @@ describe EventMachine::ZeroMQ do
|
|
81
71
|
it "the xreq should be echoed its original message" do
|
82
72
|
@results[:xreq_hndlr].received.should_not be_empty
|
83
73
|
@results[:xreq_hndlr].received.last.should be_a(ZMQ::Message)
|
84
|
-
@results[:xreq_hndlr].received.last.copy_out_string.should == @test_message
|
74
|
+
@results[:xreq_hndlr].received.last.copy_out_string.should == "re:#{@test_message}"
|
85
75
|
end
|
86
76
|
end
|
87
77
|
end
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-zeromq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: -1848230051
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 1
|
9
8
|
- 2
|
10
|
-
|
9
|
+
- 0
|
10
|
+
- beta1
|
11
|
+
version: 0.2.0.beta1
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- Andrew Cholakian
|
@@ -15,59 +16,98 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2011-02-
|
19
|
+
date: 2011-02-28 00:00:00 -08:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
23
|
+
name: eventmachine
|
23
24
|
prerelease: false
|
24
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 57
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
- 12
|
34
|
+
- 11
|
35
|
+
version: 0.12.11
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: ffi-rzmq
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 7
|
47
|
+
segments:
|
48
|
+
- 0
|
49
|
+
- 7
|
50
|
+
- 2
|
51
|
+
version: 0.7.2
|
52
|
+
type: :runtime
|
53
|
+
version_requirements: *id002
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: ffi
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
type: :runtime
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rspec
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
25
72
|
none: false
|
26
73
|
requirements:
|
27
74
|
- - ">="
|
28
75
|
- !ruby/object:Gem::Version
|
29
76
|
hash: 27
|
30
77
|
segments:
|
31
|
-
-
|
78
|
+
- 2
|
32
79
|
- 5
|
33
|
-
-
|
34
|
-
version:
|
80
|
+
- 0
|
81
|
+
version: 2.5.0
|
35
82
|
type: :development
|
36
|
-
version_requirements: *
|
83
|
+
version_requirements: *id004
|
37
84
|
description: Low level event machine support for ZeroMQ
|
38
|
-
email:
|
39
|
-
|
40
|
-
|
85
|
+
email:
|
86
|
+
- andrew@andrewvc.com
|
87
|
+
executables: []
|
88
|
+
|
41
89
|
extensions: []
|
42
90
|
|
43
|
-
extra_rdoc_files:
|
44
|
-
|
45
|
-
- bin/em-zeromq
|
46
|
-
- lib/em-zeromq/.connection.rb.swp
|
47
|
-
- lib/em-zeromq/.zeromq.rb.swp
|
48
|
-
- version.txt
|
91
|
+
extra_rdoc_files: []
|
92
|
+
|
49
93
|
files:
|
50
|
-
- .Rakefile.swo
|
51
94
|
- .bnsignore
|
95
|
+
- .gitignore
|
96
|
+
- Gemfile
|
52
97
|
- History.txt
|
53
98
|
- README.md
|
54
99
|
- Rakefile
|
55
|
-
- bin/em-zeromq
|
56
100
|
- em-zeromq.gemspec
|
57
101
|
- example/simple.rb
|
58
102
|
- lib/em-zeromq.rb
|
59
|
-
- lib/em-zeromq/.connection.rb.swp
|
60
|
-
- lib/em-zeromq/.zeromq.rb.swp
|
61
103
|
- lib/em-zeromq/connection.rb
|
62
|
-
- lib/em-zeromq/
|
63
|
-
-
|
64
|
-
- spec
|
104
|
+
- lib/em-zeromq/context.rb
|
105
|
+
- lib/em-zeromq/version.rb
|
106
|
+
- spec/context_spec.rb
|
65
107
|
- spec/pub_sub_spec.rb
|
66
108
|
- spec/push_pull_spec.rb
|
67
109
|
- spec/spec_helper.rb
|
68
110
|
- spec/xreq_xrep_spec.rb
|
69
|
-
- test/test_em-zeromq.rb
|
70
|
-
- version.txt
|
71
111
|
has_rdoc: true
|
72
112
|
homepage: https://github.com/andrewvc/em-zeromq
|
73
113
|
licenses: []
|
@@ -90,12 +130,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
131
|
none: false
|
92
132
|
requirements:
|
93
|
-
- - "
|
133
|
+
- - ">"
|
94
134
|
- !ruby/object:Gem::Version
|
95
|
-
hash:
|
135
|
+
hash: 25
|
96
136
|
segments:
|
97
|
-
-
|
98
|
-
|
137
|
+
- 1
|
138
|
+
- 3
|
139
|
+
- 1
|
140
|
+
version: 1.3.1
|
99
141
|
requirements: []
|
100
142
|
|
101
143
|
rubyforge_project: em-zeromq
|
@@ -103,5 +145,5 @@ rubygems_version: 1.3.7
|
|
103
145
|
signing_key:
|
104
146
|
specification_version: 3
|
105
147
|
summary: Low level event machine support for ZeroMQ
|
106
|
-
test_files:
|
107
|
-
|
148
|
+
test_files: []
|
149
|
+
|
data/.Rakefile.swo
DELETED
Binary file
|
data/bin/em-zeromq
DELETED
Binary file
|
Binary file
|
data/lib/em-zeromq/zeromq.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
module EventMachine
|
2
|
-
module ZeroMQ
|
3
|
-
def self.create(context, socket_type, bind_or_connect, address, handler)
|
4
|
-
socket = context.socket socket_type
|
5
|
-
|
6
|
-
unless [:bind, :connect].include?(bind_or_connect)
|
7
|
-
raise ArgumentError, "Invalid Option '#{bind_or_connect}' try :bind or :connect"
|
8
|
-
end
|
9
|
-
|
10
|
-
if bind_or_connect == :bind
|
11
|
-
socket.bind address
|
12
|
-
else
|
13
|
-
socket.connect address
|
14
|
-
end
|
15
|
-
|
16
|
-
conn = EM.watch(socket.getsockopt(ZMQ::FD), EventMachine::ZeroMQ::Connection, socket, socket_type, address, handler)
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
data/spec/.spec_helper.rb.swp
DELETED
Binary file
|
data/spec/.xreq_xrep_spec.rb.swp
DELETED
Binary file
|
data/test/test_em-zeromq.rb
DELETED
File without changes
|
data/version.txt
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.1.2
|