Permalink
Browse files

Merge pull request #180 from AlexeyKupershtokh/all_options

Missing options for SetSockOpt
  • Loading branch information...
2 parents 66fd2f6 + 252fb20 commit c0425d8e2b0741e23cebd3dd7bb3b971e67fec98 @ronkorving ronkorving committed Mar 26, 2013
Showing with 211 additions and 97 deletions.
  1. +89 −96 binding.cc
  2. +50 −0 lib/index.js
  3. +23 −1 test/test.exports.js
  4. +49 −0 test/test.socket.router.unroutable.js
View
@@ -32,6 +32,7 @@
#include <string.h>
#include <errno.h>
#include <stdexcept>
+#include <set>
#ifdef _WIN32
# define snprintf _snprintf_s
@@ -63,6 +64,12 @@ enum {
namespace zmq {
+ std::set<int> opts_int;
+ std::set<int> opts_uint32;
+ std::set<int> opts_int64;
+ std::set<int> opts_uint64;
+ std::set<int> opts_binary;
+
class Socket;
class Context : ObjectWrap {
@@ -413,41 +420,19 @@ namespace zmq {
GET_SOCKET(args);
- // FIXME: How to handle ZMQ_FD on Windows?
- switch (option) {
- case 1:
- case ZMQ_AFFINITY:
- case ZMQ_SNDBUF:
- case ZMQ_RCVBUF:
- case ZMQ_RCVMORE:
- return socket->GetSockOpt<uint64_t>(option);
- case 3:
- case ZMQ_RATE:
- case ZMQ_RECOVERY_IVL:
- case 10:
- return socket->GetSockOpt<int64_t>(option);
- case ZMQ_IDENTITY:
-#ifdef ZMQ_LAST_ENDPOINT
- case ZMQ_LAST_ENDPOINT:
-#endif
- return socket->GetSockOpt<char*>(option);
- case ZMQ_EVENTS:
- return socket->GetSockOpt<uint32_t>(option);
- case 23: /* ZMQ_SNDHWM */
- case 24: /* ZMQ_RCVHWM */
- case ZMQ_FD:
- case ZMQ_TYPE:
- case ZMQ_LINGER:
- case ZMQ_RECONNECT_IVL:
- case ZMQ_BACKLOG:
- return socket->GetSockOpt<int>(option);
- case ZMQ_SUBSCRIBE:
- case ZMQ_UNSUBSCRIBE:
- return ThrowException(Exception::TypeError(
- String::New("Socket option cannot be read")));
- default:
- return ThrowException(Exception::TypeError(
- String::New("Unknown socket option")));
+ if (opts_int.count(option)) {
+ return socket->GetSockOpt<int>(option);
+ } else if (opts_uint32.count(option)) {
+ return socket->GetSockOpt<uint32_t>(option);
+ } else if (opts_int64.count(option)) {
+ return socket->GetSockOpt<int64_t>(option);
+ } else if (opts_uint64.count(option)) {
+ return socket->GetSockOpt<uint64_t>(option);
+ } else if (opts_binary.count(option)) {
+ return socket->GetSockOpt<char*>(option);
+ } else {
+ return ThrowException(Exception::Error(
+ String::New(zmq_strerror(EINVAL))));
}
}
@@ -462,36 +447,19 @@ namespace zmq {
GET_SOCKET(args);
- switch (option) {
- case 1:
- case ZMQ_AFFINITY:
- case ZMQ_SNDBUF:
- case ZMQ_RCVBUF:
- return socket->SetSockOpt<uint64_t>(option, args[1]);
- case 3:
- case ZMQ_RATE:
- case ZMQ_RECOVERY_IVL:
- case 10:
- return socket->SetSockOpt<int64_t>(option, args[1]);
- case 23: /* ZMQ_SNDHWM */
- case 24: /* ZMQ_RCVHWM */
- case ZMQ_IDENTITY:
- case ZMQ_SUBSCRIBE:
- case ZMQ_UNSUBSCRIBE:
- return socket->SetSockOpt<char*>(option, args[1]);
- case ZMQ_LINGER:
- case ZMQ_RECONNECT_IVL:
- case ZMQ_BACKLOG:
- return socket->SetSockOpt<int>(option, args[1]);
- case ZMQ_RCVMORE:
- case ZMQ_EVENTS:
- case ZMQ_FD:
- case ZMQ_TYPE:
- return ThrowException(Exception::TypeError(
- String::New("Socket option cannot be written")));
- default:
- return ThrowException(Exception::TypeError(
- String::New("Unknown socket option")));
+ if (opts_int.count(option)) {
+ return socket->SetSockOpt<int>(option, args[1]);
+ } else if (opts_uint32.count(option)) {
+ return socket->SetSockOpt<uint32_t>(option, args[1]);
+ } else if (opts_int64.count(option)) {
+ return socket->SetSockOpt<int64_t>(option, args[1]);
+ } else if (opts_uint64.count(option)) {
+ return socket->SetSockOpt<uint64_t>(option, args[1]);
+ } else if (opts_binary.count(option)) {
+ return socket->SetSockOpt<char*>(option, args[1]);
+ } else {
+ return ThrowException(Exception::Error(
+ String::New(zmq_strerror(EINVAL))));
}
}
@@ -890,6 +858,62 @@ namespace zmq {
Initialize(Handle<Object> target) {
HandleScope scope;
+ opts_int.insert(14); // ZMQ_FD
+ opts_int.insert(16); // ZMQ_TYPE
+ opts_int.insert(17); // ZMQ_LINGER
+ opts_int.insert(18); // ZMQ_RECONNECT_IVL
+ opts_int.insert(19); // ZMQ_BACKLOG
+ opts_int.insert(21); // ZMQ_RECONNECT_IVL_MAX
+ opts_int.insert(23); // ZMQ_SNDHWM
+ opts_int.insert(24); // ZMQ_RCVHWM
+ opts_int.insert(25); // ZMQ_MULTICAST_HOPS
+ opts_int.insert(27); // ZMQ_RCVTIMEO
+ opts_int.insert(28); // ZMQ_SNDTIMEO
+ opts_int.insert(29); // ZMQ_RCVLABEL
+ opts_int.insert(30); // ZMQ_RCVCMD
+ opts_int.insert(31); // ZMQ_IPV4ONLY
+ opts_int.insert(33); // ZMQ_ROUTER_MANDATORY
+ opts_int.insert(34); // ZMQ_TCP_KEEPALIVE
+ opts_int.insert(35); // ZMQ_TCP_KEEPALIVE_CNT
+ opts_int.insert(36); // ZMQ_TCP_KEEPALIVE_IDLE
+ opts_int.insert(37); // ZMQ_TCP_KEEPALIVE_INTVL
+ opts_int.insert(39); // ZMQ_DELAY_ATTACH_ON_CONNECT
+ opts_int.insert(40); // ZMQ_XPUB_VERBOSE
+ opts_int.insert(41); // ZMQ_ROUTER_RAW
+ opts_int.insert(42); // ZMQ_IPV6
+
+ opts_int64.insert(3); // ZMQ_SWAP
+ opts_int64.insert(8); // ZMQ_RATE
+ opts_int64.insert(10); // ZMQ_MCAST_LOOP
+ opts_int64.insert(20); // ZMQ_RECOVERY_IVL_MSEC
+ opts_int64.insert(22); // ZMQ_MAXMSGSIZE
+
+ opts_uint64.insert(1); // ZMQ_HWM
+ opts_uint64.insert(4); // ZMQ_AFFINITY
+
+ opts_binary.insert(5); // ZMQ_IDENTITY
+ opts_binary.insert(6); // ZMQ_SUBSCRIBE
+ opts_binary.insert(7); // ZMQ_UNSUBSCRIBE
+ opts_binary.insert(32); // ZMQ_LAST_ENDPOINT
+ opts_binary.insert(38); // ZMQ_TCP_ACCEPT_FILTER
+
+ // transition types
+ #if ZMQ_VERSION_MAJOR >= 3
+ opts_int.insert(15); // ZMQ_EVENTS 3.x int
+ opts_int.insert(8); // ZMQ_RATE 3.x int
+ opts_int.insert(9); // ZMQ_RECOVERY_IVL 3.x int
+ opts_int.insert(13); // ZMQ_RCVMORE 3.x int
+ opts_int.insert(11); // ZMQ_SNDBUF 3.x int
+ opts_int.insert(12); // ZMQ_RCVBUF 3.x int
+ #else
+ opts_uint32.insert(15); // ZMQ_EVENTS 2.x uint32_t
+ opts_int64.insert(8); // ZMQ_RATE 2.x int64_t
+ opts_int64.insert(9); // ZMQ_RECOVERY_IVL 2.x int64_t
+ opts_int64.insert(13); // ZMQ_RCVMORE 2.x int64_t
+ opts_uint64.insert(11); // ZMQ_SNDBUF 2.x uint64_t
+ opts_uint64.insert(12); // ZMQ_RCVBUF 2.x uint64_t
+ #endif
+
NODE_DEFINE_CONSTANT(target, ZMQ_CAN_DISCONNECT);
NODE_DEFINE_CONSTANT(target, ZMQ_PUB);
NODE_DEFINE_CONSTANT(target, ZMQ_SUB);
@@ -907,37 +931,6 @@ namespace zmq {
NODE_DEFINE_CONSTANT(target, ZMQ_PULL);
NODE_DEFINE_CONSTANT(target, ZMQ_PAIR);
- #if ZMQ_VERSION_MAJOR == 2
- NODE_DEFINE_CONSTANT(target, ZMQ_HWM);
- NODE_DEFINE_CONSTANT(target, ZMQ_SWAP);
- #else
- NODE_DEFINE_CONSTANT(target, ZMQ_SNDHWM);
- NODE_DEFINE_CONSTANT(target, ZMQ_RCVHWM);
- #endif
- NODE_DEFINE_CONSTANT(target, ZMQ_AFFINITY);
- NODE_DEFINE_CONSTANT(target, ZMQ_IDENTITY);
-
- #ifdef ZMQ_LAST_ENDPOINT
- NODE_DEFINE_CONSTANT(target, ZMQ_LAST_ENDPOINT);
- #endif
-
- NODE_DEFINE_CONSTANT(target, ZMQ_SUBSCRIBE);
- NODE_DEFINE_CONSTANT(target, ZMQ_UNSUBSCRIBE);
- NODE_DEFINE_CONSTANT(target, ZMQ_RATE);
- NODE_DEFINE_CONSTANT(target, ZMQ_RECOVERY_IVL);
- #if ZMQ_VERSION_MAJOR == 2
- NODE_DEFINE_CONSTANT(target, ZMQ_MCAST_LOOP);
- #endif
- NODE_DEFINE_CONSTANT(target, ZMQ_SNDBUF);
- NODE_DEFINE_CONSTANT(target, ZMQ_RCVBUF);
- NODE_DEFINE_CONSTANT(target, ZMQ_RCVMORE);
- NODE_DEFINE_CONSTANT(target, ZMQ_FD);
- NODE_DEFINE_CONSTANT(target, ZMQ_EVENTS);
- NODE_DEFINE_CONSTANT(target, ZMQ_TYPE);
- NODE_DEFINE_CONSTANT(target, ZMQ_LINGER);
- NODE_DEFINE_CONSTANT(target, ZMQ_RECONNECT_IVL);
- NODE_DEFINE_CONSTANT(target, ZMQ_BACKLOG);
-
NODE_DEFINE_CONSTANT(target, ZMQ_POLLIN);
NODE_DEFINE_CONSTANT(target, ZMQ_POLLOUT);
NODE_DEFINE_CONSTANT(target, ZMQ_POLLERR);
View
@@ -37,6 +37,56 @@ var types = exports.types = {
, pair: zmq.ZMQ_PAIR
};
+var longOptions = {
+ ZMQ_HWM: 1
+ , ZMQ_SWAP: 3
+ , ZMQ_AFFINITY: 4
+ , ZMQ_IDENTITY: 5
+ , ZMQ_SUBSCRIBE: 6
+ , ZMQ_UNSUBSCRIBE: 7
+ , ZMQ_RATE: 8
+ , ZMQ_RECOVERY_IVL: 9
+ , ZMQ_MCAST_LOOP: 10
+ , ZMQ_SNDBUF: 11
+ , ZMQ_RCVBUF: 12
+ , ZMQ_RCVMORE: 13
+ , ZMQ_FD: 14
+ , ZMQ_EVENTS: 15
+ , ZMQ_TYPE: 16
+ , ZMQ_LINGER: 17
+ , ZMQ_RECONNECT_IVL: 18
+ , ZMQ_BACKLOG: 19
+ , ZMQ_RECOVERY_IVL_MSEC: 20
+ , ZMQ_RECONNECT_IVL_MAX: 21
+ , ZMQ_MAXMSGSIZE: 22
+ , ZMQ_SNDHWM: 23
+ , ZMQ_RCVHWM: 24
+ , ZMQ_MULTICAST_HOPS: 25
+ , ZMQ_RCVTIMEO: 27
+ , ZMQ_SNDTIMEO: 28
+ , ZMQ_IPV4ONLY: 31
+ , ZMQ_LAST_ENDPOINT: 32
+ , ZMQ_ROUTER_MANDATORY: 33
+ , ZMQ_TCP_KEEPALIVE: 34
+ , ZMQ_TCP_KEEPALIVE_CNT: 35
+ , ZMQ_TCP_KEEPALIVE_IDLE: 36
+ , ZMQ_TCP_KEEPALIVE_INTVL: 37
+ , ZMQ_TCP_ACCEPT_FILTER: 38
+ , ZMQ_DELAY_ATTACH_ON_CONNECT: 39
+ , ZMQ_XPUB_VERBOSE: 40
+ , ZMQ_ROUTER_RAW: 41
+ , ZMQ_IPV6: 42
+};
+
+Object.keys(longOptions).forEach(function(name){
+ Object.defineProperty(zmq, name, {
+ enumerable: true,
+ configurable: false,
+ writable: false,
+ value: longOptions[name]
+ });
+});
+
/**
* Map of socket options.
*/
View
@@ -26,6 +26,8 @@ var constants = [
'IDENTITY',
'SUBSCRIBE',
'UNSUBSCRIBE',
+ 'RCVTIMEO',
+ 'SNDTIMEO',
'RATE',
'RECOVERY_IVL',
'SNDBUF',
@@ -36,6 +38,7 @@ var constants = [
'TYPE',
'LINGER',
'RECONNECT_IVL',
+ 'RECONNECT_IVL_MAX',
'BACKLOG',
'POLLIN',
'POLLOUT',
@@ -49,6 +52,7 @@ if (semver.satisfies(zmq.version, '2.x')) {
'HWM',
'SWAP',
'MCAST_LOOP',
+ 'ZMQ_RECOVERY_IVL_MSEC',
'NOBLOCK'
]);
}
@@ -59,17 +63,35 @@ if (semver.gte(zmq.version, '3.0.0')) {
'XPUB',
'XSUB',
'SNDHWM',
- 'RCVHWM'
+ 'RCVHWM',
+ 'MAXMSGSIZE',
+ 'ZMQ_MULTICAST_HOPS',
]);
}
// 3.2 and above.
if (semver.gte(zmq.version, '3.2.0')) {
constants.concat([
+ 'IPV4ONLY',
+ 'DELAY_ATTACH_ON_CONNECT',
+ 'ROUTER_MANDATORY',
+ 'XPUB_VERBOSE',
+ 'TCP_KEEPALIVE',
+ 'TCP_KEEPALIVE_IDLE',
+ 'TCP_KEEPALIVE_CNT',
+ 'TCP_KEEPALIVE_INTVL',
+ 'TCP_ACCEPT_FILTER',
'LAST_ENDPOINT'
]);
}
+// 3.3 and above.
+if (semver.gte(zmq.version, '3.3.0')) {
+ constants.concat([
+ 'ROUTER_RAW',
+ ]);
+}
+
constants.forEach(function(typeOrProp){
zmq['ZMQ_' + typeOrProp].should.be.a('number');
});
@@ -0,0 +1,49 @@
+
+var zmq = require('../')
+ , should = require('should')
+ , semver = require('semver');
+
+if (!semver.gte(zmq.version, '3.2.0')) {
+ console.warn('Test requires libzmq >= 3.2.0');
+ return;
+}
+
+if (semver.eq(zmq.version, '3.2.1')) {
+ console.warn('ZMQ_ROUTER_MANDATORY is broken in libzmq = 3.2.1');
+ return;
+}
+
+// should emit an error event on unroutable msgs if mandatory = 1 and error handler is set
+
+var sock = zmq.socket('router');
+sock.on('error', function(err) {
+ err.message.should.equal('No route to host');
+ sock.close();
+});
+
+sock.setsockopt(zmq.ZMQ_ROUTER_MANDATORY, 1);
+
+var envelope = '12384982398293';
+sock.send([envelope, '']);
+
+// should throw an error on unroutable msgs if mandatory = 1 and no error handler is set
+
+var sock = zmq.socket('router');
+
+sock.setsockopt(zmq.ZMQ_ROUTER_MANDATORY, 1);
+
+(function(){
+ var envelope = '12384982398293';
+ sock.send([envelope, '']);
+}).should.throw('No route to host');
+sock.close();
+
+// should silently ignore unroutable msgs if mandatory = 0
+
+var sock = zmq.socket('router');
+
+(function(){
+ var envelope = '12384982398293';
+ sock.send([envelope, '']);
+ sock.close();
+}).should.not.throw('No route to host');

0 comments on commit c0425d8

Please sign in to comment.