em-zeromq 0.1.2 → 0.2.0.beta1
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/.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
|