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.
Files changed (101) hide show
  1. data/.gitignore +23 -0
  2. data/.travis.yml +19 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +19 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +247 -0
  7. data/Rakefile +67 -0
  8. data/examples/loop.rb +109 -0
  9. data/examples/poller.rb +37 -0
  10. data/examples/pub_sub.rb +101 -0
  11. data/examples/push_pull.rb +104 -0
  12. data/examples/req_rep.rb +100 -0
  13. data/ext/czmq.tar.gz +0 -0
  14. data/ext/rbczmq/context.c +280 -0
  15. data/ext/rbczmq/context.h +26 -0
  16. data/ext/rbczmq/extconf.rb +138 -0
  17. data/ext/rbczmq/frame.c +401 -0
  18. data/ext/rbczmq/frame.h +24 -0
  19. data/ext/rbczmq/jruby.h +22 -0
  20. data/ext/rbczmq/loop.c +413 -0
  21. data/ext/rbczmq/loop.h +24 -0
  22. data/ext/rbczmq/message.c +620 -0
  23. data/ext/rbczmq/message.h +24 -0
  24. data/ext/rbczmq/poller.c +308 -0
  25. data/ext/rbczmq/poller.h +29 -0
  26. data/ext/rbczmq/pollitem.c +251 -0
  27. data/ext/rbczmq/pollitem.h +25 -0
  28. data/ext/rbczmq/rbczmq_ext.c +198 -0
  29. data/ext/rbczmq/rbczmq_ext.h +94 -0
  30. data/ext/rbczmq/rbczmq_prelude.h +22 -0
  31. data/ext/rbczmq/rubinius.h +24 -0
  32. data/ext/rbczmq/ruby18.h +43 -0
  33. data/ext/rbczmq/ruby19.h +15 -0
  34. data/ext/rbczmq/socket.c +1570 -0
  35. data/ext/rbczmq/socket.h +136 -0
  36. data/ext/rbczmq/timer.c +110 -0
  37. data/ext/rbczmq/timer.h +23 -0
  38. data/ext/zeromq.tar.gz +0 -0
  39. data/lib/rbczmq.rb +3 -0
  40. data/lib/zmq.rb +77 -0
  41. data/lib/zmq/context.rb +50 -0
  42. data/lib/zmq/default_handler.rb +16 -0
  43. data/lib/zmq/frame.rb +11 -0
  44. data/lib/zmq/handler.rb +76 -0
  45. data/lib/zmq/loop.rb +131 -0
  46. data/lib/zmq/message.rb +9 -0
  47. data/lib/zmq/poller.rb +22 -0
  48. data/lib/zmq/pollitem.rb +31 -0
  49. data/lib/zmq/socket.rb +125 -0
  50. data/lib/zmq/socket/dealer.rb +33 -0
  51. data/lib/zmq/socket/pair.rb +39 -0
  52. data/lib/zmq/socket/pub.rb +30 -0
  53. data/lib/zmq/socket/pull.rb +29 -0
  54. data/lib/zmq/socket/push.rb +32 -0
  55. data/lib/zmq/socket/rep.rb +37 -0
  56. data/lib/zmq/socket/req.rb +37 -0
  57. data/lib/zmq/socket/router.rb +38 -0
  58. data/lib/zmq/socket/sub.rb +27 -0
  59. data/lib/zmq/timer.rb +12 -0
  60. data/lib/zmq/version.rb +5 -0
  61. data/perf/pair.rb +7 -0
  62. data/perf/pair/local.rb +22 -0
  63. data/perf/pair/remote.rb +25 -0
  64. data/perf/pub_sub.rb +7 -0
  65. data/perf/pub_sub/local.rb +22 -0
  66. data/perf/pub_sub/remote.rb +25 -0
  67. data/perf/push_pull.rb +7 -0
  68. data/perf/push_pull/local.rb +21 -0
  69. data/perf/push_pull/remote.rb +25 -0
  70. data/perf/req_rep.rb +7 -0
  71. data/perf/req_rep/local.rb +35 -0
  72. data/perf/req_rep/remote.rb +28 -0
  73. data/perf/runner.rb +142 -0
  74. data/rbczmq.gemspec +22 -0
  75. data/test/helper.rb +21 -0
  76. data/test/socket/test_dealer_socket.rb +14 -0
  77. data/test/socket/test_pair_socket.rb +24 -0
  78. data/test/socket/test_pair_sockets.rb +74 -0
  79. data/test/socket/test_pub_socket.rb +17 -0
  80. data/test/socket/test_pub_sub_sockets.rb +87 -0
  81. data/test/socket/test_pull_socket.rb +17 -0
  82. data/test/socket/test_push_pull_sockets.rb +81 -0
  83. data/test/socket/test_push_socket.rb +17 -0
  84. data/test/socket/test_rep_socket.rb +25 -0
  85. data/test/socket/test_req_rep_sockets.rb +42 -0
  86. data/test/socket/test_req_socket.rb +27 -0
  87. data/test/socket/test_router_socket.rb +14 -0
  88. data/test/socket/test_routing.rb +66 -0
  89. data/test/socket/test_sub_socket.rb +17 -0
  90. data/test/test_context.rb +86 -0
  91. data/test/test_frame.rb +78 -0
  92. data/test/test_handler.rb +28 -0
  93. data/test/test_loop.rb +252 -0
  94. data/test/test_message.rb +201 -0
  95. data/test/test_poller.rb +154 -0
  96. data/test/test_pollitem.rb +78 -0
  97. data/test/test_socket.rb +403 -0
  98. data/test/test_threading.rb +34 -0
  99. data/test/test_timer.rb +37 -0
  100. data/test/test_zmq.rb +62 -0
  101. 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
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module ZMQ
4
+ VERSION = "0.1"
5
+ end
data/perf/pair.rb ADDED
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift('.')
4
+ require File.join(File.dirname(__FILE__), 'runner')
5
+
6
+ $runner = ThreadRunner.new(ENV["MSG_COUNT"], ENV["MSG_SIZE"], ENV["MSG_ENCODING"])
7
+ $runner.start(:pair)
@@ -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)
@@ -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,7 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift('.')
4
+ require File.join(File.dirname(__FILE__), 'runner')
5
+
6
+ $runner = ProcessRunner.new(ENV["MSG_COUNT"], ENV["MSG_SIZE"], ENV["MSG_ENCODING"], ENV["PROCESSES"])
7
+ $runner.start(:pub_sub)
@@ -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,7 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift('.')
4
+ require File.join(File.dirname(__FILE__), 'runner')
5
+
6
+ $runner = ProcessRunner.new(ENV["MSG_COUNT"], ENV["MSG_SIZE"], ENV["MSG_ENCODING"], ENV["PROCESSES"])
7
+ $runner.start(:push_pull)
@@ -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,7 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift('.')
4
+ require File.join(File.dirname(__FILE__), 'runner')
5
+
6
+ $runner = ProcessRunner.new(ENV["MSG_COUNT"], ENV["MSG_SIZE"], ENV["MSG_ENCODING"])
7
+ $runner.start(:req_rep)
@@ -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)