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