rbczmq 0.9 → 1.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/CHANGELOG.rdoc +6 -0
- data/README.rdoc +2 -2
- data/ext/czmq.tar.gz +0 -0
- data/ext/libzmq.tar.gz +0 -0
- data/ext/rbczmq/context.c +6 -0
- data/ext/rbczmq/extconf.rb +0 -3
- data/ext/rbczmq/rbczmq_ext.c +12 -0
- data/ext/rbczmq/rbczmq_ext.h +0 -11
- data/ext/rbczmq/socket.c +283 -6
- data/ext/rbczmq/socket.h +20 -0
- data/ext/zeromq.tar.gz +0 -0
- data/lib/zmq.rb +15 -0
- data/lib/zmq/monitor.rb +33 -0
- data/lib/zmq/version.rb +1 -1
- data/test/test_context.rb +2 -1
- data/test/test_monitoring.rb +47 -0
- data/test/test_socket.rb +55 -22
- metadata +8 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 1.0 (November 24, 2012)
|
4
|
+
* Supports ZeroMQ 3.2.2 (first stable and backwards compatible 3.x release)
|
5
|
+
* Monitoring API for handling socket state changes / events
|
6
|
+
* Support for raw TCP sockets (ROUTER sockets only)
|
7
|
+
* Not dependent on libuuid anymore
|
8
|
+
|
3
9
|
== 0.9 (August 18, 2012)
|
4
10
|
* Sockets now record and show all endpoints
|
5
11
|
* Support connect_all for SRV managed topologies
|
data/README.rdoc
CHANGED
@@ -224,10 +224,10 @@ Running tests
|
|
224
224
|
|
225
225
|
OS X notes:
|
226
226
|
|
227
|
-
If you are installing the package on a new mack ensure you have libtool and autoconf
|
227
|
+
If you are installing the package on a new mack ensure you have libtool and autoconf installed.
|
228
228
|
You can get those with brew packaging system:
|
229
229
|
|
230
|
-
brew
|
230
|
+
brew install libtool autoconf automake
|
231
231
|
|
232
232
|
== TODO
|
233
233
|
|
data/ext/czmq.tar.gz
CHANGED
Binary file
|
data/ext/libzmq.tar.gz
ADDED
Binary file
|
data/ext/rbczmq/context.c
CHANGED
@@ -190,6 +190,7 @@ static VALUE rb_czmq_ctx_hwm(VALUE obj)
|
|
190
190
|
errno = 0;
|
191
191
|
int wm;
|
192
192
|
ZmqGetContext(obj);
|
193
|
+
rb_warn("Deprecated method ZMQ::Context#hwm, does nothing - to be removed after 2013/05/14");
|
193
194
|
return INT2FIX(zctx_hwm(ctx->ctx));
|
194
195
|
}
|
195
196
|
|
@@ -211,6 +212,7 @@ static VALUE rb_czmq_ctx_set_hwm(VALUE obj, VALUE hwm)
|
|
211
212
|
int wm;
|
212
213
|
ZmqGetContext(obj);
|
213
214
|
Check_Type(hwm, T_FIXNUM);
|
215
|
+
rb_warn("Deprecated method ZMQ::Context#hwm=, does nothing - to be removed after 2013/05/14");
|
214
216
|
wm = FIX2INT(hwm);
|
215
217
|
if (wm < 0) rb_raise(rb_eZmqError, "negative HWM values is not supported.");
|
216
218
|
zctx_set_hwm(ctx->ctx, wm);
|
@@ -303,6 +305,10 @@ static VALUE rb_czmq_ctx_socket(VALUE obj, VALUE type)
|
|
303
305
|
sock->state = ZMQ_SOCKET_PENDING;
|
304
306
|
sock->endpoints = rb_ary_new();
|
305
307
|
sock->thread = rb_thread_current();
|
308
|
+
sock->context = obj;
|
309
|
+
sock->monitor_endpoint = Qnil;
|
310
|
+
sock->monitor_handler = Qnil;
|
311
|
+
sock->monitor_thread = Qnil;
|
306
312
|
rb_obj_call_init(socket, 0, NULL);
|
307
313
|
return socket;
|
308
314
|
}
|
data/ext/rbczmq/extconf.rb
CHANGED
@@ -30,9 +30,6 @@ czmq_include_path = czmq_path + 'include'
|
|
30
30
|
|
31
31
|
# Fail early if we don't meet the following dependencies.
|
32
32
|
|
33
|
-
# Present on OS X and BSD systems, package install required on Linux
|
34
|
-
fail("package uuid-dev required (apt-get install uuid-dev)") unless have_header('uuid/uuid.h')
|
35
|
-
|
36
33
|
# Courtesy of EventMachine and @tmm1
|
37
34
|
def check_libs libs = [], fatal = false
|
38
35
|
libs.all? { |lib| have_library(lib) || (abort("could not find library: #{lib}") if fatal) }
|
data/ext/rbczmq/rbczmq_ext.c
CHANGED
@@ -197,6 +197,18 @@ void Init_rbczmq_ext()
|
|
197
197
|
rb_define_const(rb_mZmq, "ETERM", INT2NUM(ETERM));
|
198
198
|
rb_define_const(rb_mZmq, "EMTHREAD", INT2NUM(EMTHREAD));
|
199
199
|
|
200
|
+
rb_define_const(rb_mZmq, "EVENT_CONNECTED", INT2NUM(ZMQ_EVENT_CONNECTED));
|
201
|
+
rb_define_const(rb_mZmq, "EVENT_CONNECT_DELAYED", INT2NUM(ZMQ_EVENT_CONNECT_DELAYED));
|
202
|
+
rb_define_const(rb_mZmq, "EVENT_CONNECT_RETRIED", INT2NUM(ZMQ_EVENT_CONNECT_RETRIED));
|
203
|
+
rb_define_const(rb_mZmq, "EVENT_LISTENING", INT2NUM(ZMQ_EVENT_LISTENING));
|
204
|
+
rb_define_const(rb_mZmq, "EVENT_BIND_FAILED", INT2NUM(ZMQ_EVENT_BIND_FAILED));
|
205
|
+
rb_define_const(rb_mZmq, "EVENT_ACCEPTED", INT2NUM(ZMQ_EVENT_ACCEPTED));
|
206
|
+
rb_define_const(rb_mZmq, "EVENT_ACCEPT_FAILED", INT2NUM(ZMQ_EVENT_ACCEPT_FAILED));
|
207
|
+
rb_define_const(rb_mZmq, "EVENT_CLOSED", INT2NUM(ZMQ_EVENT_CLOSED));
|
208
|
+
rb_define_const(rb_mZmq, "EVENT_CLOSE_FAILED", INT2NUM(ZMQ_EVENT_CLOSE_FAILED));
|
209
|
+
rb_define_const(rb_mZmq, "EVENT_DISCONNECTED", INT2NUM(ZMQ_EVENT_DISCONNECTED));
|
210
|
+
rb_define_const(rb_mZmq, "EVENT_ALL", INT2NUM(ZMQ_EVENT_ALL));
|
211
|
+
|
200
212
|
_init_rb_czmq_context();
|
201
213
|
_init_rb_czmq_socket();
|
202
214
|
_init_rb_czmq_frame();
|
data/ext/rbczmq/rbczmq_ext.h
CHANGED
@@ -92,15 +92,4 @@ static inline char *rb_czmq_formatted_current_time()
|
|
92
92
|
return formatted;
|
93
93
|
}
|
94
94
|
|
95
|
-
struct nogvl_device_args {
|
96
|
-
int type;
|
97
|
-
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
|
98
|
-
zctx_t *ctx;
|
99
|
-
#endif
|
100
|
-
zmq_sock_wrapper *in;
|
101
|
-
zmq_sock_wrapper *out;
|
102
|
-
int rc;
|
103
|
-
};
|
104
|
-
typedef struct nogvl_device_args nogvl_device_args_t;
|
105
|
-
|
106
95
|
#endif
|
data/ext/rbczmq/socket.c
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
#include "rbczmq_ext.h"
|
2
2
|
|
3
|
+
VALUE intern_on_connected;
|
4
|
+
VALUE intern_on_connect_delayed;
|
5
|
+
VALUE intern_on_connect_retried;
|
6
|
+
VALUE intern_on_listening;
|
7
|
+
VALUE intern_on_bind_failed;
|
8
|
+
VALUE intern_on_accepted;
|
9
|
+
VALUE intern_on_accept_failed;
|
10
|
+
VALUE intern_on_closed;
|
11
|
+
VALUE intern_on_close_failed;
|
12
|
+
VALUE intern_on_disconnected;
|
13
|
+
|
3
14
|
/*
|
4
15
|
* :nodoc:
|
5
16
|
* Destroy the socket while the GIL is released - may block depending on socket linger value.
|
@@ -42,6 +53,10 @@ void rb_czmq_mark_sock(void *ptr)
|
|
42
53
|
zclock_log ("I: %s socket %p, context %p: GC mark", zsocket_type_str(sock->socket), sock, sock->ctx);
|
43
54
|
rb_gc_mark(sock->endpoints);
|
44
55
|
rb_gc_mark(sock->thread);
|
56
|
+
rb_gc_mark(sock->context);
|
57
|
+
rb_gc_mark(sock->monitor_endpoint);
|
58
|
+
rb_gc_mark(sock->monitor_handler);
|
59
|
+
rb_gc_mark(sock->monitor_thread);
|
45
60
|
}
|
46
61
|
}
|
47
62
|
|
@@ -788,6 +803,8 @@ static VALUE rb_czmq_socket_recv_message(VALUE obj)
|
|
788
803
|
return rb_czmq_alloc_message(message);
|
789
804
|
}
|
790
805
|
|
806
|
+
#if ZMQ_VERSION_MAJOR == 2
|
807
|
+
|
791
808
|
/*
|
792
809
|
* call-seq:
|
793
810
|
* sock.hwm => Fixnum
|
@@ -866,6 +883,89 @@ static VALUE rb_czmq_socket_set_opt_swap(VALUE obj, VALUE value)
|
|
866
883
|
zmq_sock_wrapper *sock = NULL;
|
867
884
|
ZmqSetSockOpt(obj, zsocket_set_swap, "SWAP", value);
|
868
885
|
}
|
886
|
+
#endif
|
887
|
+
|
888
|
+
#if ZMQ_VERSION_MAJOR == 3
|
889
|
+
/*
|
890
|
+
* call-seq:
|
891
|
+
* sock.sndhwm => Fixnum
|
892
|
+
*
|
893
|
+
* Returns the socket send HWM (High Water Mark) value.
|
894
|
+
*
|
895
|
+
* === Examples
|
896
|
+
* ctx = ZMQ::Context.new
|
897
|
+
* sock = ctx.socket(:REP)
|
898
|
+
* sock.sndhwm => 0
|
899
|
+
*
|
900
|
+
*/
|
901
|
+
|
902
|
+
static VALUE rb_czmq_socket_opt_sndhwm(VALUE obj)
|
903
|
+
{
|
904
|
+
zmq_sock_wrapper *sock = NULL;
|
905
|
+
GetZmqSocket(obj);
|
906
|
+
return INT2NUM(zsocket_sndhwm(sock->socket));
|
907
|
+
}
|
908
|
+
|
909
|
+
/*
|
910
|
+
* call-seq:
|
911
|
+
* sock.sndhwm = 100 => nil
|
912
|
+
*
|
913
|
+
* Sets the socket send HWM (High Water Mark() value.
|
914
|
+
*
|
915
|
+
* === Examples
|
916
|
+
* ctx = ZMQ::Context.new
|
917
|
+
* sock = ctx.socket(:REP)
|
918
|
+
* sock.sndhwm = 100 => nil
|
919
|
+
* sock.sndhwm => 100
|
920
|
+
*
|
921
|
+
*/
|
922
|
+
|
923
|
+
static VALUE rb_czmq_socket_set_opt_sndhwm(VALUE obj, VALUE value)
|
924
|
+
{
|
925
|
+
zmq_sock_wrapper *sock = NULL;
|
926
|
+
ZmqSetSockOpt(obj, zsocket_set_sndhwm, "SNDHWM", value);
|
927
|
+
}
|
928
|
+
|
929
|
+
/*
|
930
|
+
* call-seq:
|
931
|
+
* sock.rcvhwm => Fixnum
|
932
|
+
*
|
933
|
+
* Returns the socket receive HWM (High Water Mark) value.
|
934
|
+
*
|
935
|
+
* === Examples
|
936
|
+
* ctx = ZMQ::Context.new
|
937
|
+
* sock = ctx.socket(:REP)
|
938
|
+
* sock.sndhwm => 0
|
939
|
+
*
|
940
|
+
*/
|
941
|
+
|
942
|
+
static VALUE rb_czmq_socket_opt_rcvhwm(VALUE obj)
|
943
|
+
{
|
944
|
+
zmq_sock_wrapper *sock = NULL;
|
945
|
+
GetZmqSocket(obj);
|
946
|
+
return INT2NUM(zsocket_rcvhwm(sock->socket));
|
947
|
+
}
|
948
|
+
|
949
|
+
/*
|
950
|
+
* call-seq:
|
951
|
+
* sock.rcvhwm = 100 => nil
|
952
|
+
*
|
953
|
+
* Sets the socket receive HWM (High Water Mark() value.
|
954
|
+
*
|
955
|
+
* === Examples
|
956
|
+
* ctx = ZMQ::Context.new
|
957
|
+
* sock = ctx.socket(:REP)
|
958
|
+
* sock.rcvhwm = 100 => nil
|
959
|
+
* sock.rcvhwm => 100
|
960
|
+
*
|
961
|
+
*/
|
962
|
+
|
963
|
+
static VALUE rb_czmq_socket_set_opt_rcvhwm(VALUE obj, VALUE value)
|
964
|
+
{
|
965
|
+
zmq_sock_wrapper *sock = NULL;
|
966
|
+
ZmqSetSockOpt(obj, zsocket_set_rcvhwm, "RCVHWM", value);
|
967
|
+
}
|
968
|
+
#endif
|
869
969
|
|
870
970
|
/*
|
871
971
|
* call-seq:
|
@@ -984,6 +1084,7 @@ static VALUE rb_czmq_socket_set_opt_recovery_ivl(VALUE obj, VALUE value)
|
|
984
1084
|
ZmqSetSockOpt(obj, zsocket_set_recovery_ivl, "RECOVERY_IVL", value);
|
985
1085
|
}
|
986
1086
|
|
1087
|
+
#if ZMQ_VERSION_MAJOR == 2
|
987
1088
|
/*
|
988
1089
|
* call-seq:
|
989
1090
|
* sock.recovery_ivl_msec => Fixnum
|
@@ -1061,6 +1162,7 @@ static VALUE rb_czmq_socket_set_opt_mcast_loop(VALUE obj, VALUE value)
|
|
1061
1162
|
zmq_sock_wrapper *sock = NULL;
|
1062
1163
|
ZmqSetBooleanSockOpt(obj, zsocket_set_mcast_loop, "MCAST_LOOP", value);
|
1063
1164
|
}
|
1165
|
+
#endif
|
1064
1166
|
|
1065
1167
|
/*
|
1066
1168
|
* call-seq:
|
@@ -1485,6 +1587,155 @@ static VALUE rb_czmq_socket_set_opt_sndtimeo(VALUE obj, VALUE value)
|
|
1485
1587
|
ZmqSetSockOpt(obj, zsocket_set_sndtimeo, "SNDTIMEO", value);
|
1486
1588
|
}
|
1487
1589
|
|
1590
|
+
#if defined (ZMQ_ROUTER_RAW)
|
1591
|
+
/*
|
1592
|
+
* call-seq:
|
1593
|
+
* sock.raw = true => nil
|
1594
|
+
*
|
1595
|
+
* Define this as a RAW socket - applicable to ROUTER sockets only.
|
1596
|
+
*
|
1597
|
+
* === Examples
|
1598
|
+
* ctx = ZMQ::Context.new
|
1599
|
+
* sock = ctx.socket(:ROUTER)
|
1600
|
+
* sock.router = 200 => nil
|
1601
|
+
*
|
1602
|
+
*/
|
1603
|
+
|
1604
|
+
static VALUE rb_czmq_socket_set_opt_raw(VALUE obj, VALUE value)
|
1605
|
+
{
|
1606
|
+
zmq_sock_wrapper *sock = NULL;
|
1607
|
+
ZmqSetBooleanSockOpt(obj, zsocket_set_router_raw, "ROUTER_RAW", value);
|
1608
|
+
}
|
1609
|
+
#endif
|
1610
|
+
|
1611
|
+
/*
|
1612
|
+
* :nodoc:
|
1613
|
+
* Receives a monitoring event message while the GIL is released.
|
1614
|
+
*
|
1615
|
+
*/
|
1616
|
+
|
1617
|
+
static VALUE rb_czmq_nogvl_monitor_recv(void *ptr)
|
1618
|
+
{
|
1619
|
+
struct nogvl_monitor_recv_args *args = ptr;
|
1620
|
+
int rc;
|
1621
|
+
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
1622
|
+
rc = zmq_recvmsg (args->socket, &args->msg, 0);
|
1623
|
+
#else
|
1624
|
+
int fd;
|
1625
|
+
size_t option_len = sizeof (int);
|
1626
|
+
zmq_getsockopt (args->socket, ZMQ_FD, &fd, &option_len);
|
1627
|
+
try_readable:
|
1628
|
+
if ((zsocket_events(args->socket) & ZMQ_POLLIN) == ZMQ_POLLIN) {
|
1629
|
+
rc = zmq_recvmsg (args->socket, &args->msg, 0);
|
1630
|
+
} else {
|
1631
|
+
rb_thread_wait_fd(fd);
|
1632
|
+
goto try_readable;
|
1633
|
+
}
|
1634
|
+
#endif
|
1635
|
+
return (VALUE)rc;
|
1636
|
+
}
|
1637
|
+
|
1638
|
+
/*
|
1639
|
+
* :nodoc:
|
1640
|
+
* Runs with the context of a new Ruby thread and spawns a PAIR socket for handling monitoring events
|
1641
|
+
*
|
1642
|
+
*/
|
1643
|
+
|
1644
|
+
static VALUE rb_czmq_socket_monitor_thread(void *arg)
|
1645
|
+
{
|
1646
|
+
zmq_event_t event;
|
1647
|
+
struct nogvl_monitor_recv_args args;
|
1648
|
+
int rc;
|
1649
|
+
zmq_sock_wrapper *sock = (zmq_sock_wrapper *)arg;
|
1650
|
+
|
1651
|
+
void *s = zsocket_new (sock->ctx, ZMQ_PAIR);
|
1652
|
+
assert (s);
|
1653
|
+
|
1654
|
+
rc = zmq_connect (s, StringValueCStr(sock->monitor_endpoint));
|
1655
|
+
assert (rc == 0);
|
1656
|
+
|
1657
|
+
THREAD_PASS;
|
1658
|
+
|
1659
|
+
while (1) {
|
1660
|
+
args.socket = s;
|
1661
|
+
zmq_msg_init (&args.msg);
|
1662
|
+
rc = (int)rb_thread_blocking_region(rb_czmq_nogvl_monitor_recv, (void *)&args, RUBY_UBF_IO, 0);
|
1663
|
+
if (rc == -1 && (zmq_errno() == ETERM || zmq_errno() == ENOTSOCK || zmq_errno() == EINTR)) break;
|
1664
|
+
assert (rc != -1);
|
1665
|
+
memcpy (&event, zmq_msg_data (&args.msg), sizeof (event));
|
1666
|
+
switch (event.event) {
|
1667
|
+
case ZMQ_EVENT_CONNECTED: rb_funcall(sock->monitor_handler, intern_on_connected, 2, rb_str_new2(event.data.connected.addr), INT2FIX(event.data.connected.fd));
|
1668
|
+
break;
|
1669
|
+
case ZMQ_EVENT_CONNECT_DELAYED: rb_funcall(sock->monitor_handler, intern_on_connect_delayed, 2, rb_str_new2(event.data.connect_delayed.addr), INT2FIX(event.data.connect_delayed.err));
|
1670
|
+
break;
|
1671
|
+
case ZMQ_EVENT_CONNECT_RETRIED: rb_funcall(sock->monitor_handler, intern_on_connect_retried, 2, rb_str_new2(event.data.connect_retried.addr), INT2FIX(event.data.connect_retried.interval));
|
1672
|
+
break;
|
1673
|
+
case ZMQ_EVENT_LISTENING: rb_funcall(sock->monitor_handler, intern_on_listening, 2, rb_str_new2(event.data.listening.addr), INT2FIX(event.data.listening.fd));
|
1674
|
+
break;
|
1675
|
+
case ZMQ_EVENT_BIND_FAILED: rb_funcall(sock->monitor_handler, intern_on_bind_failed, 2, rb_str_new2(event.data.bind_failed.addr), INT2FIX(event.data.bind_failed.err));
|
1676
|
+
break;
|
1677
|
+
case ZMQ_EVENT_ACCEPTED: rb_funcall(sock->monitor_handler, intern_on_accepted, 2, rb_str_new2(event.data.accepted.addr), INT2FIX(event.data.accepted.fd));
|
1678
|
+
break;
|
1679
|
+
case ZMQ_EVENT_ACCEPT_FAILED: rb_funcall(sock->monitor_handler, intern_on_accept_failed, 2, rb_str_new2(event.data.accept_failed.addr), INT2FIX(event.data.accept_failed.err));
|
1680
|
+
break;
|
1681
|
+
case ZMQ_EVENT_CLOSE_FAILED: rb_funcall(sock->monitor_handler, intern_on_close_failed, 2, rb_str_new2(event.data.close_failed.addr), INT2FIX(event.data.close_failed.err));
|
1682
|
+
break;
|
1683
|
+
case ZMQ_EVENT_CLOSED: rb_funcall(sock->monitor_handler, intern_on_closed, 2, rb_str_new2(event.data.closed.addr), INT2FIX(event.data.closed.fd));
|
1684
|
+
break;
|
1685
|
+
case ZMQ_EVENT_DISCONNECTED: rb_funcall(sock->monitor_handler, intern_on_disconnected, 2, rb_str_new2(event.data.disconnected.addr), INT2FIX(event.data.disconnected.fd));
|
1686
|
+
break;
|
1687
|
+
}
|
1688
|
+
}
|
1689
|
+
zmq_close (s);
|
1690
|
+
return Qnil;
|
1691
|
+
}
|
1692
|
+
|
1693
|
+
/*
|
1694
|
+
* call-seq:
|
1695
|
+
* sock.monitor("inproc://monitoring", callback, events) => nil
|
1696
|
+
*
|
1697
|
+
* Registers a monitoring callback for this socket
|
1698
|
+
*
|
1699
|
+
* === Examples
|
1700
|
+
* ctx = ZMQ::Context.new
|
1701
|
+
* rep = ctx.socket(:REP)
|
1702
|
+
* rep.monitor("inproc://monitoring.rep", RepMonitor)
|
1703
|
+
* req = ctx.socket(:REQ)
|
1704
|
+
* req.monitor("inproc://monitoring.req", ReqMonitor, ZMQ_EVENT_DISCONNECTED)
|
1705
|
+
* rep.bind("tcp://127.0.0.1:5331")
|
1706
|
+
* rep.bind("tcp://127.0.0.1:5332")
|
1707
|
+
*
|
1708
|
+
*/
|
1709
|
+
|
1710
|
+
static VALUE rb_czmq_socket_monitor(int argc, VALUE *argv, VALUE obj)
|
1711
|
+
{
|
1712
|
+
VALUE endpoint;
|
1713
|
+
VALUE handler;
|
1714
|
+
VALUE events;
|
1715
|
+
int rc;
|
1716
|
+
zmq_sock_wrapper *sock = NULL;
|
1717
|
+
GetZmqSocket(obj);
|
1718
|
+
ZmqSockGuardCrossThread(sock);
|
1719
|
+
rb_scan_args(argc, argv, "12", &endpoint, &handler, &events);
|
1720
|
+
Check_Type(endpoint, T_STRING);
|
1721
|
+
if (NIL_P(events))
|
1722
|
+
events = rb_const_get_at(rb_mZmq, rb_intern("EVENT_ALL"));
|
1723
|
+
if (NIL_P(handler)) {
|
1724
|
+
handler = rb_class_new_instance(0, NULL, rb_const_get_at(rb_mZmq, rb_intern("Monitor")));
|
1725
|
+
}
|
1726
|
+
Check_Type(events, T_FIXNUM);
|
1727
|
+
rc = zmq_socket_monitor(sock->socket, StringValueCStr(endpoint), NUM2INT(events));
|
1728
|
+
if (rc == 0) {
|
1729
|
+
sock->monitor_endpoint = endpoint;
|
1730
|
+
sock->monitor_handler = handler;
|
1731
|
+
sock->monitor_thread = rb_thread_create(rb_czmq_socket_monitor_thread, (void*)sock);
|
1732
|
+
rb_thread_run(sock->monitor_thread);
|
1733
|
+
return Qtrue;
|
1734
|
+
} else {
|
1735
|
+
return Qfalse;
|
1736
|
+
}
|
1737
|
+
}
|
1738
|
+
|
1488
1739
|
void _init_rb_czmq_socket()
|
1489
1740
|
{
|
1490
1741
|
rb_cZmqSocket = rb_define_class_under(rb_mZmq, "Socket", rb_cObject);
|
@@ -1498,6 +1749,17 @@ void _init_rb_czmq_socket()
|
|
1498
1749
|
rb_cZmqReqSocket = rb_define_class_under(rb_cZmqSocket, "Req", rb_cZmqSocket);;
|
1499
1750
|
rb_cZmqPairSocket = rb_define_class_under(rb_cZmqSocket, "Pair", rb_cZmqSocket);;
|
1500
1751
|
|
1752
|
+
intern_on_connected = rb_intern("on_connected");
|
1753
|
+
intern_on_connect_delayed = rb_intern("on_connect_delayed");
|
1754
|
+
intern_on_connect_retried = rb_intern("on_connect_retried");
|
1755
|
+
intern_on_listening = rb_intern("on_listening");
|
1756
|
+
intern_on_bind_failed = rb_intern("on_bind_failed");
|
1757
|
+
intern_on_accepted = rb_intern("on_accepted");
|
1758
|
+
intern_on_accept_failed = rb_intern("on_accept_failed");
|
1759
|
+
intern_on_closed = rb_intern("on_closed");
|
1760
|
+
intern_on_close_failed = rb_intern("on_close_failed");
|
1761
|
+
intern_on_disconnected = rb_intern("on_disconnected");
|
1762
|
+
|
1501
1763
|
rb_define_const(rb_cZmqSocket, "PENDING", INT2NUM(ZMQ_SOCKET_PENDING));
|
1502
1764
|
rb_define_const(rb_cZmqSocket, "BOUND", INT2NUM(ZMQ_SOCKET_BOUND));
|
1503
1765
|
rb_define_const(rb_cZmqSocket, "CONNECTED", INT2NUM(ZMQ_SOCKET_CONNECTED));
|
@@ -1520,20 +1782,34 @@ void _init_rb_czmq_socket()
|
|
1520
1782
|
rb_define_method(rb_cZmqSocket, "recv_frame_nonblock", rb_czmq_socket_recv_frame_nonblock, 0);
|
1521
1783
|
rb_define_method(rb_cZmqSocket, "recv_message", rb_czmq_socket_recv_message, 0);
|
1522
1784
|
|
1523
|
-
|
1524
|
-
rb_define_method(rb_cZmqSocket, "hwm=", rb_czmq_socket_set_opt_hwm, 1);
|
1785
|
+
#if ZMQ_VERSION_MAJOR == 2
|
1525
1786
|
rb_define_method(rb_cZmqSocket, "swap", rb_czmq_socket_opt_swap, 0);
|
1526
1787
|
rb_define_method(rb_cZmqSocket, "swap=", rb_czmq_socket_set_opt_swap, 1);
|
1788
|
+
rb_define_method(rb_cZmqSocket, "recovery_ivl_msec", rb_czmq_socket_opt_recovery_ivl_msec, 0);
|
1789
|
+
rb_define_method(rb_cZmqSocket, "recovery_ivl_msec=", rb_czmq_socket_set_opt_recovery_ivl_msec, 1);
|
1790
|
+
rb_define_method(rb_cZmqSocket, "mcast_loop?", rb_czmq_socket_opt_mcast_loop, 0);
|
1791
|
+
rb_define_method(rb_cZmqSocket, "mcast_loop=", rb_czmq_socket_set_opt_mcast_loop, 1);
|
1792
|
+
rb_define_method(rb_cZmqSocket, "hwm", rb_czmq_socket_opt_hwm, 0);
|
1793
|
+
rb_define_method(rb_cZmqSocket, "hwm=", rb_czmq_socket_set_opt_hwm, 1);
|
1794
|
+
#endif
|
1795
|
+
|
1796
|
+
#if ZMQ_VERSION_MAJOR == 3
|
1797
|
+
rb_define_method(rb_cZmqSocket, "sndhwm", rb_czmq_socket_opt_sndhwm, 0);
|
1798
|
+
rb_define_method(rb_cZmqSocket, "sndhwm=", rb_czmq_socket_set_opt_sndhwm, 1);
|
1799
|
+
rb_define_method(rb_cZmqSocket, "rcvhwm", rb_czmq_socket_opt_rcvhwm, 0);
|
1800
|
+
rb_define_method(rb_cZmqSocket, "rcvhwm=", rb_czmq_socket_set_opt_rcvhwm, 1);
|
1801
|
+
|
1802
|
+
#if defined (ZMQ_ROUTER_RAW)
|
1803
|
+
rb_define_method(rb_cZmqSocket, "raw=", rb_czmq_socket_set_opt_raw, 1);
|
1804
|
+
#endif
|
1805
|
+
#endif
|
1806
|
+
|
1527
1807
|
rb_define_method(rb_cZmqSocket, "affinity", rb_czmq_socket_opt_affinity, 0);
|
1528
1808
|
rb_define_method(rb_cZmqSocket, "affinity=", rb_czmq_socket_set_opt_affinity, 1);
|
1529
1809
|
rb_define_method(rb_cZmqSocket, "rate", rb_czmq_socket_opt_rate, 0);
|
1530
1810
|
rb_define_method(rb_cZmqSocket, "rate=", rb_czmq_socket_set_opt_rate, 1);
|
1531
1811
|
rb_define_method(rb_cZmqSocket, "recovery_ivl", rb_czmq_socket_opt_recovery_ivl, 0);
|
1532
1812
|
rb_define_method(rb_cZmqSocket, "recovery_ivl=", rb_czmq_socket_set_opt_recovery_ivl, 1);
|
1533
|
-
rb_define_method(rb_cZmqSocket, "recovery_ivl_msec", rb_czmq_socket_opt_recovery_ivl_msec, 0);
|
1534
|
-
rb_define_method(rb_cZmqSocket, "recovery_ivl_msec=", rb_czmq_socket_set_opt_recovery_ivl_msec, 1);
|
1535
|
-
rb_define_method(rb_cZmqSocket, "mcast_loop?", rb_czmq_socket_opt_mcast_loop, 0);
|
1536
|
-
rb_define_method(rb_cZmqSocket, "mcast_loop=", rb_czmq_socket_set_opt_mcast_loop, 1);
|
1537
1813
|
rb_define_method(rb_cZmqSocket, "sndbuf", rb_czmq_socket_opt_sndbuf, 0);
|
1538
1814
|
rb_define_method(rb_cZmqSocket, "sndbuf=", rb_czmq_socket_set_opt_sndbuf, 1);
|
1539
1815
|
rb_define_method(rb_cZmqSocket, "rcvbuf", rb_czmq_socket_opt_rcvbuf, 0);
|
@@ -1555,4 +1831,5 @@ void _init_rb_czmq_socket()
|
|
1555
1831
|
rb_define_method(rb_cZmqSocket, "rcvtimeo=", rb_czmq_socket_set_opt_rcvtimeo, 1);
|
1556
1832
|
rb_define_method(rb_cZmqSocket, "sndtimeo", rb_czmq_socket_opt_sndtimeo, 0);
|
1557
1833
|
rb_define_method(rb_cZmqSocket, "sndtimeo=", rb_czmq_socket_set_opt_sndtimeo, 1);
|
1834
|
+
rb_define_method(rb_cZmqSocket, "monitor", rb_czmq_socket_monitor, -1);
|
1558
1835
|
}
|
data/ext/rbczmq/socket.h
CHANGED
@@ -22,6 +22,10 @@ typedef struct {
|
|
22
22
|
#endif
|
23
23
|
VALUE endpoints;
|
24
24
|
VALUE thread;
|
25
|
+
VALUE context;
|
26
|
+
VALUE monitor_endpoint;
|
27
|
+
VALUE monitor_handler;
|
28
|
+
VALUE monitor_thread;
|
25
29
|
} zmq_sock_wrapper;
|
26
30
|
|
27
31
|
#define ZmqAssertSocket(obj) ZmqAssertType(obj, rb_cZmqSocket, "ZMQ::Socket")
|
@@ -122,11 +126,27 @@ struct nogvl_recv_args {
|
|
122
126
|
zmq_sock_wrapper *socket;
|
123
127
|
};
|
124
128
|
|
129
|
+
struct nogvl_monitor_recv_args {
|
130
|
+
void *socket;
|
131
|
+
zmq_msg_t msg;
|
132
|
+
};
|
133
|
+
|
125
134
|
struct nogvl_conn_args {
|
126
135
|
zmq_sock_wrapper *socket;
|
127
136
|
char *endpoint;
|
128
137
|
};
|
129
138
|
|
139
|
+
extern VALUE intern_on_connected;
|
140
|
+
extern VALUE intern_on_connect_delayed;
|
141
|
+
extern VALUE intern_on_connect_retried;
|
142
|
+
extern VALUE intern_on_listening;
|
143
|
+
extern VALUE intern_on_bind_failed;
|
144
|
+
extern VALUE intern_on_accepted;
|
145
|
+
extern VALUE intern_on_accept_failed;
|
146
|
+
extern VALUE intern_on_closed;
|
147
|
+
extern VALUE intern_on_close_failed;
|
148
|
+
extern VALUE intern_on_disconnected;
|
149
|
+
|
130
150
|
void _init_rb_czmq_socket();
|
131
151
|
|
132
152
|
#endif
|
data/ext/zeromq.tar.gz
CHANGED
Binary file
|
data/lib/zmq.rb
CHANGED
@@ -13,6 +13,20 @@ require 'zmq/version' unless defined? ZMQ::VERSION
|
|
13
13
|
require 'socket'
|
14
14
|
|
15
15
|
module ZMQ
|
16
|
+
def self.version3?
|
17
|
+
version[0] == 3
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.stable_version?
|
21
|
+
version[0] == 3 &&
|
22
|
+
version[1] == 2 &&
|
23
|
+
version[2] == 2
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.version2?
|
27
|
+
!version3?
|
28
|
+
end
|
29
|
+
|
16
30
|
# Sugaring for creating new ZMQ frames
|
17
31
|
#
|
18
32
|
# ZMQ::Frame("frame") => ZMQ::Frame
|
@@ -75,6 +89,7 @@ module ZMQ
|
|
75
89
|
end
|
76
90
|
|
77
91
|
require "zmq/context"
|
92
|
+
require "zmq/monitor"
|
78
93
|
require "zmq/socket"
|
79
94
|
require "zmq/loop"
|
80
95
|
require "zmq/timer"
|
data/lib/zmq/monitor.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class ZMQ::Monitor
|
4
|
+
def on_connected(addr, fd)
|
5
|
+
end
|
6
|
+
|
7
|
+
def on_connect_delayed(addr, err)
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_connect_retried(addr, interval)
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_listening(addr, fd)
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_bind_failed(addr, err)
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_accepted(addr, fd)
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_accept_failed(addr, err)
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_closed(addr, fd)
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_close_failed(addr, err)
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_disconnected(addr, fd)
|
32
|
+
end
|
33
|
+
end
|
data/lib/zmq/version.rb
CHANGED
data/test/test_context.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
4
|
+
|
5
|
+
if ZMQ.stable_version?
|
6
|
+
|
7
|
+
class TestMonitor
|
8
|
+
attr_reader :listening, :closed
|
9
|
+
|
10
|
+
def on_listening(addr, fd)
|
11
|
+
@listening = true
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_closed(addr, fd)
|
15
|
+
@closed = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class TestZmqMonitoring < ZmqTestCase
|
20
|
+
def test_monitoring
|
21
|
+
ctx = ZMQ::Context.new
|
22
|
+
sock = ctx.socket(:REP)
|
23
|
+
assert_raises TypeError do
|
24
|
+
sock.monitor(:invalid)
|
25
|
+
end
|
26
|
+
|
27
|
+
assert_raises TypeError do
|
28
|
+
sock.monitor("inproc://monitor.rep", nil, :invalid)
|
29
|
+
end
|
30
|
+
|
31
|
+
cb = TestMonitor.new
|
32
|
+
|
33
|
+
assert !sock.monitor("tcp://0.0.0.0:5000")
|
34
|
+
assert sock.monitor("inproc://monitor.rep", cb)
|
35
|
+
sleep 1
|
36
|
+
sock.bind("tcp://0.0.0.0:5555")
|
37
|
+
sleep 1
|
38
|
+
assert cb.listening
|
39
|
+
sock.close
|
40
|
+
sleep 1
|
41
|
+
assert cb.closed
|
42
|
+
ensure
|
43
|
+
ctx.destroy
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/test/test_socket.rb
CHANGED
@@ -18,7 +18,11 @@ class TestZmqSocket < ZmqTestCase
|
|
18
18
|
def test_send_timeout
|
19
19
|
ctx = ZMQ::Context.new
|
20
20
|
rep = ctx.socket(:REP)
|
21
|
-
|
21
|
+
if ZMQ.version3?
|
22
|
+
rep.sndhwm = 1
|
23
|
+
else
|
24
|
+
rep.hwm = 1
|
25
|
+
end
|
22
26
|
rep.bind("inproc://test.socket-send-timeout")
|
23
27
|
req = ctx.connect(:REQ, "inproc://test.socket-send-timeout")
|
24
28
|
# Cannot test much other than normal transfer's not disrupted
|
@@ -408,35 +412,60 @@ class TestZmqSocket < ZmqTestCase
|
|
408
412
|
|
409
413
|
def test_sock_options
|
410
414
|
ctx = ZMQ::Context.new
|
411
|
-
sock = ctx.socket(:
|
415
|
+
sock = ctx.socket(:ROUTER)
|
412
416
|
sock.verbose = true
|
413
|
-
assert_equal 0, sock.hwm
|
414
|
-
sock.hwm = 1000
|
415
|
-
assert_equal 1000, sock.hwm
|
416
417
|
|
417
|
-
|
418
|
-
|
419
|
-
|
418
|
+
if ZMQ.version3?
|
419
|
+
assert_equal 1000, sock.sndhwm
|
420
|
+
sock.sndhwm = 10000
|
421
|
+
assert_equal 10000, sock.sndhwm
|
422
|
+
|
423
|
+
assert_equal 1000, sock.rcvhwm
|
424
|
+
sock.rcvhwm = 10000
|
425
|
+
assert_equal 10000, sock.rcvhwm
|
426
|
+
else
|
427
|
+
assert_equal 0, sock.hwm
|
428
|
+
sock.hwm = 1000
|
429
|
+
assert_equal 1000, sock.hwm
|
430
|
+
|
431
|
+
assert_equal 0, sock.swap
|
432
|
+
sock.swap = 1000
|
433
|
+
assert_equal 1000, sock.swap
|
434
|
+
|
435
|
+
assert_equal(-1, sock.recovery_ivl_msec)
|
436
|
+
sock.recovery_ivl_msec = 20
|
437
|
+
assert_equal 20, sock.recovery_ivl_msec
|
438
|
+
end
|
420
439
|
|
421
440
|
assert_equal 0, sock.affinity
|
422
441
|
sock.affinity = 1
|
423
442
|
assert_equal 1, sock.affinity
|
424
443
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
444
|
+
if ZMQ.version3?
|
445
|
+
assert_equal 100, sock.rate
|
446
|
+
sock.rate = 50000
|
447
|
+
assert_equal 50000, sock.rate
|
448
|
+
else
|
449
|
+
assert_equal 40000, sock.rate
|
450
|
+
sock.rate = 50000
|
451
|
+
assert_equal 50000, sock.rate
|
452
|
+
end
|
432
453
|
|
433
|
-
|
434
|
-
|
435
|
-
|
454
|
+
if ZMQ.version3?
|
455
|
+
assert_equal 10000, sock.recovery_ivl
|
456
|
+
sock.recovery_ivl = 20
|
457
|
+
assert_equal 20, sock.recovery_ivl
|
458
|
+
else
|
459
|
+
assert_equal 10, sock.recovery_ivl
|
460
|
+
sock.recovery_ivl = 20
|
461
|
+
assert_equal 20, sock.recovery_ivl
|
462
|
+
end
|
436
463
|
|
437
|
-
|
438
|
-
|
439
|
-
|
464
|
+
if ZMQ.version2?
|
465
|
+
assert_equal true, sock.mcast_loop?
|
466
|
+
sock.mcast_loop = false
|
467
|
+
assert !sock.mcast_loop?
|
468
|
+
end
|
440
469
|
|
441
470
|
assert_equal 0, sock.sndbuf
|
442
471
|
sock.sndbuf = 1000
|
@@ -470,6 +499,10 @@ class TestZmqSocket < ZmqTestCase
|
|
470
499
|
sock.sndtimeo = 200
|
471
500
|
assert_equal 200, sock.sndtimeo
|
472
501
|
|
502
|
+
if sock.respond_to?(:raw=)
|
503
|
+
sock.raw = true
|
504
|
+
end
|
505
|
+
|
473
506
|
sock.identity = "anonymous"
|
474
507
|
assert_raises ZMQ::Error do
|
475
508
|
sock.identity = ""
|
@@ -480,7 +513,7 @@ class TestZmqSocket < ZmqTestCase
|
|
480
513
|
|
481
514
|
assert !sock.rcvmore?
|
482
515
|
|
483
|
-
assert_equal
|
516
|
+
assert_equal 2, sock.events
|
484
517
|
|
485
518
|
sub_sock = ctx.socket(:SUB)
|
486
519
|
sub_sock.verbose = true
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbczmq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: "0.9"
|
9
|
+
version: "1.0"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- "Lourens Naud\xC3\xA9"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-11-24 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rake-compiler
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- examples/push_pull.rb
|
59
59
|
- examples/req_rep.rb
|
60
60
|
- ext/czmq.tar.gz
|
61
|
+
- ext/libzmq.tar.gz
|
61
62
|
- ext/rbczmq/context.c
|
62
63
|
- ext/rbczmq/context.h
|
63
64
|
- ext/rbczmq/extconf.rb
|
@@ -91,6 +92,7 @@ files:
|
|
91
92
|
- lib/zmq/handler.rb
|
92
93
|
- lib/zmq/loop.rb
|
93
94
|
- lib/zmq/message.rb
|
95
|
+
- lib/zmq/monitor.rb
|
94
96
|
- lib/zmq/poller.rb
|
95
97
|
- lib/zmq/pollitem.rb
|
96
98
|
- lib/zmq/socket.rb
|
@@ -139,6 +141,7 @@ files:
|
|
139
141
|
- test/test_handler.rb
|
140
142
|
- test/test_loop.rb
|
141
143
|
- test/test_message.rb
|
144
|
+
- test/test_monitoring.rb
|
142
145
|
- test/test_poller.rb
|
143
146
|
- test/test_pollitem.rb
|
144
147
|
- test/test_socket.rb
|
@@ -199,6 +202,7 @@ test_files:
|
|
199
202
|
- test/test_handler.rb
|
200
203
|
- test/test_loop.rb
|
201
204
|
- test/test_message.rb
|
205
|
+
- test/test_monitoring.rb
|
202
206
|
- test/test_poller.rb
|
203
207
|
- test/test_pollitem.rb
|
204
208
|
- test/test_socket.rb
|