rbczmq 0.1

Sign up to get free protection for your applications and to get access to all the features.
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)