nanomsg 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +16 -0
- data/README +9 -5
- data/examples/bus.rb +32 -0
- data/examples/bus_device.rb +39 -0
- data/examples/pair.rb +2 -2
- data/ext/Makefile +2 -2
- data/ext/constants.c +89 -0
- data/ext/constants.h +9 -0
- data/ext/constants.o +0 -0
- data/ext/init.c +272 -73
- data/ext/init.o +0 -0
- data/ext/nanomsg.bundle +0 -0
- data/spec/lib/nanomsg/bus_spec.rb +34 -0
- data/spec/lib/nanomsg/device_spec.rb +41 -0
- data/spec/lib/nanomsg/pair_socket_spec.rb +5 -0
- data/spec/lib/nanomsg/pub_sub_spec.rb +58 -0
- data/spec/lib/nanomsg/push_pull_spec.rb +70 -0
- data/spec/lib/nanomsg/req_rep_spec.rb +33 -0
- data/spec/lib/nanomsg/survey_spec.rb +47 -0
- data/spec/lib/nanomsg_spec.rb +11 -0
- data/spec/spec_helper.rb +7 -1
- metadata +17 -14
- data/ext/mkmf.log +0 -22
- data/ext/nanomsg.o +0 -0
data/HISTORY
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
= 0.2 /
|
3
|
+
|
4
|
+
* Adds REQ/REP socket type (ReqSocket, RepSocket).
|
5
|
+
* Adds PUB/SUB socket type.
|
6
|
+
* Adds SURVEYOR/RESPONDENT socket types. (SurveySocket, RespondSocket)
|
7
|
+
* Adds PUSH/PULL socket types. (PushSocket, PullSocket)
|
8
|
+
* Adds BUS socket type. (BusSocket)
|
9
|
+
* There's an experimental API for devices (.run_loopback, .run_device).
|
10
|
+
Devices block a Ruby thread until .terminate is called.
|
11
|
+
* Exceptions raised are now subclasses of NanoMsg::Errno
|
12
|
+
* Added NanoMsg.terminate, calls nn_term.
|
13
|
+
|
14
|
+
= 0.1 / 22Aug2013
|
15
|
+
|
16
|
+
* Initial release, only PAIR sockets supported.
|
data/README
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
TLDR
|
3
3
|
|
4
|
-
An idiomatic nanomsg wrapper for Ruby.
|
4
|
+
An idiomatic nanomsg wrapper for Ruby.
|
5
5
|
|
6
6
|
NANOMSG
|
7
7
|
|
@@ -25,6 +25,11 @@ stack. At the moment, nanomsg library supports following transports:
|
|
25
25
|
* IPC - transport between processes on a single machine
|
26
26
|
* TCP - network transport via TCP
|
27
27
|
|
28
|
+
DOCUMENTATION
|
29
|
+
|
30
|
+
Check out the examples folder of the project. See http://nanomsg.org/ for more
|
31
|
+
documentation.
|
32
|
+
|
28
33
|
SYNOPSIS
|
29
34
|
|
30
35
|
require 'nanomsg'
|
@@ -37,11 +42,10 @@ SYNOPSIS
|
|
37
42
|
|
38
43
|
STATUS
|
39
44
|
|
40
|
-
Very early alpha, not much testing has been done.
|
41
|
-
|
42
|
-
application.
|
45
|
+
Very early alpha, not much testing has been done. All socket types and devices
|
46
|
+
should work.
|
43
47
|
|
44
48
|
LICENSE
|
45
49
|
|
46
|
-
|
50
|
+
See file LICENSE, Copyright (c) 2013 Kaspar Schiess
|
47
51
|
|
data/examples/bus.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
2
|
+
require 'nanomsg'
|
3
|
+
include NanoMsg
|
4
|
+
|
5
|
+
buses = 3.times.map { BusSocket.new }
|
6
|
+
|
7
|
+
a = 'tcp://127.0.0.1:5432'
|
8
|
+
b = 'tcp://127.0.0.1:5433'
|
9
|
+
|
10
|
+
one, two, three = *buses
|
11
|
+
|
12
|
+
one.bind a
|
13
|
+
|
14
|
+
two.bind b
|
15
|
+
two.connect a
|
16
|
+
|
17
|
+
three.connect a
|
18
|
+
three.connect b
|
19
|
+
|
20
|
+
sleep 0.1
|
21
|
+
|
22
|
+
one.send 'A'
|
23
|
+
p two.recv
|
24
|
+
p three.recv
|
25
|
+
|
26
|
+
two.send 'B'
|
27
|
+
p one.recv
|
28
|
+
p three.recv
|
29
|
+
|
30
|
+
three.send 'C'
|
31
|
+
p one.recv
|
32
|
+
p two.recv
|
@@ -0,0 +1,39 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
2
|
+
require 'nanomsg'
|
3
|
+
include NanoMsg
|
4
|
+
|
5
|
+
a = 'tcp://127.0.0.1:5432'
|
6
|
+
b = 'tcp://127.0.0.1:5433'
|
7
|
+
c = 'tcp://127.0.0.1:5434'
|
8
|
+
|
9
|
+
one, two, three = 3.times.map { BusSocket.new }
|
10
|
+
four, five, six = 3.times.map { BusSocket.new(AF_SP_RAW) }
|
11
|
+
|
12
|
+
one.bind a
|
13
|
+
two.bind b
|
14
|
+
three.bind c
|
15
|
+
|
16
|
+
# one -> four -> four -> two
|
17
|
+
four.connect a
|
18
|
+
four.connect b
|
19
|
+
Thread.start do
|
20
|
+
NanoMsg.run_loopback(four)
|
21
|
+
end.abort_on_exception = true
|
22
|
+
|
23
|
+
# one -> five -> six -> three
|
24
|
+
five.connect a
|
25
|
+
six.connect c
|
26
|
+
Thread.start do
|
27
|
+
NanoMsg.run_device(five, six)
|
28
|
+
end.abort_on_exception = true
|
29
|
+
|
30
|
+
sleep 0.2
|
31
|
+
one.send 'A'
|
32
|
+
|
33
|
+
# Gets sent to three, which forwards it to two.
|
34
|
+
puts two.recv
|
35
|
+
|
36
|
+
# Gets sent to five, which forwards it through six to three.
|
37
|
+
puts three.recv
|
38
|
+
|
39
|
+
NanoMsg.terminate
|
data/examples/pair.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
$:.unshift File.dirname(__FILE__) + "/../lib"
|
3
3
|
require 'nanomsg'
|
4
4
|
|
5
|
-
sock1 = NanoMsg::PairSocket.new
|
5
|
+
sock1 = NanoMsg::PairSocket.new
|
6
6
|
sock1.bind("ipc:///tmp/test.ipc")
|
7
7
|
|
8
|
-
sock2 = NanoMsg::PairSocket.new
|
8
|
+
sock2 = NanoMsg::PairSocket.new
|
9
9
|
sock2.connect("ipc:///tmp/test.ipc")
|
10
10
|
|
11
11
|
sock1.send 'test'
|
data/ext/Makefile
CHANGED
@@ -117,8 +117,8 @@ extout_prefix =
|
|
117
117
|
target_prefix =
|
118
118
|
LOCAL_LIBS =
|
119
119
|
LIBS = $(LIBRUBYARG_SHARED) -lnanomsg -lpthread -ldl -lobjc
|
120
|
-
SRCS = init.c
|
121
|
-
OBJS = init.o
|
120
|
+
SRCS = constants.c init.c
|
121
|
+
OBJS = constants.o init.o
|
122
122
|
TARGET = nanomsg
|
123
123
|
DLLIB = $(TARGET).bundle
|
124
124
|
EXTSTATIC =
|
data/ext/constants.c
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
|
2
|
+
#include "ruby/ruby.h"
|
3
|
+
#include "ruby/st.h"
|
4
|
+
|
5
|
+
#include <nanomsg/nn.h>
|
6
|
+
|
7
|
+
static st_table *syserr_tbl;
|
8
|
+
|
9
|
+
static VALUE
|
10
|
+
errno_initialize(VALUE self)
|
11
|
+
{
|
12
|
+
VALUE error;
|
13
|
+
VALUE klass = rb_obj_class(self);
|
14
|
+
|
15
|
+
const char *explanation;
|
16
|
+
VALUE message;
|
17
|
+
|
18
|
+
error = rb_const_get(klass, rb_intern("Errno"));
|
19
|
+
explanation = nn_strerror(FIX2INT(error));
|
20
|
+
|
21
|
+
message = rb_str_new(explanation, strlen(explanation));
|
22
|
+
rb_call_super(1, &message);
|
23
|
+
|
24
|
+
rb_iv_set(self, "errno", error);
|
25
|
+
|
26
|
+
return self;
|
27
|
+
}
|
28
|
+
|
29
|
+
static VALUE
|
30
|
+
errno_errno(VALUE self)
|
31
|
+
{
|
32
|
+
return rb_attr_get(self, rb_intern("errno"));
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE
|
36
|
+
err_add(VALUE module, int n, const char *name)
|
37
|
+
{
|
38
|
+
st_data_t error;
|
39
|
+
|
40
|
+
if (!st_lookup(syserr_tbl, n, &error)) {
|
41
|
+
error = rb_define_class_under(module, name, rb_eStandardError);
|
42
|
+
|
43
|
+
rb_define_const(error, "Errno", INT2NUM(n));
|
44
|
+
rb_define_method(error, "initialize", errno_initialize, 0);
|
45
|
+
rb_define_method(error, "errno", errno_errno, 0);
|
46
|
+
|
47
|
+
st_add_direct(syserr_tbl, n, error);
|
48
|
+
}
|
49
|
+
|
50
|
+
return error;
|
51
|
+
}
|
52
|
+
|
53
|
+
VALUE
|
54
|
+
errno_lookup(int n)
|
55
|
+
{
|
56
|
+
st_data_t error;
|
57
|
+
|
58
|
+
if (!st_lookup(syserr_tbl, n, &error))
|
59
|
+
return Qnil;
|
60
|
+
|
61
|
+
return error;
|
62
|
+
}
|
63
|
+
|
64
|
+
void
|
65
|
+
Init_constants(VALUE module)
|
66
|
+
{
|
67
|
+
VALUE mErrno;
|
68
|
+
int i, value;
|
69
|
+
|
70
|
+
syserr_tbl = st_init_numtable();
|
71
|
+
|
72
|
+
mErrno = rb_define_module_under(module, "Errno");
|
73
|
+
|
74
|
+
// Define all constants that nanomsg knows about:
|
75
|
+
for (i = 0; ; ++i) {
|
76
|
+
const char* name = nn_symbol (i, &value);
|
77
|
+
if (name == NULL) break;
|
78
|
+
|
79
|
+
// I see no point in declaring values other than those starting with NN_:
|
80
|
+
if (strncmp(name, "NN_", 3) == 0)
|
81
|
+
rb_const_set(module, rb_intern(name), INT2NUM(value));
|
82
|
+
|
83
|
+
if (strncmp(name, "AF_", 3) == 0)
|
84
|
+
rb_const_set(module, rb_intern(name), INT2NUM(value));
|
85
|
+
|
86
|
+
if (strncmp(name, "E", 1) == 0)
|
87
|
+
err_add(mErrno, value, name);
|
88
|
+
}
|
89
|
+
}
|
data/ext/constants.h
ADDED
data/ext/constants.o
ADDED
Binary file
|
data/ext/init.c
CHANGED
@@ -2,11 +2,34 @@
|
|
2
2
|
#include "ruby/ruby.h"
|
3
3
|
|
4
4
|
#include <nanomsg/nn.h>
|
5
|
+
#include <nanomsg/reqrep.h>
|
5
6
|
#include <nanomsg/pair.h>
|
7
|
+
#include <nanomsg/pubsub.h>
|
8
|
+
#include <nanomsg/survey.h>
|
9
|
+
#include <nanomsg/pipeline.h>
|
10
|
+
#include <nanomsg/bus.h>
|
6
11
|
|
7
|
-
|
12
|
+
#include "constants.h"
|
13
|
+
|
14
|
+
static VALUE mNanoMsg;
|
8
15
|
static VALUE cSocket;
|
16
|
+
|
9
17
|
static VALUE cPairSocket;
|
18
|
+
|
19
|
+
static VALUE cReqSocket;
|
20
|
+
static VALUE cRepSocket;
|
21
|
+
|
22
|
+
static VALUE cPubSocket;
|
23
|
+
static VALUE cSubSocket;
|
24
|
+
|
25
|
+
static VALUE cSurveySocket;
|
26
|
+
static VALUE cRespondSocket;
|
27
|
+
|
28
|
+
static VALUE cPushSocket;
|
29
|
+
static VALUE cPullSocket;
|
30
|
+
|
31
|
+
static VALUE cBusSocket;
|
32
|
+
|
10
33
|
static VALUE ceSocketError;
|
11
34
|
|
12
35
|
struct nmsg_socket {
|
@@ -65,46 +88,18 @@ sock_alloc(VALUE klass)
|
|
65
88
|
}
|
66
89
|
|
67
90
|
static void
|
68
|
-
sock_raise_error(int
|
91
|
+
sock_raise_error(int nn_errno)
|
69
92
|
{
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
rb_raise(ceSocketError, "The operation is not supported by this socket type.");
|
79
|
-
break;
|
80
|
-
case EFSM:
|
81
|
-
rb_raise(ceSocketError, "The operation cannot be performed on this socket at the moment because the socket is not in the appropriate state.");
|
82
|
-
break;
|
83
|
-
case EAGAIN:
|
84
|
-
rb_raise(ceSocketError, "Non-blocking mode was requested and the message cannot be sent at the moment.");
|
85
|
-
break;
|
86
|
-
case EINTR:
|
87
|
-
rb_raise(ceSocketError, "The operation was interrupted by delivery of a signal before the message was sent.");
|
88
|
-
break;
|
89
|
-
case ETIMEDOUT:
|
90
|
-
rb_raise(ceSocketError, "Individual socket types may define their own specific timeouts. If such timeout is hit, this error will be returned.");
|
91
|
-
break;
|
92
|
-
case EAFNOSUPPORT:
|
93
|
-
rb_raise(ceSocketError, "Specified address family is not supported.");
|
94
|
-
break;
|
95
|
-
case EINVAL:
|
96
|
-
rb_raise(ceSocketError, "Unknown protocol.");
|
97
|
-
break;
|
98
|
-
case EMFILE:
|
99
|
-
rb_raise(ceSocketError, "The limit on the total number of open SP sockets or OS limit for file descriptors has been reached.");
|
100
|
-
break;
|
101
|
-
case ETERM:
|
102
|
-
rb_raise(ceSocketError, "The library is terminating.");
|
103
|
-
break;
|
104
|
-
default:
|
105
|
-
rb_raise(ceSocketError, "Unknown error code %d", errno);
|
106
|
-
}
|
93
|
+
VALUE error = errno_lookup(nn_errno);
|
94
|
+
|
95
|
+
if (error != Qnil) {
|
96
|
+
VALUE exc = rb_class_new_instance(0, NULL, error);
|
97
|
+
rb_exc_raise(exc);
|
98
|
+
}
|
99
|
+
|
100
|
+
rb_raise(ceSocketError, "General failure, no such error code %d found.", nn_errno);
|
107
101
|
}
|
102
|
+
#define RAISE_SOCK_ERROR { sock_raise_error(nn_errno()); }
|
108
103
|
|
109
104
|
static VALUE
|
110
105
|
sock_bind(VALUE socket, VALUE bind)
|
@@ -114,7 +109,7 @@ sock_bind(VALUE socket, VALUE bind)
|
|
114
109
|
|
115
110
|
endpoint = nn_bind(sock, StringValueCStr(bind));
|
116
111
|
if (endpoint < 0)
|
117
|
-
|
112
|
+
RAISE_SOCK_ERROR;
|
118
113
|
|
119
114
|
// TODO do something with the endpoint, returning it in a class for example.
|
120
115
|
return Qnil;
|
@@ -128,14 +123,25 @@ sock_connect(VALUE socket, VALUE connect)
|
|
128
123
|
|
129
124
|
endpoint = nn_connect(sock, StringValueCStr(connect));
|
130
125
|
if (endpoint < 0)
|
131
|
-
|
126
|
+
RAISE_SOCK_ERROR;
|
132
127
|
|
133
128
|
// TODO do something with the endpoint, returning it in a class for example.
|
134
129
|
return Qnil;
|
135
130
|
}
|
136
131
|
|
132
|
+
static void
|
133
|
+
sock_init(VALUE socket, int domain, int protocol)
|
134
|
+
{
|
135
|
+
struct nmsg_socket *psock = sock_get_ptr(socket);
|
136
|
+
|
137
|
+
psock->socket = nn_socket(domain, protocol);
|
138
|
+
if (psock->socket < 0)
|
139
|
+
RAISE_SOCK_ERROR;
|
140
|
+
}
|
141
|
+
|
137
142
|
struct ioop {
|
138
|
-
int
|
143
|
+
int nn_errno;
|
144
|
+
int return_code;
|
139
145
|
int sock;
|
140
146
|
char* buffer;
|
141
147
|
long len;
|
@@ -147,11 +153,18 @@ sock_send_no_gvl(void* data)
|
|
147
153
|
{
|
148
154
|
struct ioop *pio = data;
|
149
155
|
|
150
|
-
|
151
|
-
|
156
|
+
// TODO This is buggy. I cannot make the difference between
|
157
|
+
// 'socket gone away' (=EAGAIN) and 'socket busy' (=EAGAIN). So I err on the
|
158
|
+
// side of 'socket busy' and do not raise the error. As a consequence, we'll
|
159
|
+
// get stuck in an endless loop when the socket is just not answering.
|
160
|
+
|
161
|
+
while (pio->nn_errno == EAGAIN && !pio->abort) {
|
162
|
+
pio->return_code = nn_send(pio->sock, pio->buffer, pio->len, NN_DONTWAIT /* flags */);
|
152
163
|
|
153
|
-
if (pio->
|
154
|
-
pio->
|
164
|
+
if (pio->return_code < 0)
|
165
|
+
pio->nn_errno = nn_errno();
|
166
|
+
else
|
167
|
+
break;
|
155
168
|
}
|
156
169
|
|
157
170
|
return Qnil;
|
@@ -170,7 +183,7 @@ sock_send(VALUE socket, VALUE buffer)
|
|
170
183
|
struct ioop io;
|
171
184
|
|
172
185
|
io.sock = sock_get(socket);
|
173
|
-
io.
|
186
|
+
io.nn_errno = EAGAIN;
|
174
187
|
io.buffer = StringValuePtr(buffer);
|
175
188
|
io.len = RSTRING_LEN(buffer);
|
176
189
|
io.abort = Qfalse;
|
@@ -182,10 +195,10 @@ sock_send(VALUE socket, VALUE buffer)
|
|
182
195
|
if (io.abort)
|
183
196
|
return Qnil;
|
184
197
|
|
185
|
-
if (io.
|
186
|
-
sock_raise_error(io.
|
198
|
+
if (io.return_code < 0)
|
199
|
+
sock_raise_error(io.nn_errno);
|
187
200
|
|
188
|
-
return INT2NUM(io.
|
201
|
+
return INT2NUM(io.return_code);
|
189
202
|
}
|
190
203
|
|
191
204
|
static VALUE
|
@@ -193,11 +206,18 @@ sock_recv_no_gvl(void* data)
|
|
193
206
|
{
|
194
207
|
struct ioop *pio = data;
|
195
208
|
|
196
|
-
|
197
|
-
|
209
|
+
// TODO This is buggy. I cannot make the difference between
|
210
|
+
// 'socket gone away' (=EAGAIN) and 'socket busy' (=EAGAIN). So I err on the
|
211
|
+
// side of 'socket busy' and do not raise the error. As a consequence, we'll
|
212
|
+
// get stuck in an endless loop when the socket is just not answering.
|
213
|
+
|
214
|
+
while (pio->nn_errno == EAGAIN && !pio->abort) {
|
215
|
+
pio->return_code = nn_recv(pio->sock, &pio->buffer, NN_MSG, NN_DONTWAIT /* flags */);
|
198
216
|
|
199
|
-
if (pio->
|
200
|
-
pio->
|
217
|
+
if (pio->return_code < 0)
|
218
|
+
pio->nn_errno = nn_errno();
|
219
|
+
else
|
220
|
+
break;
|
201
221
|
}
|
202
222
|
|
203
223
|
return Qnil;
|
@@ -220,52 +240,231 @@ sock_recv(VALUE socket)
|
|
220
240
|
io.sock = sock_get(socket);
|
221
241
|
io.buffer = (char*) 0;
|
222
242
|
io.abort = Qfalse;
|
223
|
-
io.
|
243
|
+
io.nn_errno = EAGAIN;
|
224
244
|
|
225
245
|
rb_thread_blocking_region(sock_recv_no_gvl, &io, sock_recv_abort, &io);
|
226
246
|
|
227
247
|
if (io.abort)
|
228
248
|
return Qnil;
|
229
249
|
|
230
|
-
if (io.
|
231
|
-
sock_raise_error(io.
|
250
|
+
if (io.return_code < 0)
|
251
|
+
sock_raise_error(io.nn_errno);
|
232
252
|
|
233
|
-
result = rb_str_new(io.buffer, io.
|
253
|
+
result = rb_str_new(io.buffer, io.return_code);
|
234
254
|
nn_freemsg(io.buffer); io.buffer = (char*) 0;
|
235
255
|
|
236
256
|
return result;
|
237
257
|
}
|
238
258
|
|
239
|
-
static VALUE
|
240
|
-
|
259
|
+
static VALUE
|
260
|
+
sock_close_no_gvl(void* data)
|
241
261
|
{
|
242
|
-
struct
|
262
|
+
struct ioop *pio = (struct ioop*) data;
|
243
263
|
|
244
|
-
|
245
|
-
if (
|
246
|
-
|
247
|
-
}
|
264
|
+
pio->return_code = nn_close(pio->sock);
|
265
|
+
if (pio->return_code < 0)
|
266
|
+
pio->nn_errno = nn_errno();
|
248
267
|
|
249
|
-
return
|
268
|
+
return Qnil;
|
269
|
+
}
|
270
|
+
|
271
|
+
static VALUE
|
272
|
+
sock_close(VALUE socket)
|
273
|
+
{
|
274
|
+
struct ioop io;
|
275
|
+
|
276
|
+
io.sock = sock_get(socket);
|
277
|
+
|
278
|
+
// I've no idea on how to abort a close (which may block for NN_LINGER
|
279
|
+
// seconds), so we'll be uninterruptible.
|
280
|
+
rb_thread_blocking_region(sock_close_no_gvl, &io, NULL, NULL);
|
281
|
+
|
282
|
+
if (io.return_code < 0)
|
283
|
+
sock_raise_error(io.nn_errno);
|
284
|
+
|
285
|
+
return Qnil;
|
286
|
+
}
|
287
|
+
|
288
|
+
#define SOCK_INIT_FUNC(name, type) \
|
289
|
+
static VALUE \
|
290
|
+
name(int argc, VALUE *argv, VALUE self) \
|
291
|
+
{ \
|
292
|
+
VALUE domain; \
|
293
|
+
\
|
294
|
+
rb_scan_args(argc, argv, "01", &domain); \
|
295
|
+
if (NIL_P(domain)) \
|
296
|
+
sock_init(self, AF_SP, (type)); \
|
297
|
+
else \
|
298
|
+
sock_init(self, FIX2INT(domain), (type)); \
|
299
|
+
\
|
300
|
+
return self; \
|
301
|
+
}
|
302
|
+
|
303
|
+
SOCK_INIT_FUNC(pair_sock_init, NN_PAIR);
|
304
|
+
SOCK_INIT_FUNC(req_sock_init, NN_REQ);
|
305
|
+
SOCK_INIT_FUNC(rep_sock_init, NN_REP);
|
306
|
+
SOCK_INIT_FUNC(pub_sock_init, NN_PUB);
|
307
|
+
SOCK_INIT_FUNC(sub_sock_init, NN_SUB);
|
308
|
+
SOCK_INIT_FUNC(srvy_sock_init, NN_SURVEYOR);
|
309
|
+
SOCK_INIT_FUNC(resp_sock_init, NN_RESPONDENT);
|
310
|
+
SOCK_INIT_FUNC(push_sock_init, NN_PUSH);
|
311
|
+
SOCK_INIT_FUNC(pull_sock_init, NN_PULL);
|
312
|
+
SOCK_INIT_FUNC(bus_sock_init, NN_BUS);
|
313
|
+
|
314
|
+
static VALUE
|
315
|
+
sub_sock_subscribe(VALUE socket, VALUE channel)
|
316
|
+
{
|
317
|
+
int sock = sock_get(socket);
|
318
|
+
int err;
|
319
|
+
|
320
|
+
err = nn_setsockopt(
|
321
|
+
sock, NN_SUB, NN_SUB_SUBSCRIBE,
|
322
|
+
StringValuePtr(channel),
|
323
|
+
RSTRING_LEN(channel)
|
324
|
+
);
|
325
|
+
if (err < 0)
|
326
|
+
RAISE_SOCK_ERROR;
|
327
|
+
|
328
|
+
return socket;
|
329
|
+
}
|
330
|
+
|
331
|
+
static VALUE
|
332
|
+
srvy_set_deadline(VALUE self, VALUE deadline)
|
333
|
+
{
|
334
|
+
int sock = sock_get(self);
|
335
|
+
VALUE miliseconds = rb_funcall(deadline, rb_intern("*"), 1, INT2NUM(1000));
|
336
|
+
int timeout = FIX2INT(miliseconds);
|
337
|
+
int err;
|
338
|
+
|
339
|
+
err = nn_setsockopt(sock, NN_SURVEYOR, NN_SURVEYOR_DEADLINE, &timeout, sizeof(int));
|
340
|
+
if (err < 0)
|
341
|
+
RAISE_SOCK_ERROR;
|
342
|
+
|
343
|
+
return deadline;
|
344
|
+
}
|
345
|
+
|
346
|
+
static VALUE
|
347
|
+
srvy_get_deadline(VALUE self)
|
348
|
+
{
|
349
|
+
int sock = sock_get(self);
|
350
|
+
int deadline;
|
351
|
+
size_t size = sizeof(int);
|
352
|
+
|
353
|
+
int err;
|
354
|
+
|
355
|
+
err = nn_getsockopt(sock, NN_SURVEYOR, NN_SURVEYOR_DEADLINE, &deadline, &size);
|
356
|
+
if (err < 0)
|
357
|
+
RAISE_SOCK_ERROR;
|
358
|
+
|
359
|
+
return rb_funcall(INT2NUM(deadline), rb_intern("/"), 1, rb_float_new(1000));
|
360
|
+
}
|
361
|
+
|
362
|
+
static VALUE
|
363
|
+
nanomsg_terminate(VALUE self)
|
364
|
+
{
|
365
|
+
nn_term();
|
366
|
+
|
367
|
+
return Qnil;
|
368
|
+
}
|
369
|
+
|
370
|
+
struct device_op {
|
371
|
+
int sa, sb;
|
372
|
+
int err;
|
373
|
+
};
|
374
|
+
|
375
|
+
static VALUE
|
376
|
+
nanomsg_run_device_no_gvl(void* data)
|
377
|
+
{
|
378
|
+
struct device_op *pop = (struct device_op*) data;
|
379
|
+
|
380
|
+
pop->err = nn_device(pop->sa, pop->sb);
|
381
|
+
|
382
|
+
return Qnil;
|
383
|
+
}
|
384
|
+
|
385
|
+
static VALUE
|
386
|
+
nanomsg_run_device(VALUE self, VALUE a, VALUE b)
|
387
|
+
{
|
388
|
+
struct device_op dop;
|
389
|
+
|
390
|
+
dop.sa = sock_get(a);
|
391
|
+
dop.sb = sock_get(b);
|
392
|
+
|
393
|
+
rb_thread_blocking_region(nanomsg_run_device_no_gvl, &dop, NULL, NULL);
|
394
|
+
if (dop.err < 0)
|
395
|
+
RAISE_SOCK_ERROR;
|
396
|
+
|
397
|
+
return Qnil;
|
398
|
+
}
|
399
|
+
|
400
|
+
static VALUE
|
401
|
+
nanomsg_run_loopback(VALUE self, VALUE a)
|
402
|
+
{
|
403
|
+
struct device_op dop;
|
404
|
+
|
405
|
+
dop.sa = sock_get(a);
|
406
|
+
dop.sb = -1; // invalid socket, see documentation
|
407
|
+
|
408
|
+
rb_thread_blocking_region(nanomsg_run_device_no_gvl, &dop, NULL, NULL);
|
409
|
+
if (dop.err < 0)
|
410
|
+
RAISE_SOCK_ERROR;
|
411
|
+
|
412
|
+
return Qnil;
|
250
413
|
}
|
251
414
|
|
252
415
|
void
|
253
416
|
Init_nanomsg(void)
|
254
417
|
{
|
255
|
-
|
418
|
+
mNanoMsg = rb_define_module("NanoMsg");
|
419
|
+
cSocket = rb_define_class_under(mNanoMsg, "Socket", rb_cObject);
|
420
|
+
cPairSocket = rb_define_class_under(mNanoMsg, "PairSocket", cSocket);
|
421
|
+
|
422
|
+
cReqSocket = rb_define_class_under(mNanoMsg, "ReqSocket", cSocket);
|
423
|
+
cRepSocket = rb_define_class_under(mNanoMsg, "RepSocket", cSocket);
|
424
|
+
|
425
|
+
cPubSocket = rb_define_class_under(mNanoMsg, "PubSocket", cSocket);
|
426
|
+
cSubSocket = rb_define_class_under(mNanoMsg, "SubSocket", cSocket);
|
427
|
+
|
428
|
+
cSurveySocket = rb_define_class_under(mNanoMsg, "SurveySocket", cSocket);
|
429
|
+
cRespondSocket = rb_define_class_under(mNanoMsg, "RespondSocket", cSocket);
|
430
|
+
|
431
|
+
cPushSocket = rb_define_class_under(mNanoMsg, "PushSocket", cSocket);
|
432
|
+
cPullSocket = rb_define_class_under(mNanoMsg, "PullSocket", cSocket);
|
433
|
+
|
434
|
+
cBusSocket = rb_define_class_under(mNanoMsg, "BusSocket", cSocket);
|
256
435
|
|
257
|
-
|
258
|
-
cSocket = rb_define_class_under(cNanoMsg, "Socket", rb_cObject);
|
259
|
-
cPairSocket = rb_define_class_under(cNanoMsg, "PairSocket", cSocket);
|
436
|
+
ceSocketError = rb_define_class_under(mNanoMsg, "SocketError", rb_eIOError);
|
260
437
|
|
261
|
-
|
438
|
+
rb_define_singleton_method(mNanoMsg, "terminate", nanomsg_terminate, 0);
|
439
|
+
rb_define_singleton_method(mNanoMsg, "run_device", nanomsg_run_device, 2);
|
440
|
+
rb_define_singleton_method(mNanoMsg, "run_loopback", nanomsg_run_loopback, 1);
|
262
441
|
|
442
|
+
rb_define_alloc_func(cSocket, sock_alloc);
|
263
443
|
rb_define_method(cSocket, "bind", sock_bind, 1);
|
264
444
|
rb_define_method(cSocket, "connect", sock_connect, 1);
|
265
445
|
rb_define_method(cSocket, "send", sock_send, 1);
|
266
446
|
rb_define_method(cSocket, "recv", sock_recv, 0);
|
447
|
+
rb_define_method(cSocket, "close", sock_close, 0);
|
448
|
+
|
449
|
+
rb_define_method(cPairSocket, "initialize", pair_sock_init, -1);
|
450
|
+
|
451
|
+
rb_define_method(cReqSocket, "initialize", req_sock_init, -1);
|
452
|
+
rb_define_method(cRepSocket, "initialize", rep_sock_init, -1);
|
453
|
+
|
454
|
+
rb_define_method(cPubSocket, "initialize", pub_sock_init, -1);
|
455
|
+
rb_define_method(cSubSocket, "initialize", sub_sock_init, -1);
|
456
|
+
rb_define_method(cSubSocket, "subscribe", sub_sock_subscribe, 1);
|
457
|
+
|
458
|
+
rb_define_method(cSurveySocket, "initialize", srvy_sock_init, -1);
|
459
|
+
rb_define_method(cSurveySocket, "deadline=", srvy_set_deadline, 1);
|
460
|
+
rb_define_method(cSurveySocket, "deadline", srvy_get_deadline, 0);
|
461
|
+
rb_define_method(cRespondSocket, "initialize", resp_sock_init, -1);
|
462
|
+
|
463
|
+
rb_define_method(cPushSocket, "initialize", push_sock_init, -1);
|
464
|
+
rb_define_method(cPullSocket, "initialize", pull_sock_init, -1);
|
465
|
+
|
466
|
+
rb_define_method(cBusSocket, "initialize", bus_sock_init, -1);
|
267
467
|
|
268
|
-
|
269
|
-
rb_define_method(cPairSocket, "initialize", pair_sock_init, 0);
|
468
|
+
Init_constants(mNanoMsg);
|
270
469
|
}
|
271
470
|
|
data/ext/init.o
CHANGED
Binary file
|
data/ext/nanomsg.bundle
CHANGED
Binary file
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'BUS sockets' do
|
4
|
+
def self.examples_for_transport tbind
|
5
|
+
name = tbind.split('://').first
|
6
|
+
|
7
|
+
describe "transport #{name}" do
|
8
|
+
describe "using a broker topology" do
|
9
|
+
let!(:a) { NanoMsg::BusSocket.new }
|
10
|
+
let!(:b) { NanoMsg::BusSocket.new }
|
11
|
+
|
12
|
+
after(:each) do
|
13
|
+
[a, b].each(&:close)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'forwards messages to everyone (except the producer)' do
|
17
|
+
a.bind(tbind)
|
18
|
+
b.connect(tbind)
|
19
|
+
sleep 0.01
|
20
|
+
|
21
|
+
a.send 'test'
|
22
|
+
b.recv.should == 'test'
|
23
|
+
|
24
|
+
b.send 'ing'
|
25
|
+
a.recv.should == 'ing'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
examples_for_transport "ipc:///tmp/bus1.ipc"
|
32
|
+
examples_for_transport "tcp://127.0.0.1:5558"
|
33
|
+
examples_for_transport "inproc://bus1"
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
describe 'Devices' do
|
6
|
+
describe "connecting two BUSes" do
|
7
|
+
let(:a) { NanoMsg::BusSocket.new(NanoMsg::AF_SP_RAW) }
|
8
|
+
let(:b) { NanoMsg::BusSocket.new(NanoMsg::AF_SP_RAW) }
|
9
|
+
let(:c) { NanoMsg::BusSocket.new }
|
10
|
+
let(:d) { NanoMsg::BusSocket.new }
|
11
|
+
|
12
|
+
let(:adr1) { 'inproc://a' }
|
13
|
+
let(:adr2) { 'inproc://b' }
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
a.bind(adr1)
|
17
|
+
b.bind(adr2)
|
18
|
+
|
19
|
+
c.connect adr1
|
20
|
+
d.connect adr2
|
21
|
+
end
|
22
|
+
|
23
|
+
let!(:thread) {
|
24
|
+
Thread.start do
|
25
|
+
begin
|
26
|
+
NanoMsg.run_device(a, b)
|
27
|
+
rescue NanoMsg::Errno::ETERM
|
28
|
+
# Ignore, spec shutdown
|
29
|
+
end
|
30
|
+
end
|
31
|
+
}
|
32
|
+
|
33
|
+
it "forwards messages" do
|
34
|
+
sleep 0.01
|
35
|
+
c.send 'test'
|
36
|
+
timeout(1) do
|
37
|
+
d.recv.should == 'test'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
describe 'PUB/SUB sockets' do
|
6
|
+
describe 'PUB socket' do
|
7
|
+
it 'has no #recv method'
|
8
|
+
end
|
9
|
+
describe 'SUB socket' do
|
10
|
+
it 'has no #send method'
|
11
|
+
it 'allows subscribing to channels'
|
12
|
+
it 'allows unsubscribing to channels'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.examples_for_transport tbind
|
16
|
+
name = tbind.split('://').first
|
17
|
+
|
18
|
+
describe "transport #{name}" do
|
19
|
+
let(:pub) { NanoMsg::PubSocket.new }
|
20
|
+
let(:sub1) { NanoMsg::SubSocket.new }
|
21
|
+
let(:sub2) { NanoMsg::SubSocket.new }
|
22
|
+
|
23
|
+
after(:each) {
|
24
|
+
pub.close
|
25
|
+
sub1.close
|
26
|
+
sub2.close
|
27
|
+
}
|
28
|
+
|
29
|
+
around(:each) { |example|
|
30
|
+
timeout(1) { example.run }}
|
31
|
+
|
32
|
+
it 'allows simple pub/sub' do
|
33
|
+
pub.bind(tbind)
|
34
|
+
sub1.connect(tbind)
|
35
|
+
sub2.connect(tbind)
|
36
|
+
|
37
|
+
sub1.subscribe 'foo'
|
38
|
+
sub2.subscribe 'foo'
|
39
|
+
|
40
|
+
sub1.subscribe 'bar'
|
41
|
+
sleep 0.1
|
42
|
+
|
43
|
+
pub.send 'foo1234'
|
44
|
+
sub1.recv.should == 'foo1234'
|
45
|
+
sub2.recv.should == 'foo1234'
|
46
|
+
|
47
|
+
pub.send 'bar4567'
|
48
|
+
pub.send 'foo9999'
|
49
|
+
sub1.recv.should == 'bar4567'
|
50
|
+
sub2.recv.should == 'foo9999'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
examples_for_transport "ipc:///tmp/pubsub.ipc"
|
56
|
+
examples_for_transport "tcp://127.0.0.1:5557"
|
57
|
+
examples_for_transport "inproc://pubsub"
|
58
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'PUSH/PULL pipeline sockets' do
|
4
|
+
def self.examples_for_transport tbind
|
5
|
+
name = tbind.split('://').first
|
6
|
+
|
7
|
+
describe "transport #{name}" do
|
8
|
+
describe 'fanout' do
|
9
|
+
let(:producer) { NanoMsg::PushSocket.new }
|
10
|
+
let(:consumer1) { NanoMsg::PullSocket.new }
|
11
|
+
let(:consumer2) { NanoMsg::PullSocket.new }
|
12
|
+
|
13
|
+
after(:each) do
|
14
|
+
[producer, consumer2, consumer1].each(&:close)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'distributes load evenly' do
|
18
|
+
producer.bind(tbind)
|
19
|
+
consumer1.connect(tbind)
|
20
|
+
consumer2.connect(tbind)
|
21
|
+
sleep 0.1
|
22
|
+
|
23
|
+
100.times do |i|
|
24
|
+
producer.send i.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
n = [0, 0]
|
28
|
+
50.times do
|
29
|
+
[consumer1, consumer2].each_with_index do |consumer, idx|
|
30
|
+
v = consumer.recv.to_i
|
31
|
+
n[idx] += 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# This is about a 5% level of the binominal distribution
|
36
|
+
(n.first - n.last).abs.should < 10
|
37
|
+
end
|
38
|
+
end
|
39
|
+
describe 'fanin' do
|
40
|
+
let(:producer1) { NanoMsg::PushSocket.new }
|
41
|
+
let(:producer2) { NanoMsg::PushSocket.new }
|
42
|
+
let(:consumer) { NanoMsg::PullSocket.new }
|
43
|
+
|
44
|
+
after(:each) do
|
45
|
+
[producer1, producer2, consumer].each(&:close)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'consumes results fairly' do
|
49
|
+
consumer.bind(tbind)
|
50
|
+
producer1.connect(tbind)
|
51
|
+
producer2.connect(tbind)
|
52
|
+
|
53
|
+
100.times do |i|
|
54
|
+
producer = [producer1, producer2][i%2]
|
55
|
+
|
56
|
+
producer.send i.to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
100.times do |i|
|
60
|
+
consumer.recv.to_i.should == i
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
examples_for_transport "ipc:///tmp/reqrep.ipc"
|
68
|
+
examples_for_transport "tcp://127.0.0.1:5555"
|
69
|
+
examples_for_transport "inproc://reqrep"
|
70
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'REQ/REP sockets' do
|
4
|
+
let(:req) { NanoMsg::ReqSocket.new }
|
5
|
+
let(:rep) { NanoMsg::RepSocket.new }
|
6
|
+
|
7
|
+
after(:each) do
|
8
|
+
req.close
|
9
|
+
rep.close
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.examples_for_transport tbind
|
13
|
+
name = tbind.split('://').first
|
14
|
+
|
15
|
+
describe "transport #{name}" do
|
16
|
+
it 'allows simple req/rep' do
|
17
|
+
req.bind(tbind)
|
18
|
+
rep.connect(tbind)
|
19
|
+
|
20
|
+
req.send 'req1'
|
21
|
+
|
22
|
+
rep.recv.should == 'req1'
|
23
|
+
rep.send 'rep1'
|
24
|
+
|
25
|
+
req.recv.should == 'rep1'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
examples_for_transport "ipc:///tmp/reqrep.ipc"
|
31
|
+
examples_for_transport "tcp://127.0.0.1:5555"
|
32
|
+
examples_for_transport "inproc://reqrep"
|
33
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'SURVEY sockets' do
|
4
|
+
let(:surveyor) { NanoMsg::SurveySocket.new }
|
5
|
+
let(:resp1) { NanoMsg::RespondSocket.new }
|
6
|
+
let(:resp2) { NanoMsg::RespondSocket.new }
|
7
|
+
|
8
|
+
after(:each) do
|
9
|
+
[surveyor, resp2, resp1].each(&:close)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.examples_for_transport tbind
|
13
|
+
name = tbind.split('://').first
|
14
|
+
|
15
|
+
describe "transport #{name}" do
|
16
|
+
it 'allows simple surveys' do
|
17
|
+
surveyor.deadline.should == 1 # default: 1 second
|
18
|
+
surveyor.deadline = 0.1 # 100ms
|
19
|
+
surveyor.deadline.should == 0.1
|
20
|
+
|
21
|
+
surveyor.bind(tbind)
|
22
|
+
|
23
|
+
resp1.connect(tbind)
|
24
|
+
resp2.connect(tbind)
|
25
|
+
|
26
|
+
sleep 0.1
|
27
|
+
surveyor.send 'u there?'
|
28
|
+
resp1.recv.should == 'u there?'
|
29
|
+
resp2.recv.should == 'u there?'
|
30
|
+
|
31
|
+
resp1.send 'KTHNXBYE'
|
32
|
+
surveyor.recv.should == 'KTHNXBYE'
|
33
|
+
|
34
|
+
# nanomsg/tests/survey.c says this should be EFSM, the documentation
|
35
|
+
# says it should be ETIMEDOUT. Reality wins.
|
36
|
+
begin
|
37
|
+
surveyor.recv
|
38
|
+
rescue NanoMsg::Errno::EFSM
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
examples_for_transport "ipc:///tmp/reqrep.ipc"
|
45
|
+
examples_for_transport "tcp://127.0.0.1:5555"
|
46
|
+
examples_for_transport "inproc://reqrep"
|
47
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanomsg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,19 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description: ! " nanomsg
|
15
|
-
(nanomsg.org)\n\n nanomsg library is a high-performance implementation of several
|
14
|
+
description: ! " nanomsg library is a high-performance implementation of several
|
16
15
|
\"scalability \n protocols\". Scalability protocol's job is to define how multiple
|
17
|
-
applications \n communicate to form a single distributed application.
|
18
|
-
|
19
|
-
- simple one-to-one communication\n BUS - simple many-to-many communication\n
|
20
|
-
\ REQREP - allows to build clusters of stateless services to process user requests\n
|
21
|
-
\ PUBSUB - distributes messages to large sets of interested subscribers\n FANIN
|
22
|
-
- aggregates messages from multiple sources\n FANOUT - load balances messages
|
23
|
-
among many destinations\n SURVEY - allows to query state of multiple applications
|
24
|
-
in a single go\n\n WARNING: nanomsg is still in alpha stage!\n"
|
16
|
+
applications \n communicate to form a single distributed application. WARNING:
|
17
|
+
nanomsg is still in alpha stage!\n"
|
25
18
|
email: kaspar.schiess@absurd.li
|
26
19
|
executables: []
|
27
20
|
extensions:
|
@@ -34,16 +27,26 @@ files:
|
|
34
27
|
- README
|
35
28
|
- lib/nanomsg/pair_socket.rb
|
36
29
|
- lib/nanomsg.rb
|
30
|
+
- ext/constants.c
|
31
|
+
- ext/constants.h
|
32
|
+
- ext/constants.o
|
37
33
|
- ext/extconf.rb
|
38
34
|
- ext/init.c
|
39
35
|
- ext/init.o
|
40
36
|
- ext/Makefile
|
41
|
-
- ext/mkmf.log
|
42
37
|
- ext/nanomsg.bundle
|
43
|
-
-
|
38
|
+
- examples/bus.rb
|
39
|
+
- examples/bus_device.rb
|
44
40
|
- examples/pair.rb
|
45
41
|
- examples/roundtrip_latency.rb
|
42
|
+
- spec/lib/nanomsg/bus_spec.rb
|
43
|
+
- spec/lib/nanomsg/device_spec.rb
|
46
44
|
- spec/lib/nanomsg/pair_socket_spec.rb
|
45
|
+
- spec/lib/nanomsg/pub_sub_spec.rb
|
46
|
+
- spec/lib/nanomsg/push_pull_spec.rb
|
47
|
+
- spec/lib/nanomsg/req_rep_spec.rb
|
48
|
+
- spec/lib/nanomsg/survey_spec.rb
|
49
|
+
- spec/lib/nanomsg_spec.rb
|
47
50
|
- spec/spec_helper.rb
|
48
51
|
homepage: https://bitbucket.org/kschiess/nanomsg
|
49
52
|
licenses: []
|
data/ext/mkmf.log
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
have_library: checking for main() in -lnanomsg... -------------------- yes
|
2
|
-
|
3
|
-
"/usr/local/bin/gcc-4.2 -o conftest -I/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/include/ruby-1.9.1/x86_64-darwin12.3.0 -I/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/include/ruby-1.9.1/ruby/backward -I/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/include/ruby-1.9.1 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/libxslt/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -I/usr/local/opt/sqlite/include -O3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -fno-common -pipe conftest.c -L. -L/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/libxslt/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/sqlite/lib -L. -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/libxslt/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/sqlite/lib -lruby.1.9.1 -lpthread -ldl -lobjc "
|
4
|
-
checked program was:
|
5
|
-
/* begin */
|
6
|
-
1: #include "ruby.h"
|
7
|
-
2:
|
8
|
-
3: int main() {return 0;}
|
9
|
-
/* end */
|
10
|
-
|
11
|
-
"/usr/local/bin/gcc-4.2 -o conftest -I/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/include/ruby-1.9.1/x86_64-darwin12.3.0 -I/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/include/ruby-1.9.1/ruby/backward -I/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/include/ruby-1.9.1 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -I/usr/local/opt/libyaml/include -I/usr/local/opt/readline/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/libxslt/include -I/usr/local/opt/libksba/include -I/usr/local/opt/openssl/include -I/usr/local/opt/sqlite/include -O3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -fno-common -pipe conftest.c -L. -L/Users/kschiess/.rvm/rubies/ruby-1.9.3-p392-turbo/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/libxslt/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/sqlite/lib -L. -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/libxslt/lib -L/usr/local/opt/libksba/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/sqlite/lib -lruby.1.9.1 -lnanomsg -lpthread -ldl -lobjc "
|
12
|
-
checked program was:
|
13
|
-
/* begin */
|
14
|
-
1: #include "ruby.h"
|
15
|
-
2:
|
16
|
-
3: /*top*/
|
17
|
-
4: int main() {return 0;}
|
18
|
-
5: int t() { void ((*volatile p)()); p = (void ((*)()))main; return 0; }
|
19
|
-
/* end */
|
20
|
-
|
21
|
-
--------------------
|
22
|
-
|
data/ext/nanomsg.o
DELETED
Binary file
|