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.
@@ -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