rbczmq 0.9 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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 isntalled.
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 insatll libtool autoconf automake
230
+ brew install libtool autoconf automake
231
231
 
232
232
  == TODO
233
233
 
Binary file
Binary file
@@ -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
  }
@@ -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) }
@@ -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();
@@ -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
@@ -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
- rb_define_method(rb_cZmqSocket, "hwm", rb_czmq_socket_opt_hwm, 0);
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
  }
@@ -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
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"
@@ -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
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module ZMQ
4
- VERSION = "0.9"
4
+ VERSION = "1.0"
5
5
  end
@@ -68,7 +68,8 @@ class TestZmqContext < ZmqTestCase
68
68
  assert_raises ZMQ::Error do
69
69
  ctx.hwm = -2
70
70
  end
71
- assert_equal 10, ctx.hwm
71
+ # deprecated method
72
+ assert_equal 0, ctx.hwm
72
73
  ensure
73
74
  ctx.destroy
74
75
  end
@@ -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
@@ -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
- rep.hwm = 1
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(:PAIR)
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
- assert_equal 0, sock.swap
418
- sock.swap = 1000
419
- assert_equal 1000, sock.swap
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
- assert_equal 40000, sock.rate
426
- sock.rate = 50000
427
- assert_equal 50000, sock.rate
428
-
429
- assert_equal 10, sock.recovery_ivl
430
- sock.recovery_ivl = 20
431
- assert_equal 20, sock.recovery_ivl
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
- assert_equal(-1, sock.recovery_ivl_msec)
434
- sock.recovery_ivl_msec = 20
435
- assert_equal 20, sock.recovery_ivl_msec
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
- assert_equal true, sock.mcast_loop?
438
- sock.mcast_loop = false
439
- assert !sock.mcast_loop?
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 0, sock.events
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: 25
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
+ - 1
7
8
  - 0
8
- - 9
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-08-19 00:00:00 Z
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