grpc 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.rubocop.yml +10 -0
- data/.rubocop_todo.yml +52 -0
- data/Gemfile +4 -0
- data/README.md +82 -0
- data/Rakefile +54 -0
- data/bin/apis/google/protobuf/empty.rb +44 -0
- data/bin/apis/pubsub_demo.rb +267 -0
- data/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
- data/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
- data/bin/interop/README.md +8 -0
- data/bin/interop/interop_client.rb +334 -0
- data/bin/interop/interop_server.rb +192 -0
- data/bin/interop/test/cpp/interop/empty.rb +44 -0
- data/bin/interop/test/cpp/interop/messages.rb +89 -0
- data/bin/interop/test/cpp/interop/test.rb +43 -0
- data/bin/interop/test/cpp/interop/test_services.rb +60 -0
- data/bin/math.proto +80 -0
- data/bin/math.rb +61 -0
- data/bin/math_client.rb +147 -0
- data/bin/math_server.rb +190 -0
- data/bin/math_services.rb +56 -0
- data/bin/noproto_client.rb +108 -0
- data/bin/noproto_server.rb +112 -0
- data/ext/grpc/extconf.rb +76 -0
- data/ext/grpc/rb_byte_buffer.c +241 -0
- data/ext/grpc/rb_byte_buffer.h +54 -0
- data/ext/grpc/rb_call.c +569 -0
- data/ext/grpc/rb_call.h +59 -0
- data/ext/grpc/rb_channel.c +264 -0
- data/ext/grpc/rb_channel.h +49 -0
- data/ext/grpc/rb_channel_args.c +154 -0
- data/ext/grpc/rb_channel_args.h +52 -0
- data/ext/grpc/rb_completion_queue.c +185 -0
- data/ext/grpc/rb_completion_queue.h +50 -0
- data/ext/grpc/rb_credentials.c +281 -0
- data/ext/grpc/rb_credentials.h +50 -0
- data/ext/grpc/rb_event.c +361 -0
- data/ext/grpc/rb_event.h +53 -0
- data/ext/grpc/rb_grpc.c +274 -0
- data/ext/grpc/rb_grpc.h +74 -0
- data/ext/grpc/rb_metadata.c +215 -0
- data/ext/grpc/rb_metadata.h +53 -0
- data/ext/grpc/rb_server.c +278 -0
- data/ext/grpc/rb_server.h +50 -0
- data/ext/grpc/rb_server_credentials.c +210 -0
- data/ext/grpc/rb_server_credentials.h +50 -0
- data/grpc.gemspec +41 -0
- data/lib/grpc.rb +39 -0
- data/lib/grpc/core/event.rb +44 -0
- data/lib/grpc/core/time_consts.rb +71 -0
- data/lib/grpc/errors.rb +61 -0
- data/lib/grpc/generic/active_call.rb +536 -0
- data/lib/grpc/generic/bidi_call.rb +221 -0
- data/lib/grpc/generic/client_stub.rb +413 -0
- data/lib/grpc/generic/rpc_desc.rb +150 -0
- data/lib/grpc/generic/rpc_server.rb +404 -0
- data/lib/grpc/generic/service.rb +235 -0
- data/lib/grpc/logconfig.rb +40 -0
- data/lib/grpc/version.rb +33 -0
- data/spec/alloc_spec.rb +44 -0
- data/spec/byte_buffer_spec.rb +67 -0
- data/spec/call_spec.rb +163 -0
- data/spec/channel_spec.rb +181 -0
- data/spec/client_server_spec.rb +372 -0
- data/spec/completion_queue_spec.rb +74 -0
- data/spec/credentials_spec.rb +71 -0
- data/spec/event_spec.rb +53 -0
- data/spec/generic/active_call_spec.rb +373 -0
- data/spec/generic/client_stub_spec.rb +519 -0
- data/spec/generic/rpc_desc_spec.rb +357 -0
- data/spec/generic/rpc_server_pool_spec.rb +139 -0
- data/spec/generic/rpc_server_spec.rb +404 -0
- data/spec/generic/service_spec.rb +342 -0
- data/spec/metadata_spec.rb +64 -0
- data/spec/server_credentials_spec.rb +69 -0
- data/spec/server_spec.rb +212 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/testdata/README +1 -0
- data/spec/testdata/ca.pem +15 -0
- data/spec/testdata/server1.key +16 -0
- data/spec/testdata/server1.pem +16 -0
- data/spec/time_consts_spec.rb +89 -0
- metadata +353 -0
data/ext/grpc/rb_call.h
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2015, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#ifndef GRPC_RB_CALL_H_
|
35
|
+
#define GRPC_RB_CALL_H_
|
36
|
+
|
37
|
+
#include <grpc/grpc.h>
|
38
|
+
#include <ruby.h>
|
39
|
+
|
40
|
+
/* Gets the wrapped call from a VALUE. */
|
41
|
+
grpc_call* grpc_rb_get_wrapped_call(VALUE v);
|
42
|
+
|
43
|
+
/* Gets the VALUE corresponding to given grpc_call. */
|
44
|
+
VALUE grpc_rb_wrap_call(grpc_call* c);
|
45
|
+
|
46
|
+
/* Provides the details of an call error */
|
47
|
+
const char* grpc_call_error_detail_of(grpc_call_error err);
|
48
|
+
|
49
|
+
/* rb_cCall is the Call class whose instances proxy grpc_call. */
|
50
|
+
extern VALUE rb_cCall;
|
51
|
+
|
52
|
+
/* rb_cCallError is the ruby class of the exception thrown during call
|
53
|
+
operations. */
|
54
|
+
extern VALUE rb_eCallError;
|
55
|
+
|
56
|
+
/* Initializes the Call class. */
|
57
|
+
void Init_grpc_call();
|
58
|
+
|
59
|
+
#endif /* GRPC_RB_CALL_H_ */
|
@@ -0,0 +1,264 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2015, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#include "rb_channel.h"
|
35
|
+
|
36
|
+
#include <ruby.h>
|
37
|
+
|
38
|
+
#include <grpc/grpc.h>
|
39
|
+
#include <grpc/grpc_security.h>
|
40
|
+
#include "rb_grpc.h"
|
41
|
+
#include "rb_call.h"
|
42
|
+
#include "rb_channel_args.h"
|
43
|
+
#include "rb_completion_queue.h"
|
44
|
+
#include "rb_credentials.h"
|
45
|
+
#include "rb_server.h"
|
46
|
+
|
47
|
+
/* id_channel is the name of the hidden ivar that preserves a reference to the
|
48
|
+
* channel on a call, so that calls are not GCed before their channel. */
|
49
|
+
static ID id_channel;
|
50
|
+
|
51
|
+
/* id_target is the name of the hidden ivar that preserves a reference to the
|
52
|
+
* target string used to create the call, preserved so that is does not get
|
53
|
+
* GCed before the channel */
|
54
|
+
static ID id_target;
|
55
|
+
|
56
|
+
/* Used during the conversion of a hash to channel args during channel setup */
|
57
|
+
static VALUE rb_cChannelArgs;
|
58
|
+
|
59
|
+
/* grpc_rb_channel wraps a grpc_channel. It provides a peer ruby object,
|
60
|
+
* 'mark' to minimize copying when a channel is created from ruby. */
|
61
|
+
typedef struct grpc_rb_channel {
|
62
|
+
/* Holder of ruby objects involved in constructing the channel */
|
63
|
+
VALUE mark;
|
64
|
+
/* The actual channel */
|
65
|
+
grpc_channel *wrapped;
|
66
|
+
} grpc_rb_channel;
|
67
|
+
|
68
|
+
/* Destroys Channel instances. */
|
69
|
+
static void grpc_rb_channel_free(void *p) {
|
70
|
+
grpc_rb_channel *ch = NULL;
|
71
|
+
if (p == NULL) {
|
72
|
+
return;
|
73
|
+
};
|
74
|
+
ch = (grpc_rb_channel *)p;
|
75
|
+
|
76
|
+
/* Deletes the wrapped object if the mark object is Qnil, which indicates
|
77
|
+
* that no other object is the actual owner. */
|
78
|
+
if (ch->wrapped != NULL && ch->mark == Qnil) {
|
79
|
+
grpc_channel_destroy(ch->wrapped);
|
80
|
+
rb_warning("channel gc: destroyed the c channel");
|
81
|
+
} else {
|
82
|
+
rb_warning("channel gc: did not destroy the c channel");
|
83
|
+
}
|
84
|
+
|
85
|
+
xfree(p);
|
86
|
+
}
|
87
|
+
|
88
|
+
/* Protects the mark object from GC */
|
89
|
+
static void grpc_rb_channel_mark(void *p) {
|
90
|
+
grpc_rb_channel *channel = NULL;
|
91
|
+
if (p == NULL) {
|
92
|
+
return;
|
93
|
+
}
|
94
|
+
channel = (grpc_rb_channel *)p;
|
95
|
+
if (channel->mark != Qnil) {
|
96
|
+
rb_gc_mark(channel->mark);
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
/* Allocates grpc_rb_channel instances. */
|
101
|
+
static VALUE grpc_rb_channel_alloc(VALUE cls) {
|
102
|
+
grpc_rb_channel *wrapper = ALLOC(grpc_rb_channel);
|
103
|
+
wrapper->wrapped = NULL;
|
104
|
+
wrapper->mark = Qnil;
|
105
|
+
return Data_Wrap_Struct(cls, grpc_rb_channel_mark, grpc_rb_channel_free,
|
106
|
+
wrapper);
|
107
|
+
}
|
108
|
+
|
109
|
+
/*
|
110
|
+
call-seq:
|
111
|
+
insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'})
|
112
|
+
creds = ...
|
113
|
+
secure_channel = Channel:new("myhost:443", {'arg1': 'value1'}, creds)
|
114
|
+
|
115
|
+
Creates channel instances. */
|
116
|
+
static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
|
117
|
+
VALUE channel_args = Qnil;
|
118
|
+
VALUE credentials = Qnil;
|
119
|
+
VALUE target = Qnil;
|
120
|
+
grpc_rb_channel *wrapper = NULL;
|
121
|
+
grpc_credentials *creds = NULL;
|
122
|
+
grpc_channel *ch = NULL;
|
123
|
+
char *target_chars = NULL;
|
124
|
+
grpc_channel_args args;
|
125
|
+
MEMZERO(&args, grpc_channel_args, 1);
|
126
|
+
|
127
|
+
/* "21" == 2 mandatory args, 1 (credentials) is optional */
|
128
|
+
rb_scan_args(argc, argv, "21", &target, &channel_args, &credentials);
|
129
|
+
|
130
|
+
Data_Get_Struct(self, grpc_rb_channel, wrapper);
|
131
|
+
target_chars = StringValueCStr(target);
|
132
|
+
grpc_rb_hash_convert_to_channel_args(channel_args, &args);
|
133
|
+
if (credentials == Qnil) {
|
134
|
+
ch = grpc_channel_create(target_chars, &args);
|
135
|
+
} else {
|
136
|
+
creds = grpc_rb_get_wrapped_credentials(credentials);
|
137
|
+
ch = grpc_secure_channel_create(creds, target_chars, &args);
|
138
|
+
}
|
139
|
+
if (args.args != NULL) {
|
140
|
+
xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
|
141
|
+
}
|
142
|
+
if (ch == NULL) {
|
143
|
+
rb_raise(rb_eRuntimeError, "could not create an rpc channel to target:%s",
|
144
|
+
target_chars);
|
145
|
+
}
|
146
|
+
rb_ivar_set(self, id_target, target);
|
147
|
+
wrapper->wrapped = ch;
|
148
|
+
return self;
|
149
|
+
}
|
150
|
+
|
151
|
+
/* Clones Channel instances.
|
152
|
+
|
153
|
+
Gives Channel a consistent implementation of Ruby's object copy/dup
|
154
|
+
protocol. */
|
155
|
+
static VALUE grpc_rb_channel_init_copy(VALUE copy, VALUE orig) {
|
156
|
+
grpc_rb_channel *orig_ch = NULL;
|
157
|
+
grpc_rb_channel *copy_ch = NULL;
|
158
|
+
|
159
|
+
if (copy == orig) {
|
160
|
+
return copy;
|
161
|
+
}
|
162
|
+
|
163
|
+
/* Raise an error if orig is not a channel object or a subclass. */
|
164
|
+
if (TYPE(orig) != T_DATA ||
|
165
|
+
RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_channel_free) {
|
166
|
+
rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(rb_cChannel));
|
167
|
+
}
|
168
|
+
|
169
|
+
Data_Get_Struct(orig, grpc_rb_channel, orig_ch);
|
170
|
+
Data_Get_Struct(copy, grpc_rb_channel, copy_ch);
|
171
|
+
|
172
|
+
/* use ruby's MEMCPY to make a byte-for-byte copy of the channel wrapper
|
173
|
+
* object. */
|
174
|
+
MEMCPY(copy_ch, orig_ch, grpc_rb_channel, 1);
|
175
|
+
return copy;
|
176
|
+
}
|
177
|
+
|
178
|
+
/* Create a call given a grpc_channel, in order to call method. The request
|
179
|
+
is not sent until grpc_call_invoke is called. */
|
180
|
+
static VALUE grpc_rb_channel_create_call(VALUE self, VALUE method, VALUE host,
|
181
|
+
VALUE deadline) {
|
182
|
+
VALUE res = Qnil;
|
183
|
+
grpc_rb_channel *wrapper = NULL;
|
184
|
+
grpc_channel *ch = NULL;
|
185
|
+
grpc_call *call = NULL;
|
186
|
+
char *method_chars = StringValueCStr(method);
|
187
|
+
char *host_chars = StringValueCStr(host);
|
188
|
+
|
189
|
+
Data_Get_Struct(self, grpc_rb_channel, wrapper);
|
190
|
+
ch = wrapper->wrapped;
|
191
|
+
if (ch == NULL) {
|
192
|
+
rb_raise(rb_eRuntimeError, "closed!");
|
193
|
+
}
|
194
|
+
|
195
|
+
call =
|
196
|
+
grpc_channel_create_call_old(ch, method_chars, host_chars,
|
197
|
+
grpc_rb_time_timeval(deadline,
|
198
|
+
/* absolute time */ 0));
|
199
|
+
if (call == NULL) {
|
200
|
+
rb_raise(rb_eRuntimeError, "cannot create call with method %s",
|
201
|
+
method_chars);
|
202
|
+
}
|
203
|
+
res = grpc_rb_wrap_call(call);
|
204
|
+
|
205
|
+
/* Make this channel an instance attribute of the call so that is is not GCed
|
206
|
+
* before the call. */
|
207
|
+
rb_ivar_set(res, id_channel, self);
|
208
|
+
return res;
|
209
|
+
}
|
210
|
+
|
211
|
+
/* Closes the channel, calling it's destroy method */
|
212
|
+
static VALUE grpc_rb_channel_destroy(VALUE self) {
|
213
|
+
grpc_rb_channel *wrapper = NULL;
|
214
|
+
grpc_channel *ch = NULL;
|
215
|
+
|
216
|
+
Data_Get_Struct(self, grpc_rb_channel, wrapper);
|
217
|
+
ch = wrapper->wrapped;
|
218
|
+
if (ch != NULL) {
|
219
|
+
grpc_channel_destroy(ch);
|
220
|
+
wrapper->wrapped = NULL;
|
221
|
+
wrapper->mark = Qnil;
|
222
|
+
}
|
223
|
+
|
224
|
+
return Qnil;
|
225
|
+
}
|
226
|
+
|
227
|
+
/* rb_cChannel is the ruby class that proxies grpc_channel. */
|
228
|
+
VALUE rb_cChannel = Qnil;
|
229
|
+
|
230
|
+
void Init_grpc_channel() {
|
231
|
+
rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
|
232
|
+
rb_cChannel = rb_define_class_under(rb_mGrpcCore, "Channel", rb_cObject);
|
233
|
+
|
234
|
+
/* Allocates an object managed by the ruby runtime */
|
235
|
+
rb_define_alloc_func(rb_cChannel, grpc_rb_channel_alloc);
|
236
|
+
|
237
|
+
/* Provides a ruby constructor and support for dup/clone. */
|
238
|
+
rb_define_method(rb_cChannel, "initialize", grpc_rb_channel_init, -1);
|
239
|
+
rb_define_method(rb_cChannel, "initialize_copy", grpc_rb_channel_init_copy,
|
240
|
+
1);
|
241
|
+
|
242
|
+
/* Add ruby analogues of the Channel methods. */
|
243
|
+
rb_define_method(rb_cChannel, "create_call", grpc_rb_channel_create_call, 3);
|
244
|
+
rb_define_method(rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
|
245
|
+
rb_define_alias(rb_cChannel, "close", "destroy");
|
246
|
+
|
247
|
+
id_channel = rb_intern("__channel");
|
248
|
+
id_target = rb_intern("__target");
|
249
|
+
rb_define_const(rb_cChannel, "SSL_TARGET",
|
250
|
+
ID2SYM(rb_intern(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
|
251
|
+
rb_define_const(rb_cChannel, "ENABLE_CENSUS",
|
252
|
+
ID2SYM(rb_intern(GRPC_ARG_ENABLE_CENSUS)));
|
253
|
+
rb_define_const(rb_cChannel, "MAX_CONCURRENT_STREAMS",
|
254
|
+
ID2SYM(rb_intern(GRPC_ARG_MAX_CONCURRENT_STREAMS)));
|
255
|
+
rb_define_const(rb_cChannel, "MAX_MESSAGE_LENGTH",
|
256
|
+
ID2SYM(rb_intern(GRPC_ARG_MAX_MESSAGE_LENGTH)));
|
257
|
+
}
|
258
|
+
|
259
|
+
/* Gets the wrapped channel from the ruby wrapper */
|
260
|
+
grpc_channel *grpc_rb_get_wrapped_channel(VALUE v) {
|
261
|
+
grpc_rb_channel *wrapper = NULL;
|
262
|
+
Data_Get_Struct(v, grpc_rb_channel, wrapper);
|
263
|
+
return wrapper->wrapped;
|
264
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2015, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#ifndef GRPC_RB_CHANNEL_H_
|
35
|
+
#define GRPC_RB_CHANNEL_H_
|
36
|
+
|
37
|
+
#include <ruby.h>
|
38
|
+
#include <grpc/grpc.h>
|
39
|
+
|
40
|
+
/* rb_cChannel is the Channel class whose instances proxy grpc_channel. */
|
41
|
+
extern VALUE rb_cChannel;
|
42
|
+
|
43
|
+
/* Initializes the Channel class. */
|
44
|
+
void Init_grpc_channel();
|
45
|
+
|
46
|
+
/* Gets the wrapped channel from the ruby wrapper */
|
47
|
+
grpc_channel* grpc_rb_get_wrapped_channel(VALUE v);
|
48
|
+
|
49
|
+
#endif /* GRPC_RB_CHANNEL_H_ */
|
@@ -0,0 +1,154 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2015, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#include "rb_channel_args.h"
|
35
|
+
|
36
|
+
#include <ruby.h>
|
37
|
+
#include <grpc/grpc.h>
|
38
|
+
|
39
|
+
#include "rb_grpc.h"
|
40
|
+
|
41
|
+
/* A callback the processes the hash key values in channel_args hash */
|
42
|
+
static int grpc_rb_channel_create_in_process_add_args_hash_cb(VALUE key,
|
43
|
+
VALUE val,
|
44
|
+
VALUE args_obj) {
|
45
|
+
const char* the_key;
|
46
|
+
grpc_channel_args* args;
|
47
|
+
|
48
|
+
switch (TYPE(key)) {
|
49
|
+
case T_STRING:
|
50
|
+
the_key = StringValuePtr(key);
|
51
|
+
break;
|
52
|
+
|
53
|
+
case T_SYMBOL:
|
54
|
+
the_key = rb_id2name(SYM2ID(key));
|
55
|
+
break;
|
56
|
+
|
57
|
+
default:
|
58
|
+
rb_raise(rb_eTypeError, "bad chan arg: got <%s>, want <String|Symbol>",
|
59
|
+
rb_obj_classname(key));
|
60
|
+
return ST_STOP;
|
61
|
+
}
|
62
|
+
|
63
|
+
Data_Get_Struct(args_obj, grpc_channel_args, args);
|
64
|
+
if (args->num_args <= 0) {
|
65
|
+
rb_raise(rb_eRuntimeError, "hash_cb bug: num_args is %lu for key:%s",
|
66
|
+
args->num_args, StringValueCStr(key));
|
67
|
+
return ST_STOP;
|
68
|
+
}
|
69
|
+
|
70
|
+
args->args[args->num_args - 1].key = (char*)the_key;
|
71
|
+
switch (TYPE(val)) {
|
72
|
+
case T_SYMBOL:
|
73
|
+
args->args[args->num_args - 1].type = GRPC_ARG_STRING;
|
74
|
+
args->args[args->num_args - 1].value.string =
|
75
|
+
(char*)rb_id2name(SYM2ID(val));
|
76
|
+
--args->num_args;
|
77
|
+
return ST_CONTINUE;
|
78
|
+
|
79
|
+
case T_STRING:
|
80
|
+
args->args[args->num_args - 1].type = GRPC_ARG_STRING;
|
81
|
+
args->args[args->num_args - 1].value.string = StringValueCStr(val);
|
82
|
+
--args->num_args;
|
83
|
+
return ST_CONTINUE;
|
84
|
+
|
85
|
+
case T_FIXNUM:
|
86
|
+
args->args[args->num_args - 1].type = GRPC_ARG_INTEGER;
|
87
|
+
args->args[args->num_args - 1].value.integer = NUM2INT(val);
|
88
|
+
--args->num_args;
|
89
|
+
return ST_CONTINUE;
|
90
|
+
|
91
|
+
default:
|
92
|
+
rb_raise(rb_eTypeError, "%s: bad value: got <%s>, want <String|Fixnum>",
|
93
|
+
StringValueCStr(key), rb_obj_classname(val));
|
94
|
+
return ST_STOP;
|
95
|
+
}
|
96
|
+
rb_raise(rb_eRuntimeError, "impl bug: hash_cb reached to far while on key:%s",
|
97
|
+
StringValueCStr(key));
|
98
|
+
return ST_STOP;
|
99
|
+
}
|
100
|
+
|
101
|
+
/* channel_convert_params allows the call to
|
102
|
+
grpc_rb_hash_convert_to_channel_args to be made within an rb_protect
|
103
|
+
exception-handler. This allows any allocated memory to be freed before
|
104
|
+
propagating any exception that occurs */
|
105
|
+
typedef struct channel_convert_params {
|
106
|
+
VALUE src_hash;
|
107
|
+
grpc_channel_args* dst;
|
108
|
+
} channel_convert_params;
|
109
|
+
|
110
|
+
static VALUE grpc_rb_hash_convert_to_channel_args0(VALUE as_value) {
|
111
|
+
ID id_size = rb_intern("size");
|
112
|
+
VALUE rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
|
113
|
+
channel_convert_params* params = (channel_convert_params*)as_value;
|
114
|
+
size_t num_args = 0;
|
115
|
+
|
116
|
+
if (!NIL_P(params->src_hash) && TYPE(params->src_hash) != T_HASH) {
|
117
|
+
rb_raise(rb_eTypeError, "bad channel args: got:<%s> want: a hash or nil",
|
118
|
+
rb_obj_classname(params->src_hash));
|
119
|
+
return Qnil;
|
120
|
+
}
|
121
|
+
|
122
|
+
if (TYPE(params->src_hash) == T_HASH) {
|
123
|
+
num_args = NUM2INT(rb_funcall(params->src_hash, id_size, 0));
|
124
|
+
params->dst->num_args = num_args;
|
125
|
+
params->dst->args = ALLOC_N(grpc_arg, num_args);
|
126
|
+
MEMZERO(params->dst->args, grpc_arg, num_args);
|
127
|
+
rb_hash_foreach(params->src_hash,
|
128
|
+
grpc_rb_channel_create_in_process_add_args_hash_cb,
|
129
|
+
Data_Wrap_Struct(rb_cChannelArgs, GC_NOT_MARKED,
|
130
|
+
GC_DONT_FREE, params->dst));
|
131
|
+
/* reset num_args as grpc_rb_channel_create_in_process_add_args_hash_cb
|
132
|
+
* decrements it during has processing */
|
133
|
+
params->dst->num_args = num_args;
|
134
|
+
}
|
135
|
+
return Qnil;
|
136
|
+
}
|
137
|
+
|
138
|
+
void grpc_rb_hash_convert_to_channel_args(VALUE src_hash,
|
139
|
+
grpc_channel_args* dst) {
|
140
|
+
channel_convert_params params;
|
141
|
+
int status = 0;
|
142
|
+
|
143
|
+
/* Make a protected call to grpc_rb_hash_convert_channel_args */
|
144
|
+
params.src_hash = src_hash;
|
145
|
+
params.dst = dst;
|
146
|
+
rb_protect(grpc_rb_hash_convert_to_channel_args0, (VALUE) & params, &status);
|
147
|
+
if (status != 0) {
|
148
|
+
if (dst->args != NULL) {
|
149
|
+
/* Free any allocated memory before propagating the error */
|
150
|
+
xfree(dst->args);
|
151
|
+
}
|
152
|
+
rb_jump_tag(status);
|
153
|
+
}
|
154
|
+
}
|