rbczmq 0.1
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 +23 -0
- data/.travis.yml +19 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +19 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +247 -0
- data/Rakefile +67 -0
- data/examples/loop.rb +109 -0
- data/examples/poller.rb +37 -0
- data/examples/pub_sub.rb +101 -0
- data/examples/push_pull.rb +104 -0
- data/examples/req_rep.rb +100 -0
- data/ext/czmq.tar.gz +0 -0
- data/ext/rbczmq/context.c +280 -0
- data/ext/rbczmq/context.h +26 -0
- data/ext/rbczmq/extconf.rb +138 -0
- data/ext/rbczmq/frame.c +401 -0
- data/ext/rbczmq/frame.h +24 -0
- data/ext/rbczmq/jruby.h +22 -0
- data/ext/rbczmq/loop.c +413 -0
- data/ext/rbczmq/loop.h +24 -0
- data/ext/rbczmq/message.c +620 -0
- data/ext/rbczmq/message.h +24 -0
- data/ext/rbczmq/poller.c +308 -0
- data/ext/rbczmq/poller.h +29 -0
- data/ext/rbczmq/pollitem.c +251 -0
- data/ext/rbczmq/pollitem.h +25 -0
- data/ext/rbczmq/rbczmq_ext.c +198 -0
- data/ext/rbczmq/rbczmq_ext.h +94 -0
- data/ext/rbczmq/rbczmq_prelude.h +22 -0
- data/ext/rbczmq/rubinius.h +24 -0
- data/ext/rbczmq/ruby18.h +43 -0
- data/ext/rbczmq/ruby19.h +15 -0
- data/ext/rbczmq/socket.c +1570 -0
- data/ext/rbczmq/socket.h +136 -0
- data/ext/rbczmq/timer.c +110 -0
- data/ext/rbczmq/timer.h +23 -0
- data/ext/zeromq.tar.gz +0 -0
- data/lib/rbczmq.rb +3 -0
- data/lib/zmq.rb +77 -0
- data/lib/zmq/context.rb +50 -0
- data/lib/zmq/default_handler.rb +16 -0
- data/lib/zmq/frame.rb +11 -0
- data/lib/zmq/handler.rb +76 -0
- data/lib/zmq/loop.rb +131 -0
- data/lib/zmq/message.rb +9 -0
- data/lib/zmq/poller.rb +22 -0
- data/lib/zmq/pollitem.rb +31 -0
- data/lib/zmq/socket.rb +125 -0
- data/lib/zmq/socket/dealer.rb +33 -0
- data/lib/zmq/socket/pair.rb +39 -0
- data/lib/zmq/socket/pub.rb +30 -0
- data/lib/zmq/socket/pull.rb +29 -0
- data/lib/zmq/socket/push.rb +32 -0
- data/lib/zmq/socket/rep.rb +37 -0
- data/lib/zmq/socket/req.rb +37 -0
- data/lib/zmq/socket/router.rb +38 -0
- data/lib/zmq/socket/sub.rb +27 -0
- data/lib/zmq/timer.rb +12 -0
- data/lib/zmq/version.rb +5 -0
- data/perf/pair.rb +7 -0
- data/perf/pair/local.rb +22 -0
- data/perf/pair/remote.rb +25 -0
- data/perf/pub_sub.rb +7 -0
- data/perf/pub_sub/local.rb +22 -0
- data/perf/pub_sub/remote.rb +25 -0
- data/perf/push_pull.rb +7 -0
- data/perf/push_pull/local.rb +21 -0
- data/perf/push_pull/remote.rb +25 -0
- data/perf/req_rep.rb +7 -0
- data/perf/req_rep/local.rb +35 -0
- data/perf/req_rep/remote.rb +28 -0
- data/perf/runner.rb +142 -0
- data/rbczmq.gemspec +22 -0
- data/test/helper.rb +21 -0
- data/test/socket/test_dealer_socket.rb +14 -0
- data/test/socket/test_pair_socket.rb +24 -0
- data/test/socket/test_pair_sockets.rb +74 -0
- data/test/socket/test_pub_socket.rb +17 -0
- data/test/socket/test_pub_sub_sockets.rb +87 -0
- data/test/socket/test_pull_socket.rb +17 -0
- data/test/socket/test_push_pull_sockets.rb +81 -0
- data/test/socket/test_push_socket.rb +17 -0
- data/test/socket/test_rep_socket.rb +25 -0
- data/test/socket/test_req_rep_sockets.rb +42 -0
- data/test/socket/test_req_socket.rb +27 -0
- data/test/socket/test_router_socket.rb +14 -0
- data/test/socket/test_routing.rb +66 -0
- data/test/socket/test_sub_socket.rb +17 -0
- data/test/test_context.rb +86 -0
- data/test/test_frame.rb +78 -0
- data/test/test_handler.rb +28 -0
- data/test/test_loop.rb +252 -0
- data/test/test_message.rb +201 -0
- data/test/test_poller.rb +154 -0
- data/test/test_pollitem.rb +78 -0
- data/test/test_socket.rb +403 -0
- data/test/test_threading.rb +34 -0
- data/test/test_timer.rb +37 -0
- data/test/test_zmq.rb +62 -0
- metadata +208 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ZMQ::Socket::Push
|
4
|
+
|
5
|
+
# == ZMQ::Socket::Push
|
6
|
+
#
|
7
|
+
# A socket of type ZMQ::Socket::Push is used by a pipeline node to send messages to downstream pipeline nodes. Messages are
|
8
|
+
# load-balanced to all connected downstream nodes. The ZMQ::Socket#recv function is not implemented for this socket type.
|
9
|
+
#
|
10
|
+
# When a ZMQ::Socket::Push socket enters an exceptional state due to having reached the high water mark for all downstream
|
11
|
+
# nodes, or if there are no downstream nodes at all, then any ZMQ::Socket#send operations on the socket shall block until
|
12
|
+
# the exceptional state ends or at least one downstream node becomes available for sending; messages are not discarded.
|
13
|
+
#
|
14
|
+
# Deprecated alias: ZMQ_DOWNSTREAM.
|
15
|
+
#
|
16
|
+
# === Summary of ZMQ::Socket::Push characteristics
|
17
|
+
#
|
18
|
+
# [Compatible peer sockets] ZMQ::Socket::Pull
|
19
|
+
# [Direction] Unidirectional
|
20
|
+
# [Send/receive pattern] Send only
|
21
|
+
# [Incoming routing strategy] N/A
|
22
|
+
# [Outgoing routing strategy] Load-balanced
|
23
|
+
# [ZMQ::Socket#hwm option action] Block
|
24
|
+
|
25
|
+
TYPE_STR = "PUSH"
|
26
|
+
|
27
|
+
def type
|
28
|
+
ZMQ::PUSH
|
29
|
+
end
|
30
|
+
|
31
|
+
include ZMQ::UpstreamSocket
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ZMQ::Socket::Rep
|
4
|
+
|
5
|
+
# == ZMQ::Socket::Rep
|
6
|
+
#
|
7
|
+
# A socket of type ZMQ::Socket::Rep is used by a service to receive requests from and send replies to a client. This socket type
|
8
|
+
# allows only an alternating sequence of ZMQ::Socket#recv and subsequent ZMQ::Socket#send calls. Each request received is
|
9
|
+
# fair-queued from among all clients, and each reply sent is routed to the client that issued the last request. If the
|
10
|
+
# original requester doesn't exist any more the reply is silently discarded.
|
11
|
+
#
|
12
|
+
# When a ZMQ::Socket::Rep socket enters an exceptional state due to having reached the high water mark for a client, then any replies
|
13
|
+
# sent to the client in question shall be dropped until the exceptional state ends.
|
14
|
+
#
|
15
|
+
# === Summary of ZMQ::Socket#rep characteristics
|
16
|
+
#
|
17
|
+
# [Compatible peer sockets] ZMQ::Socket::Rep
|
18
|
+
# [Direction] Bidirectional
|
19
|
+
# [Send/receive pattern] Receive, Send, Receive, Send, …
|
20
|
+
# [Incoming routing strategy] Fair-queued
|
21
|
+
# [Outgoing routing strategy] Last peer
|
22
|
+
# [ZMQ::Socket#hwm option action] Drop
|
23
|
+
|
24
|
+
TYPE_STR = "REP"
|
25
|
+
|
26
|
+
def type
|
27
|
+
ZMQ::REP
|
28
|
+
end
|
29
|
+
|
30
|
+
unsupported_api :sendm
|
31
|
+
handle_fsm_errors "REP sockets allows only an alternating sequence of receive and subsequent send calls.", :send, :send_frame, :send_message, :recv, :recv_nonblock, :recv_frame, :recv_frame_nonblock, :recv_message
|
32
|
+
|
33
|
+
def send_frame(frame, flags = 0)
|
34
|
+
raise ZMQ::Error, "cannot send multiple frames on REP sockets" if (flags & ZMQ::Frame::MORE) == ZMQ::Frame::MORE
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ZMQ::Socket::Req
|
4
|
+
|
5
|
+
# == ZMQ::Socket::Req
|
6
|
+
#
|
7
|
+
# A socket of type ZMQ::Socket::Req is used by a client to send requests to and receive replies from a service. This socket type allows
|
8
|
+
# only an alternating sequence of ZMQ::Socket#send and subsequent ZMQ::Socket#recv calls. Each request sent is load-balanced
|
9
|
+
# among all services, and each reply received is matched with the last issued request.
|
10
|
+
#
|
11
|
+
# When a ZMQ::Socket::Req socket enters an exceptional state due to having reached the high water mark for all services, or if there
|
12
|
+
# are no services at all, then any ZMQ::Socket#send operations on the socket shall block until the exceptional state ends or at
|
13
|
+
# least one service becomes available for sending; messages are not discarded.
|
14
|
+
#
|
15
|
+
# === Summary of ZMQ::Socket::Req characteristics
|
16
|
+
#
|
17
|
+
# [Compatible peer sockets] ZMQ::Socket::Rep
|
18
|
+
# [Direction] Bidirectional
|
19
|
+
# [Send/receive pattern] Send, Receive, Send, Receive, …
|
20
|
+
# [Outgoing routing strategy] Load-balanced
|
21
|
+
# [Incoming routing strategy] Last peer
|
22
|
+
# [ZMQ::Socket#hwm option action] Block
|
23
|
+
|
24
|
+
TYPE_STR = "REQ"
|
25
|
+
|
26
|
+
def type
|
27
|
+
ZMQ::REQ
|
28
|
+
end
|
29
|
+
|
30
|
+
unsupported_api :sendm
|
31
|
+
handle_fsm_errors "REQ sockets allows only an alternating sequence of send and receive calls.", :send, :send_frame, :send_message, :recv, :recv_nonblock, :recv_frame, :recv_frame_nonblock, :recv_message
|
32
|
+
|
33
|
+
def send_frame(frame, flags = 0)
|
34
|
+
raise ZMQ::Error, "cannot send multiple frames on REQ sockets" if (flags & ZMQ::Frame::MORE) == ZMQ::Frame::MORE
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ZMQ::Socket::Router
|
4
|
+
|
5
|
+
# == ZMQ::Socket::Router
|
6
|
+
#
|
7
|
+
# A socket of type ZMQ::Socket::Router is an advanced pattern used for extending request/reply sockets. When receiving messages
|
8
|
+
# a ZMQ::Socket::Router socket shall prepend a message part containing the identity of the originating peer to the message before
|
9
|
+
# passing it to the application. Messages received are fair-queued from among all connected peers. When sending messages a
|
10
|
+
# ZMQ::Socket::Router socket shall remove the first part of the message and use it to determine the identity of the peer the message
|
11
|
+
# shall be routed to. If the peer does not exist anymore the message shall be silently discarded.
|
12
|
+
#
|
13
|
+
# Previously this socket was called ZMQ_XREP and that name remains available for backwards compatibility.
|
14
|
+
#
|
15
|
+
# When a ZMQ::Socket::Router socket enters an exceptional state due to having reached the high water mark for all peers, or if
|
16
|
+
# there are no peers at all, then any messages sent to the socket shall be dropped until the exceptional state ends. Likewise, any
|
17
|
+
# messages routed to a non-existent peer or a peer for which the individual high water mark has been reached shall also be dropped.
|
18
|
+
#
|
19
|
+
# When a ZMQ::Socket::Request socket is connected to a ZMQ::Socket::Router socket, in addition to the identity of the originating
|
20
|
+
# peer each message received shall contain an empty delimiter message part. Hence, the entire structure of each received message as
|
21
|
+
# seen by the application becomes: one or more identity parts, delimiter part, one or more body parts. When sending replies to a
|
22
|
+
# ZMQ::Socket::Request socket the application must include the delimiter part.
|
23
|
+
#
|
24
|
+
# === Summary of ZMQ_ROUTER characteristics
|
25
|
+
#
|
26
|
+
# [Compatible peer socket] ZMQ::Socket::Dealer, ZMQ::Socket::Req, ZMQ::Socket::Rep
|
27
|
+
# [Direction] Bidirectional
|
28
|
+
# [Send/receive pattern] Unrestricted
|
29
|
+
# [Outgoing routing strategy] See text
|
30
|
+
# [Incoming routing strategy] Fair-queued
|
31
|
+
# [ZMQ::Socket#hwm option action] Drop
|
32
|
+
|
33
|
+
TYPE_STR = "ROUTER"
|
34
|
+
|
35
|
+
def type
|
36
|
+
ZMQ::ROUTER
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ZMQ::Socket::Sub
|
4
|
+
|
5
|
+
# == ZMQ::Socket::Sub
|
6
|
+
#
|
7
|
+
# A socket of type ZMQ::Socket::Sub is used by a subscriber to subscribe to data distributed by a publisher. Initially a
|
8
|
+
# ZMQ::Socket::Sub socket is not subscribed to any messages, use ZMQ::Socket#subscribe to specify which messages to
|
9
|
+
# subscribe to. The ZMQ::Socket#send function is not implemented for this socket type.
|
10
|
+
#
|
11
|
+
# === Summary of ZMQ::Socket::Sub characteristics
|
12
|
+
#
|
13
|
+
# [Compatible peer sockets] ZMQ::Socket::Pub
|
14
|
+
# [Direction] Unidirectional
|
15
|
+
# [Send/receive pattern] Receive only
|
16
|
+
# [Incoming routing strategy] Fair-queued
|
17
|
+
# [Outgoing routing strategy] N/A
|
18
|
+
# [ZMQ::Socket#hwm option action] Drop
|
19
|
+
|
20
|
+
TYPE_STR = "SUB"
|
21
|
+
|
22
|
+
def type
|
23
|
+
ZMQ::SUB
|
24
|
+
end
|
25
|
+
|
26
|
+
include ZMQ::DownstreamSocket
|
27
|
+
end
|
data/lib/zmq/timer.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ZMQ::Timer
|
4
|
+
|
5
|
+
# Callback for error conditions such as exceptions raised in timer callbacks. Receives an exception instance as argument and raises by default.
|
6
|
+
#
|
7
|
+
# handler.on_error(err) => raise
|
8
|
+
#
|
9
|
+
def on_error(exception)
|
10
|
+
raise exception
|
11
|
+
end
|
12
|
+
end
|
data/lib/zmq/version.rb
ADDED
data/perf/pair.rb
ADDED
data/perf/pair/local.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ::Context.new
|
4
|
+
pair = ctx.socket(:PAIR)
|
5
|
+
sleep 2
|
6
|
+
pair.connect($runner.endpoint)
|
7
|
+
|
8
|
+
messages, start_time = 0, nil
|
9
|
+
while (case $runner.encoding
|
10
|
+
when :string
|
11
|
+
pair.recv
|
12
|
+
when :frame
|
13
|
+
pair.recv_frame
|
14
|
+
when :message
|
15
|
+
pair.recv_message
|
16
|
+
end) do
|
17
|
+
start_time ||= Time.now
|
18
|
+
messages += 1
|
19
|
+
break if messages == $runner.msg_count
|
20
|
+
end
|
21
|
+
|
22
|
+
$runner.stats(start_time)
|
data/perf/pair/remote.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ.context
|
4
|
+
pair = ctx.socket(:PAIR);
|
5
|
+
pair.bind($runner.endpoint);
|
6
|
+
|
7
|
+
msg = $runner.payload
|
8
|
+
|
9
|
+
start_time = Time.now
|
10
|
+
$runner.msg_count.times do
|
11
|
+
case $runner.encoding
|
12
|
+
when :string
|
13
|
+
pair.send(msg)
|
14
|
+
when :frame
|
15
|
+
pair.send_frame(ZMQ::Frame(msg))
|
16
|
+
when :message
|
17
|
+
m = ZMQ::Message.new
|
18
|
+
m.pushstr "header"
|
19
|
+
m.pushstr msg
|
20
|
+
m.pushstr "body"
|
21
|
+
pair.send_message(m)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Sent #{$runner.msg_count} messages in %ss ..." % (Time.now - start_time)
|
data/perf/pub_sub.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ::Context.new
|
4
|
+
sub = ctx.socket(:SUB)
|
5
|
+
sub.subscribe("")
|
6
|
+
sub.connect($runner.endpoint)
|
7
|
+
|
8
|
+
messages, start_time = 0, nil
|
9
|
+
while (case $runner.encoding
|
10
|
+
when :string
|
11
|
+
sub.recv
|
12
|
+
when :frame
|
13
|
+
sub.recv_frame
|
14
|
+
when :message
|
15
|
+
sub.recv_message
|
16
|
+
end) do
|
17
|
+
start_time ||= Time.now
|
18
|
+
messages += 1
|
19
|
+
break if messages == $runner.msg_count
|
20
|
+
end
|
21
|
+
|
22
|
+
$runner.stats(start_time)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ::Context.new
|
4
|
+
pub = ctx.socket(:PUB);
|
5
|
+
pub.bind($runner.endpoint);
|
6
|
+
|
7
|
+
msg = $runner.payload
|
8
|
+
|
9
|
+
start_time = Time.now
|
10
|
+
$runner.msg_count.times do
|
11
|
+
case $runner.encoding
|
12
|
+
when :string
|
13
|
+
pub.send(msg)
|
14
|
+
when :frame
|
15
|
+
pub.send_frame(ZMQ::Frame(msg))
|
16
|
+
when :message
|
17
|
+
m = ZMQ::Message.new
|
18
|
+
m.pushstr "header"
|
19
|
+
m.pushstr msg
|
20
|
+
m.pushstr "body"
|
21
|
+
pub.send_message(m)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Sent #{$runner.msg_count} messages in %ss ..." % (Time.now - start_time)
|
data/perf/push_pull.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ::Context.new
|
4
|
+
pull = ctx.socket(:PULL)
|
5
|
+
pull.connect($runner.endpoint)
|
6
|
+
|
7
|
+
messages, start_time = 0, nil
|
8
|
+
while (case $runner.encoding
|
9
|
+
when :string
|
10
|
+
pull.recv
|
11
|
+
when :frame
|
12
|
+
pull.recv_frame
|
13
|
+
when :message
|
14
|
+
pull.recv_message
|
15
|
+
end) do
|
16
|
+
start_time ||= Time.now
|
17
|
+
messages += 1
|
18
|
+
break if messages == $runner.process_msg_count
|
19
|
+
end
|
20
|
+
|
21
|
+
$runner.stats(start_time)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ::Context.new
|
4
|
+
push = ctx.socket(:PUSH);
|
5
|
+
push.bind($runner.endpoint);
|
6
|
+
|
7
|
+
msg = $runner.payload
|
8
|
+
|
9
|
+
start_time = Time.now
|
10
|
+
$runner.msg_count.times do
|
11
|
+
case $runner.encoding
|
12
|
+
when :string
|
13
|
+
push.send(msg)
|
14
|
+
when :frame
|
15
|
+
push.send_frame(ZMQ::Frame(msg))
|
16
|
+
when :message
|
17
|
+
m = ZMQ::Message.new
|
18
|
+
m.pushstr "header"
|
19
|
+
m.pushstr msg
|
20
|
+
m.pushstr "body"
|
21
|
+
push.send_message(m)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Sent #{$runner.msg_count} messages in %ss ..." % (Time.now - start_time)
|
data/perf/req_rep.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ::Context.new
|
4
|
+
req = ctx.socket(:REQ)
|
5
|
+
req.connect($runner.endpoint)
|
6
|
+
|
7
|
+
msg = $runner.payload
|
8
|
+
|
9
|
+
messages, start_time = 0, nil
|
10
|
+
while (case $runner.encoding
|
11
|
+
when :string
|
12
|
+
req.send(msg)
|
13
|
+
when :frame
|
14
|
+
req.send_frame(ZMQ::Frame(msg))
|
15
|
+
when :message
|
16
|
+
m = ZMQ::Message.new
|
17
|
+
m.pushstr "header"
|
18
|
+
m.pushstr msg
|
19
|
+
m.pushstr "body"
|
20
|
+
req.send_message(m)
|
21
|
+
end) do
|
22
|
+
start_time ||= Time.now
|
23
|
+
messages += 1
|
24
|
+
case $runner.encoding
|
25
|
+
when :string
|
26
|
+
req.recv
|
27
|
+
when :frame
|
28
|
+
req.recv_frame
|
29
|
+
when :message
|
30
|
+
req.recv_message
|
31
|
+
end
|
32
|
+
break if messages == $runner.msg_count
|
33
|
+
end
|
34
|
+
|
35
|
+
$runner.stats(start_time)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
ctx = ZMQ::Context.new
|
4
|
+
rep = ctx.socket(:REP);
|
5
|
+
rep.bind($runner.endpoint);
|
6
|
+
|
7
|
+
start_time = Time.now
|
8
|
+
$runner.msg_count.times do
|
9
|
+
msg = case $runner.encoding
|
10
|
+
when :string
|
11
|
+
rep.recv
|
12
|
+
when :frame
|
13
|
+
rep.recv_frame
|
14
|
+
when :message
|
15
|
+
rep.recv_message
|
16
|
+
end
|
17
|
+
|
18
|
+
case $runner.encoding
|
19
|
+
when :string
|
20
|
+
rep.send(msg)
|
21
|
+
when :frame
|
22
|
+
rep.send_frame(msg)
|
23
|
+
when :message
|
24
|
+
rep.send_message(msg)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
puts "Sent #{$runner.msg_count} messages in %ss ..." % (Time.now - start_time)
|