em-zeromq 0.3.1 → 0.4.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/README.md CHANGED
@@ -53,50 +53,25 @@ flag api changes but be aware that small changes can still occur between release
53
53
 
54
54
  ## Example ##
55
55
  ```ruby
56
- require 'rubygems'
57
56
  require 'em-zeromq'
58
57
 
59
- class EMTestPullHandler
60
- attr_reader :received
61
- def on_readable(socket, parts)
62
- parts.each do |m|
63
- puts m.copy_out_string
64
- end
65
- end
66
- end
58
+ zmq = EM::ZeroMQ::Context.new(1)
67
59
 
68
- trap('INT') do
69
- EM::stop()
70
- end
60
+ EM.run {
61
+ push = zmq.socket(ZMQ::PUSH)
62
+ push.connect("tcp://127.0.0.1:2091")
71
63
 
72
- ctx = EM::ZeroMQ::Context.new(1)
73
- EM.run do
74
- # setup push sockets
75
- push_socket1 = ctx.socket(ZMQ::PUSH)
76
- push_socket1.bind('tcp://127.0.0.1:2091')
77
-
78
- push_socket2 = ctx.socket(ZMQ::PUSH) do |s|
79
- s.bind('ipc:///tmp/a')
80
- end
81
-
82
- push_socket3 = ctx.socket(ZMQ::PUSH)
83
- push_socket3.bind('inproc://simple_test')
84
-
85
- # setup one pull sockets listening to all push sockets
86
- pull_socket = ctx.socket(ZMQ::PULL, EMTestPullHandler.new)
87
- pull_socket.connect('tcp://127.0.0.1:2091')
88
- pull_socket.connect('ipc:///tmp/a')
89
- pull_socket.connect('inproc://simple_test')
90
-
91
- n = 0
92
-
93
- EM::PeriodicTimer.new(0.1) do
94
- puts '.'
95
- push_socket1.send_msg("t#{n += 1}_")
96
- push_socket2.send_msg("i#{n += 1}_")
97
- push_socket3.send_msg("p#{n += 1}_")
98
- end
99
- end
64
+ pull = zmq.socket(ZMQ::PULL)
65
+ pull.bind("tcp://127.0.0.1:2091")
66
+
67
+ pull.on(:message) { |part|
68
+ puts part.copy_out_string
69
+ }
70
+
71
+ EM.add_periodic_timer(1) {
72
+ push.send_msg("Hello")
73
+ }
74
+ }
100
75
  ```
101
76
 
102
77
  ## License: ##
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.rubyforge_project = "em-zeromq"
17
17
 
18
- s.add_dependency 'eventmachine', '1.0.0.beta.4'
18
+ s.add_dependency 'eventmachine', '>= 1.0.0'
19
19
  s.add_dependency 'ffi', '>= 1.0.0'
20
20
  s.add_dependency 'ffi-rzmq', '0.9.3'
21
21
 
@@ -0,0 +1,31 @@
1
+ # This example shows how one might deal with sending and recieving multi-part
2
+ # messages
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+
6
+ require 'em-zeromq'
7
+
8
+ zmq = EM::ZeroMQ::Context.new(1)
9
+
10
+ EM.run {
11
+ pull = zmq.socket(ZMQ::PULL)
12
+ pull.bind("ipc:///tmp/test")
13
+
14
+ pull.on(:message) { |part1, part2|
15
+ p [:part1, part1.copy_out_string, :part2, part2.copy_out_string]
16
+ }
17
+
18
+ pull.on(:message) { |*parts|
19
+ p [:parts, parts.map(&:copy_out_string)]
20
+ }
21
+
22
+ push = zmq.socket(ZMQ::PUSH)
23
+ push.connect("ipc:///tmp/test")
24
+
25
+ i = 0
26
+ EM.add_periodic_timer(1) {
27
+ puts "Sending 2-part message"
28
+ i += 1
29
+ push.send_msg("hello #{i}", "second part")
30
+ }
31
+ }
@@ -4,23 +4,14 @@ require 'em-zeromq'
4
4
 
5
5
  Thread.abort_on_exception = true
6
6
 
7
- class EMTestPullHandler
8
- attr_reader :received
9
- def on_readable(socket, parts)
10
- parts.each do |m|
11
- puts m.copy_out_string
12
- end
13
- end
14
- end
15
-
16
7
  trap('INT') do
17
8
  EM::stop()
18
9
  end
19
10
 
20
11
  puts "Started (with zmq #{ZMQ::Util.version.join('.')})."
21
12
 
22
-
23
13
  ctx = EM::ZeroMQ::Context.new(1)
14
+
24
15
  EM.run do
25
16
  # setup push sockets
26
17
  push_socket1 = ctx.socket(ZMQ::PUSH)
@@ -30,19 +21,24 @@ EM.run do
30
21
 
31
22
  push_socket1.bind('tcp://127.0.0.1:2091')
32
23
 
33
- push_socket2 = ctx.socket(ZMQ::PUSH) do |s|
34
- s.bind('ipc:///tmp/a')
35
- end
24
+ push_socket2 = ctx.socket(ZMQ::PUSH)
25
+ push_socket2.bind('ipc:///tmp/a')
36
26
 
37
27
  push_socket3 = ctx.socket(ZMQ::PUSH)
38
28
  push_socket3.bind('inproc://simple_test')
39
29
 
40
30
  # setup one pull sockets listening to all push sockets
41
- pull_socket = ctx.socket(ZMQ::PULL, EMTestPullHandler.new)
31
+ pull_socket = ctx.socket(ZMQ::PULL)
42
32
  pull_socket.connect('tcp://127.0.0.1:2091')
43
33
  pull_socket.connect('ipc:///tmp/a')
44
34
  pull_socket.connect('inproc://simple_test')
45
35
 
36
+ pull_socket.on(:message) { |*parts|
37
+ parts.each do |m|
38
+ puts m.copy_out_string
39
+ end
40
+ }
41
+
46
42
  n = 0
47
43
 
48
44
  EM::PeriodicTimer.new(0.1) do
@@ -0,0 +1,23 @@
1
+ # Simpler than simple.rb ;)
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'em-zeromq'
6
+
7
+ zmq = EM::ZeroMQ::Context.new(1)
8
+
9
+ EM.run {
10
+ push = zmq.socket(ZMQ::PUSH)
11
+ push.connect("tcp://127.0.0.1:2091")
12
+
13
+ pull = zmq.socket(ZMQ::PULL)
14
+ pull.bind("tcp://127.0.0.1:2091")
15
+
16
+ pull.on(:message) { |part|
17
+ puts part.copy_out_string
18
+ }
19
+
20
+ EM.add_periodic_timer(1) {
21
+ push.send_msg("Hello")
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ # This example shows how to use setsockopt to set the linger period for socket
2
+ # shutdown. This is useful since by default pending meesages will block the
3
+ # termination of the ZMQ context.
4
+
5
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
6
+
7
+ require 'em-zeromq'
8
+
9
+ zmq = EM::ZeroMQ::Context.new(1)
10
+
11
+ EM.run {
12
+ push = zmq.socket(ZMQ::PUSH)
13
+ push.setsockopt(ZMQ::LINGER, 0)
14
+
15
+ push.connect("ipc:///tmp/foo")
16
+
17
+ push.send_msg('hello')
18
+
19
+ Signal.trap('INT') {
20
+ puts 'Trapped INT signal. Stopping eventmachine'
21
+ EM.stop
22
+ }
23
+ }
@@ -3,59 +3,8 @@ require 'ffi-rzmq'
3
3
 
4
4
  module EmZeromq
5
5
 
6
- # :stopdoc:
7
- LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
8
- PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
9
- # :startdoc:
10
-
11
- # Returns the library path for the module. If any arguments are given,
12
- # they will be joined to the end of the libray path using
13
- # <tt>File.join</tt>.
14
- #
15
- def self.libpath( *args, &block )
16
- rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
17
- if block
18
- begin
19
- $LOAD_PATH.unshift LIBPATH
20
- rv = block.call
21
- ensure
22
- $LOAD_PATH.shift
23
- end
24
- end
25
- return rv
26
- end
27
-
28
- # Returns the lpath for the module. If any arguments are given,
29
- # they will be joined to the end of the path using
30
- # <tt>File.join</tt>.
31
- #
32
- def self.path( *args, &block )
33
- rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
34
- if block
35
- begin
36
- $LOAD_PATH.unshift PATH
37
- rv = block.call
38
- ensure
39
- $LOAD_PATH.shift
40
- end
41
- end
42
- return rv
43
- end
44
-
45
- # Utility method used to require all files ending in .rb that lie in the
46
- # directory below this file that has the same name as the filename passed
47
- # in. Optionally, a specific _directory_ name can be passed in such that
48
- # the _filename_ does not have to be equivalent to the directory.
49
- #
50
- def self.require_all_libs_relative_to( fname, dir = nil )
51
- dir ||= ::File.basename(fname, '.*')
52
- search_me = ::File.expand_path(
53
- ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
54
-
55
- Dir.glob(search_me).sort.each {|rb| require rb}
56
- end
57
-
58
- end # module EmZeromq
59
-
60
- EmZeromq.require_all_libs_relative_to(__FILE__)
6
+ end
61
7
 
8
+ require 'em-zeromq/context'
9
+ require 'em-zeromq/event_emitter'
10
+ require 'em-zeromq/socket'
@@ -7,8 +7,7 @@
7
7
  module EventMachine
8
8
  module ZeroMQ
9
9
  class Context
10
- READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ ]
11
- WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ ]
10
+
12
11
 
13
12
  def initialize(threads_or_context)
14
13
  if threads_or_context.is_a?(ZMQ::Context)
@@ -24,10 +23,8 @@ module EventMachine
24
23
  # @param [Integer] socket_type One of ZMQ::REQ, ZMQ::REP, ZMQ::PULL, ZMQ::PUSH,
25
24
  # ZMQ::ROUTER, ZMQ::DEALER
26
25
  #
27
- # @param [Object] handler an object which respond to on_readable(socket, parts)
28
- # and can respond to on_writeable(socket)
29
26
  #
30
- def socket(socket_type, handler = nil)
27
+ def socket(socket_type)
31
28
  zmq_socket = @context.socket(socket_type)
32
29
 
33
30
  fd = []
@@ -35,13 +32,7 @@ module EventMachine
35
32
  raise "Unable to get socket FD: #{ZMQ::Util.error_string}"
36
33
  end
37
34
 
38
-
39
- EM.watch(fd[0], EventMachine::ZeroMQ::Socket, zmq_socket, socket_type, handler).tap do |s|
40
- s.register_readable if READABLES.include?(socket_type)
41
- s.register_writable if WRITABLES.include?(socket_type)
42
-
43
- yield(s) if block_given?
44
- end
35
+ EM.watch(fd[0], EventMachine::ZeroMQ::Socket, zmq_socket, socket_type)
45
36
  end
46
37
 
47
38
  end
@@ -0,0 +1,31 @@
1
+ module EventMachine
2
+ module ZeroMQ
3
+ module EventEmitter
4
+ def on(event, &listener)
5
+ _listeners[event] << listener
6
+ end
7
+
8
+ def emit(event, *args)
9
+ _listeners[event].each { |l| l.call(*args) }
10
+ end
11
+
12
+ def remove_listener(event, &listener)
13
+ _listeners[event].delete(listener)
14
+ end
15
+
16
+ def remove_all_listeners(event)
17
+ _listeners.delete(event)
18
+ end
19
+
20
+ def listeners(event)
21
+ _listeners[event]
22
+ end
23
+
24
+ private
25
+
26
+ def _listeners
27
+ @_listeners ||= Hash.new { |h,k| h[k] = [] }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,13 +1,19 @@
1
1
  module EventMachine
2
2
  module ZeroMQ
3
3
  class Socket < EventMachine::Connection
4
- attr_accessor :on_readable, :on_writable, :handler
4
+ READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ, ZMQ::PAIR ]
5
+ WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ, ZMQ::PAIR ]
6
+
7
+ include EventEmitter
8
+
5
9
  attr_reader :socket, :socket_type
6
10
 
7
- def initialize(socket, socket_type, handler)
11
+ def initialize(socket, socket_type)
8
12
  @socket = socket
9
13
  @socket_type = socket_type
10
- @handler = handler
14
+
15
+ self.notify_readable = true if READABLES.include?(socket_type)
16
+ self.notify_writable = true if WRITABLES.include?(socket_type)
11
17
  end
12
18
 
13
19
  def self.map_sockopt(opt, name)
@@ -96,26 +102,10 @@ module EventMachine
96
102
  def setsockopt(opt, value)
97
103
  @socket.setsockopt(opt, value)
98
104
  end
99
-
100
- # cleanup when ending loop
101
- def unbind
102
- detach_and_close
103
- end
104
-
105
- # Make this socket available for reads
106
- def register_readable
107
- # Since ZMQ is event triggered I think this is necessary
108
- if readable?
109
- notify_readable
110
- end
111
- # Subscribe to EM read notifications
112
- self.notify_readable = true
113
- end
114
105
 
115
- # Trigger on_readable when socket is readable
116
- def register_writable
117
- # Subscribe to EM write notifications
118
- self.notify_writable = true
106
+ def unbind
107
+ detach
108
+ @socket.close
119
109
  end
120
110
 
121
111
  def notify_readable
@@ -124,25 +114,9 @@ module EventMachine
124
114
  # I'm leaving this is because its in the docs, but it could probably
125
115
  # be taken out.
126
116
  return unless readable?
127
-
128
- loop do
129
- msg_parts = []
130
- msg = get_message
131
- if msg
132
- msg_parts << msg
133
- while @socket.more_parts?
134
- msg = get_message
135
- if msg
136
- msg_parts << msg
137
- else
138
- raise "Multi-part message missing a message!"
139
- end
140
- end
141
-
142
- @handler.on_readable(self, msg_parts)
143
- else
144
- break
145
- end
117
+
118
+ while (message = get_message)
119
+ emit(:message, *message)
146
120
  end
147
121
  end
148
122
 
@@ -154,9 +128,7 @@ module EventMachine
154
128
  # write events
155
129
  self.notify_writable = false
156
130
 
157
- if @handler.respond_to?(:on_writable)
158
- @handler.on_writable(self)
159
- end
131
+ emit(:writable)
160
132
  end
161
133
  def readable?
162
134
  (getsockopt(ZMQ::EVENTS) & ZMQ::POLLIN) == ZMQ::POLLIN
@@ -169,20 +141,11 @@ module EventMachine
169
141
  end
170
142
 
171
143
  private
172
-
173
- # internal methods
174
144
 
175
145
  def get_message
176
- msg = ZMQ::Message.new
177
- msg_recvd = @socket.recv(msg, ZMQ::NOBLOCK)
178
- msg_recvd != -1 ? msg : nil
179
- end
180
-
181
- # Detaches the socket from the EM loop,
182
- # then closes the socket
183
- def detach_and_close
184
- detach
185
- @socket.close
146
+ parts = []
147
+ rc = @socket.recvmsgs(parts, ZMQ::NOBLOCK)
148
+ rc >= 0 ? parts : nil
186
149
  end
187
150
  end
188
151
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module EmZeromq
3
- VERSION = "0.3.1"
3
+ VERSION = "0.4.0"
4
4
  end
@@ -1,22 +1,12 @@
1
1
  require File.join(File.dirname(__FILE__), %w[spec_helper])
2
2
 
3
3
  describe EventMachine::ZeroMQ do
4
- class EMTestSubHandler
5
- attr_reader :received
6
- def initialize
7
- @received = []
8
- end
9
- def on_readable(socket, messages)
10
- @received += messages
11
- end
12
- end
13
-
14
4
  it "Should instantiate a connection given valid opts" do
15
5
  sub_conn = nil
16
6
  address = rand_addr
17
7
 
18
- run_reactor(1) do
19
- sub_conn = SPEC_CTX.socket(ZMQ::PUB, EMTestSubHandler.new)
8
+ run_reactor do
9
+ sub_conn = SPEC_CTX.socket(ZMQ::PUB)
20
10
  sub_conn.bind(address)
21
11
  end
22
12
  sub_conn.should be_a(EventMachine::ZeroMQ::Socket)
@@ -24,42 +14,43 @@ describe EventMachine::ZeroMQ do
24
14
 
25
15
  describe "sending/receiving a single message via PUB/SUB" do
26
16
  before(:all) do
27
- results = {}
17
+ @results = {}
18
+ @received = []
28
19
  @test_message = test_message = "TMsg#{rand(999)}"
29
20
 
30
- run_reactor(0.5) do
21
+ run_reactor do
31
22
  address = rand_addr
32
23
 
33
- results[:sub_hndlr] = pull_hndlr = EMTestSubHandler.new
34
- sub_conn = SPEC_CTX.socket(ZMQ::SUB, pull_hndlr)
24
+ sub_conn = SPEC_CTX.socket(ZMQ::SUB)
35
25
  sub_conn.bind(address)
36
26
  sub_conn.subscribe('')
27
+ sub_conn.on(:message) { |m|
28
+ @received << m
29
+ }
37
30
 
38
- pub_conn = SPEC_CTX.socket(ZMQ::PUB, EMTestSubHandler.new)
31
+ pub_conn = SPEC_CTX.socket(ZMQ::PUB)
39
32
  pub_conn.connect(address)
40
33
 
41
34
  pub_conn.socket.send_string test_message, ZMQ::NOBLOCK
42
35
 
43
- EM::Timer.new(0.1) { results[:specs_ran] = true }
36
+ EM::Timer.new(0.1) { @results[:specs_ran] = true }
44
37
  end
45
-
46
- @results = results
47
38
  end
48
39
 
49
40
  it "should run completely" do
50
- @results[:specs_ran].should be_true
41
+ @received.should be_true
51
42
  end
52
43
 
53
44
  it "should receive one message" do
54
- @results[:sub_hndlr].received.length.should == 1
45
+ @received.length.should == 1
55
46
  end
56
47
 
57
48
  it "should receive the message as a ZMQ::Message" do
58
- @results[:sub_hndlr].received.first.should be_a(ZMQ::Message)
49
+ @received.first.should be_a(ZMQ::Message)
59
50
  end
60
51
 
61
52
  it "should receive the message intact" do
62
- @results[:sub_hndlr].received.first.copy_out_string.should == @test_message
53
+ @received.first.copy_out_string.should == @test_message
63
54
  end
64
55
  end
65
56
  end
@@ -1,20 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), %w[spec_helper])
2
2
 
3
3
  describe EventMachine::ZeroMQ do
4
- class EMTestPullHandler
5
- attr_reader :received
6
- def initialize
7
- @received = []
8
- end
9
- def on_readable(socket, messages)
10
- @received += messages
11
- end
12
- end
13
-
14
4
  it "Should instantiate a connection given valid opts" do
15
5
  pull_conn = nil
16
6
  run_reactor do
17
- pull_conn = SPEC_CTX.socket(ZMQ::PULL, EMTestPullHandler.new)
7
+ pull_conn = SPEC_CTX.socket(ZMQ::PULL)
18
8
  pull_conn.bind(rand_addr)
19
9
  end
20
10
  pull_conn.should be_a(EventMachine::ZeroMQ::Socket)
@@ -22,26 +12,26 @@ describe EventMachine::ZeroMQ do
22
12
 
23
13
  describe "sending/receiving a single message via PUB/SUB" do
24
14
  before(:all) do
25
- results = {}
15
+ @results = {}
16
+ @received = []
26
17
  @test_message = test_message = "TMsg#{rand(999)}"
27
18
 
28
- run_reactor(0.5) do
29
-
19
+ run_reactor(0.2) do
30
20
  address = rand_addr
31
21
 
32
- results[:pull_hndlr] = pull_hndlr = EMTestPullHandler.new
33
- pull_conn = SPEC_CTX.socket(ZMQ::PULL, pull_hndlr)
22
+ pull_conn = SPEC_CTX.socket(ZMQ::PULL)
34
23
  pull_conn.bind(address)
24
+ pull_conn.on(:message) { |m|
25
+ @received << m
26
+ }
35
27
 
36
28
  push_conn = SPEC_CTX.socket(ZMQ::PUSH)
37
29
  push_conn.connect(address)
38
30
 
39
31
  push_conn.socket.send_string test_message, ZMQ::NOBLOCK
40
32
 
41
- EM::Timer.new(0.1) { results[:specs_ran] = true }
33
+ EM::Timer.new(0.1) { @results[:specs_ran] = true }
42
34
  end
43
-
44
- @results = results
45
35
  end
46
36
 
47
37
  it "should run completely" do
@@ -49,9 +39,9 @@ describe EventMachine::ZeroMQ do
49
39
  end
50
40
 
51
41
  it "should receive the message intact" do
52
- @results[:pull_hndlr].received.should_not be_empty
53
- @results[:pull_hndlr].received.first.should be_a(ZMQ::Message)
54
- @results[:pull_hndlr].received.first.copy_out_string.should == @test_message
42
+ @received.should_not be_empty
43
+ @received.first.should be_a(ZMQ::Message)
44
+ @received.first.copy_out_string.should == @test_message
55
45
  end
56
46
  end
57
47
  end
@@ -1,39 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), %w[spec_helper])
2
2
 
3
3
  describe EventMachine::ZeroMQ do
4
- class EMTestRouterHandler
5
- attr_reader :received
6
- def initialize
7
- @received = []
8
- end
9
- def on_writable(socket)
10
- end
11
- def on_readable(socket, messages)
12
- @received += messages
13
- end
14
- end
15
-
16
- class EMTestDealerHandler
17
- attr_reader :received
18
- def initialize(&block)
19
- @received = []
20
- @on_writable_callback = block
21
- end
22
- def on_writable(socket)
23
- @on_writable_callback.call(socket) if @on_writable_callback
24
- end
25
- def on_readable(socket, messages)
26
- _, message = messages.map(&:copy_out_string)
27
- @received += [message].map {|s| ZMQ::Message.new(s)}
28
-
29
- socket.send_msg('', "re:#{message}")
30
- end
31
- end
32
-
33
4
  it "Should instantiate a connection given valid opts for Router/Dealer" do
34
5
  router_conn = nil
35
- run_reactor(1) do
36
- router_conn = SPEC_CTX.socket(ZMQ::ROUTER, EMTestRouterHandler.new)
6
+ run_reactor do
7
+ router_conn = SPEC_CTX.socket(ZMQ::ROUTER)
37
8
  router_conn.bind(rand_addr)
38
9
  end
39
10
  router_conn.should be_a(EventMachine::ZeroMQ::Socket)
@@ -41,32 +12,38 @@ describe EventMachine::ZeroMQ do
41
12
 
42
13
  describe "sending/receiving a single message via Router/Dealer" do
43
14
  before(:all) do
44
- results = {}
15
+ @results = {}
16
+ @dealer_received, @router_received = [], []
45
17
  @test_message = test_message = "M#{rand(999)}"
46
18
 
47
- run_reactor(2) do
48
- results[:dealer_hndlr] = dealer_hndlr = EMTestDealerHandler.new
49
- results[:router_hndlr] = router_hndlr = EMTestRouterHandler.new
50
-
19
+ run_reactor(0.3) do
51
20
  addr = rand_addr
52
- dealer_conn = SPEC_CTX.socket(ZMQ::DEALER, dealer_hndlr)
21
+ dealer_conn = SPEC_CTX.socket(ZMQ::DEALER)
53
22
  dealer_conn.identity = "dealer1"
54
23
  dealer_conn.bind(addr)
24
+ dealer_conn.on(:message) { |message|
25
+ # 2. Dealer receives messages, sends reply back to router
26
+ @dealer_received << message
27
+ dealer_conn.send_msg("re:#{message.copy_out_string}")
28
+ }
55
29
 
56
- router_conn = SPEC_CTX.socket(ZMQ::ROUTER, router_hndlr)
30
+ router_conn = SPEC_CTX.socket(ZMQ::ROUTER)
57
31
  router_conn.identity = "router1"
58
32
  router_conn.connect(addr)
33
+ router_conn.on(:message) { |*parts|
34
+ # 3. Message received in router identifies the sending dealer
35
+ @router_received << parts
36
+ }
59
37
 
60
38
  EM::add_timer(0.1) do
61
- router_conn.send_msg('dealer1','', test_message)
39
+ # 1. Send message to the dealer
40
+ router_conn.send_msg('dealer1', test_message)
62
41
  end
63
42
 
64
43
  EM::Timer.new(0.2) do
65
- results[:specs_ran] = true
44
+ @results[:specs_ran] = true
66
45
  end
67
46
  end
68
-
69
- @results = results
70
47
  end
71
48
 
72
49
  it "should run completely" do
@@ -74,15 +51,16 @@ describe EventMachine::ZeroMQ do
74
51
  end
75
52
 
76
53
  it "should receive the message intact on the dealer" do
77
- @results[:dealer_hndlr].received.should_not be_empty
78
- @results[:dealer_hndlr].received.last.should be_a(ZMQ::Message)
79
- @results[:dealer_hndlr].received.last.copy_out_string.should == @test_message
54
+ @dealer_received.should_not be_empty
55
+ @dealer_received.last.should be_a(ZMQ::Message)
56
+ @dealer_received.last.copy_out_string.should == @test_message
80
57
  end
81
58
 
82
- it "the router should be echoed its original message" do
83
- @results[:router_hndlr].received.should_not be_empty
84
- @results[:router_hndlr].received.last.should be_a(ZMQ::Message)
85
- @results[:router_hndlr].received.last.copy_out_string.should == "re:#{@test_message}"
59
+ it "the router should be echoed its original message with the dealer identity" do
60
+ @router_received.size.should == 1
61
+ parts = @router_received[0]
62
+ parts[0].copy_out_string.should == "dealer1"
63
+ parts[1].copy_out_string.should == "re:#{@test_message}"
86
64
  end
87
65
  end
88
66
  end
@@ -10,7 +10,7 @@ end
10
10
  require File.expand_path(
11
11
  File.join(File.dirname(__FILE__), %w[.. lib em-zeromq]))
12
12
 
13
- def run_reactor(time=0.2,&block)
13
+ def run_reactor(time=0.1,&block)
14
14
  Thread.new do
15
15
  EM.run do
16
16
  yield
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-zeromq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,24 +10,24 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-01 00:00:00.000000000 Z
13
+ date: 2012-11-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: eventmachine
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
- - - '='
20
+ - - ! '>='
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.0.beta.4
22
+ version: 1.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  none: false
27
27
  requirements:
28
- - - '='
28
+ - - ! '>='
29
29
  - !ruby/object:Gem::Version
30
- version: 1.0.0.beta.4
30
+ version: 1.0.0
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: ffi
33
33
  requirement: !ruby/object:Gem::Requirement
@@ -122,9 +122,13 @@ files:
122
122
  - README.md
123
123
  - Rakefile
124
124
  - em-zeromq.gemspec
125
+ - example/multi-part.rb
125
126
  - example/simple.rb
127
+ - example/simpler.rb
128
+ - example/terminating.rb
126
129
  - lib/em-zeromq.rb
127
130
  - lib/em-zeromq/context.rb
131
+ - lib/em-zeromq/event_emitter.rb
128
132
  - lib/em-zeromq/socket.rb
129
133
  - lib/em-zeromq/version.rb
130
134
  - spec/context_spec.rb
@@ -148,7 +152,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
152
  version: '0'
149
153
  segments:
150
154
  - 0
151
- hash: 3380199177389627233
155
+ hash: 4479496977537005722
152
156
  required_rubygems_version: !ruby/object:Gem::Requirement
153
157
  none: false
154
158
  requirements:
@@ -157,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
161
  version: '0'
158
162
  segments:
159
163
  - 0
160
- hash: 3380199177389627233
164
+ hash: 4479496977537005722
161
165
  requirements: []
162
166
  rubyforge_project: em-zeromq
163
167
  rubygems_version: 1.8.24