noderb 0.0.2 → 0.0.3
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/README.md +2 -2
- data/ext/noderb_extension/noderb.c +41 -20
- data/lib/noderb/connection.rb +7 -14
- data/lib/noderb/next_tick.rb +17 -0
- data/lib/noderb/process.rb +1 -1
- data/lib/noderb/version.rb +3 -0
- data/lib/noderb.rb +4 -22
- metadata +3 -1
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## What is it?
|
4
4
|
|
5
|
-
NodeJs + Ruby
|
5
|
+
NodeJs - JavaScript + Ruby
|
6
6
|
|
7
7
|
## Status
|
8
8
|
|
@@ -18,7 +18,7 @@ Somehow.
|
|
18
18
|
|
19
19
|
## Dependencies
|
20
20
|
|
21
|
-
|
21
|
+
No external dependencies except compiler for native extension.
|
22
22
|
|
23
23
|
## License
|
24
24
|
|
@@ -7,6 +7,12 @@ VALUE nodeRbProcess;
|
|
7
7
|
|
8
8
|
VALUE nodeRbModules;
|
9
9
|
|
10
|
+
int nodeRbNextTickStatus = 0;
|
11
|
+
|
12
|
+
typedef struct {
|
13
|
+
|
14
|
+
} nodeRb_next_tick_handle;
|
15
|
+
|
10
16
|
typedef struct {
|
11
17
|
uv_write_t req;
|
12
18
|
uv_buf_t buf;
|
@@ -23,6 +29,7 @@ typedef struct {
|
|
23
29
|
uv_pipe_t* stderr;
|
24
30
|
} nodeRb_process_handle;
|
25
31
|
|
32
|
+
|
26
33
|
VALUE nodeRb_register_instance(VALUE self, VALUE instance) {
|
27
34
|
rb_ary_push(rb_iv_get(self, "@instances"), instance);
|
28
35
|
}
|
@@ -47,13 +54,18 @@ int nodeRb_handle_error(int e) {
|
|
47
54
|
|
48
55
|
void nodeRb_next_tick(uv_idle_t* handle, int status) {
|
49
56
|
uv_idle_stop(handle);
|
57
|
+
free(handle);
|
58
|
+
nodeRbNextTickStatus = 0;
|
50
59
|
rb_funcall(nodeRb, rb_intern("next_tick_execute"), 0);
|
51
60
|
}
|
52
61
|
|
53
62
|
VALUE nodeRb_nextTick(VALUE self) {
|
54
|
-
|
55
|
-
|
56
|
-
|
63
|
+
if(nodeRbNextTickStatus == 0){
|
64
|
+
uv_idle_t* handle = malloc(sizeof(uv_idle_t));
|
65
|
+
uv_idle_init(handle);
|
66
|
+
nodeRbNextTickStatus = 1;
|
67
|
+
uv_idle_start(handle, nodeRb_next_tick);
|
68
|
+
}
|
57
69
|
}
|
58
70
|
|
59
71
|
VALUE nodeRb_start(VALUE self) {
|
@@ -85,7 +97,7 @@ VALUE nodeRb_send_data(VALUE self, VALUE data) {
|
|
85
97
|
write_req_t* wr = malloc(sizeof (write_req_t));
|
86
98
|
wr->buf.base = rb_string_value_cstr(&data);
|
87
99
|
wr->buf.len = RSTRING_LEN(data);
|
88
|
-
VALUE rhandler = rb_iv_get(self, "@
|
100
|
+
VALUE rhandler = rb_iv_get(self, "@_handle");
|
89
101
|
uv_stream_t *handle;
|
90
102
|
Data_Get_Struct(rhandler, uv_stream_t, handle);
|
91
103
|
uv_write(&wr->req, handle, &wr->buf, 1, nodeRb_after_write);
|
@@ -95,8 +107,8 @@ void nodeRb_on_close(uv_handle_t* client) {
|
|
95
107
|
nodeRb_client *client_data = client->data;
|
96
108
|
VALUE object = nodeRb_get_class_from_id(client_data->connection);
|
97
109
|
rb_funcall(object, rb_intern("on_close"), 0, 0);
|
98
|
-
|
99
|
-
rb_iv_set(object, "@
|
110
|
+
nodeRb_unregister_instance(nodeRb, object);
|
111
|
+
rb_iv_set(object, "@_handle", Qnil);
|
100
112
|
free(client_data);
|
101
113
|
free(client);
|
102
114
|
client_data = NULL;
|
@@ -109,7 +121,7 @@ void nodeRb_on_shutdown(uv_shutdown_t* req, int status) {
|
|
109
121
|
|
110
122
|
VALUE nodeRb_close_connection(VALUE self) {
|
111
123
|
uv_shutdown_t* req = malloc(sizeof (uv_shutdown_t));
|
112
|
-
VALUE rhandler = rb_iv_get(self, "@
|
124
|
+
VALUE rhandler = rb_iv_get(self, "@_handle");
|
113
125
|
uv_stream_t *handle;
|
114
126
|
Data_Get_Struct(rhandler, uv_stream_t, handle);
|
115
127
|
uv_shutdown(req, handle, nodeRb_on_shutdown);
|
@@ -121,8 +133,6 @@ void nodeRb_on_read(uv_stream_t* client, ssize_t nread, uv_buf_t buf) {
|
|
121
133
|
if (buf.base) {
|
122
134
|
free(buf.base);
|
123
135
|
}
|
124
|
-
uv_shutdown_t* req = malloc(sizeof (uv_shutdown_t));
|
125
|
-
uv_shutdown(req, client, nodeRb_on_shutdown);
|
126
136
|
return;
|
127
137
|
}
|
128
138
|
|
@@ -149,9 +159,9 @@ void nodeRb_on_server_connect(uv_stream_t* server, int status) {
|
|
149
159
|
if (nodeRb_handle_error(r)) return;
|
150
160
|
VALUE clazz = rb_path2class(server->data);
|
151
161
|
VALUE obj = rb_funcall(clazz, rb_intern("new"), 0, 0);
|
152
|
-
|
162
|
+
nodeRb_register_instance(nodeRb, obj);
|
153
163
|
rb_funcall(obj, rb_intern("on_connect"), 0, 0);
|
154
|
-
rb_iv_set(obj, "@
|
164
|
+
rb_iv_set(obj, "@_handle", Data_Wrap_Struct(nodeRbPointer, 0, NULL, client));
|
155
165
|
long id = rb_num2long(rb_obj_id(obj));
|
156
166
|
client_data->connection = id;
|
157
167
|
client->data = client_data;
|
@@ -173,7 +183,7 @@ VALUE nodeRb_startServer(VALUE self, VALUE address, VALUE port, VALUE clazz) {
|
|
173
183
|
void nodeRb_on_client_connect(uv_connect_t* client, int status) {
|
174
184
|
nodeRb_client *client_data = client->handle->data;
|
175
185
|
VALUE obj = nodeRb_get_class_from_id(client_data->connection);
|
176
|
-
rb_iv_set(obj, "@
|
186
|
+
rb_iv_set(obj, "@_handle", Data_Wrap_Struct(nodeRbPointer, 0, NULL, client->handle));
|
177
187
|
rb_funcall(obj, rb_intern("on_connect"), 0, 0);
|
178
188
|
uv_read_start((uv_stream_t*) client->handle, nodeRb_read_alloc, nodeRb_on_read);
|
179
189
|
}
|
@@ -186,7 +196,7 @@ VALUE nodeRb_startClient(VALUE self, VALUE address, VALUE port, VALUE clazz) {
|
|
186
196
|
int r = uv_tcp_connect(connect, handle, socket, nodeRb_on_client_connect);
|
187
197
|
if (nodeRb_handle_error(r)) return Qnil;
|
188
198
|
nodeRb_client *client_data = malloc(sizeof (nodeRb_client));
|
189
|
-
VALUE obj =
|
199
|
+
VALUE obj = clazz;
|
190
200
|
long id = rb_num2long(rb_obj_id(obj));
|
191
201
|
client_data->connection = id;
|
192
202
|
handle->data = client_data;
|
@@ -261,7 +271,8 @@ VALUE nodeRb_startProcess(VALUE self, VALUE executable, VALUE arguments, VALUE e
|
|
261
271
|
// Executable
|
262
272
|
options.file = rb_string_value_cstr(&executable);
|
263
273
|
// Arguments
|
264
|
-
long len
|
274
|
+
long len;
|
275
|
+
len = RARRAY_LEN(arguments);
|
265
276
|
char* args[len + 2];
|
266
277
|
args[0] = rb_string_value_cstr(&executable);
|
267
278
|
args[len + 1] = NULL;
|
@@ -274,8 +285,18 @@ VALUE nodeRb_startProcess(VALUE self, VALUE executable, VALUE arguments, VALUE e
|
|
274
285
|
}
|
275
286
|
}
|
276
287
|
// Environment
|
277
|
-
|
278
|
-
|
288
|
+
len = RARRAY_LEN(environment);
|
289
|
+
char* env[len+1];
|
290
|
+
options.env = env;
|
291
|
+
options.env[len] = NULL;
|
292
|
+
if (len > 0) {
|
293
|
+
long i;
|
294
|
+
VALUE *arr = RARRAY_PTR(environment);
|
295
|
+
for (i = 0; i < len; i++) {
|
296
|
+
options.env[i] = rb_string_value_cstr(&arr[i]);
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
279
300
|
// Working directory
|
280
301
|
options.cwd = rb_string_value_cstr(&directory);
|
281
302
|
// NodeRb helpers
|
@@ -316,15 +337,15 @@ void Init_noderb_extension() {
|
|
316
337
|
// Define module
|
317
338
|
nodeRb = rb_define_module("NodeRb");
|
318
339
|
nodeRbPointer = rb_define_class_under(nodeRb, "Pointer", rb_cObject);
|
319
|
-
nodeRbConnection =
|
320
|
-
nodeRbProcess =
|
340
|
+
nodeRbConnection = rb_define_module_under(nodeRb, "Connection");
|
341
|
+
nodeRbProcess = rb_define_module_under(nodeRb, "Process");
|
321
342
|
// Define connection methods
|
322
|
-
rb_define_method(nodeRbConnection, "
|
343
|
+
rb_define_method(nodeRbConnection, "write", nodeRb_send_data, 1);
|
323
344
|
rb_define_method(nodeRbConnection, "close_connection", nodeRb_close_connection, 0);
|
324
345
|
// Define process methods
|
325
346
|
rb_define_method(nodeRbProcess, "write", nodeRb_process_write, 1);
|
326
347
|
rb_define_method(nodeRbProcess, "kill", nodeRb_process_kill, 1);
|
327
|
-
//
|
348
|
+
// Run code on next tick
|
328
349
|
rb_define_singleton_method(nodeRb, "native_next_tick", nodeRb_nextTick, 0);
|
329
350
|
// Define starting methods
|
330
351
|
rb_define_singleton_method(nodeRb, "start", nodeRb_start, 0);
|
data/lib/noderb/connection.rb
CHANGED
@@ -1,21 +1,14 @@
|
|
1
1
|
module NodeRb
|
2
|
+
module Connection
|
2
3
|
|
3
|
-
|
4
|
+
def on_connect
|
5
|
+
end
|
4
6
|
|
5
|
-
|
6
|
-
attr_accessor :connections
|
7
|
-
end
|
8
|
-
|
9
|
-
def noderb_initialize
|
10
|
-
Connection.connections << self
|
11
|
-
end
|
12
|
-
|
13
|
-
def noderb_dispose
|
14
|
-
Connection.connections.delete(self)
|
15
|
-
end
|
16
|
-
|
7
|
+
def on_data data
|
17
8
|
end
|
18
9
|
|
19
|
-
|
10
|
+
def on_close
|
11
|
+
end
|
20
12
|
|
13
|
+
end
|
21
14
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module NodeRb
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def next_tick &block
|
5
|
+
( @next_tick ||= [] ) << block
|
6
|
+
NodeRb.native_next_tick
|
7
|
+
end
|
8
|
+
|
9
|
+
def next_tick_execute
|
10
|
+
blocks, @next_tick = @next_tick, []
|
11
|
+
blocks.each do |block|
|
12
|
+
block.call
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/noderb/process.rb
CHANGED
data/lib/noderb.rb
CHANGED
@@ -1,25 +1,7 @@
|
|
1
|
+
# Native extension
|
1
2
|
require "noderb_extension"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
VERSION = "0.0.1" unless const_defined?(:VERSION)
|
6
|
-
|
7
|
-
class << self
|
8
|
-
|
9
|
-
def next_tick &block
|
10
|
-
( @next_tick ||= [] ) << block
|
11
|
-
NodeRb.native_next_tick
|
12
|
-
end
|
13
|
-
|
14
|
-
def next_tick_execute
|
15
|
-
@next_tick.each do |block|
|
16
|
-
block.call
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
3
|
+
# Ruby extension
|
4
|
+
require "noderb/version"
|
5
|
+
require "noderb/next_tick"
|
24
6
|
require "noderb/connection"
|
25
7
|
require "noderb/process"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: noderb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -21,7 +21,9 @@ extensions:
|
|
21
21
|
extra_rdoc_files: []
|
22
22
|
files:
|
23
23
|
- lib/noderb/connection.rb
|
24
|
+
- lib/noderb/next_tick.rb
|
24
25
|
- lib/noderb/process.rb
|
26
|
+
- lib/noderb/version.rb
|
25
27
|
- lib/noderb.rb
|
26
28
|
- ext/noderb_extension/extconf.rb
|
27
29
|
- ext/noderb_extension/libuv/AUTHORS
|