noderb 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|