grpc 0.15.0-universal-darwin → 1.0.0.pre1-universal-darwin
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 +4 -4
- data/etc/roots.pem +784 -509
- data/src/ruby/ext/grpc/rb_byte_buffer.c +4 -1
- data/src/ruby/ext/grpc/rb_call.c +87 -54
- data/src/ruby/ext/grpc/rb_call.h +1 -1
- data/src/ruby/ext/grpc/rb_call_credentials.c +1 -30
- data/src/ruby/ext/grpc/rb_channel.c +25 -50
- data/src/ruby/ext/grpc/rb_channel_credentials.c +1 -31
- data/src/ruby/ext/grpc/rb_completion_queue.c +15 -134
- data/src/ruby/ext/grpc/rb_completion_queue.h +3 -7
- data/src/ruby/ext/grpc/rb_grpc.c +2 -4
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +4 -1
- data/src/ruby/ext/grpc/rb_server.c +81 -133
- data/src/ruby/ext/grpc/rb_server_credentials.c +4 -33
- data/src/ruby/lib/grpc/2.0/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/2.1/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/2.2/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/2.3/grpc_c.bundle +0 -0
- data/src/ruby/lib/grpc/generic/active_call.rb +40 -55
- data/src/ruby/lib/grpc/generic/bidi_call.rb +21 -23
- data/src/ruby/lib/grpc/generic/client_stub.rb +20 -15
- data/src/ruby/lib/grpc/generic/rpc_server.rb +15 -37
- data/src/ruby/lib/grpc/generic/service.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/test/client.rb +25 -7
- data/src/ruby/pb/test/server.rb +7 -5
- data/src/ruby/spec/call_spec.rb +1 -2
- data/src/ruby/spec/channel_spec.rb +2 -3
- data/src/ruby/spec/client_server_spec.rb +74 -59
- data/src/ruby/spec/generic/active_call_spec.rb +66 -86
- data/src/ruby/spec/generic/client_stub_spec.rb +27 -48
- data/src/ruby/spec/generic/rpc_server_spec.rb +4 -34
- data/src/ruby/spec/pb/health/checker_spec.rb +0 -2
- data/src/ruby/spec/server_spec.rb +20 -24
- metadata +4 -6
- data/src/ruby/spec/completion_queue_spec.rb +0 -42
@@ -56,7 +56,10 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
|
|
56
56
|
return Qnil;
|
57
57
|
}
|
58
58
|
rb_string = rb_str_buf_new(grpc_byte_buffer_length(buffer));
|
59
|
-
grpc_byte_buffer_reader_init(&reader, buffer)
|
59
|
+
if (!grpc_byte_buffer_reader_init(&reader, buffer)) {
|
60
|
+
rb_raise(rb_eRuntimeError, "Error initializing byte buffer reader.");
|
61
|
+
return Qnil;
|
62
|
+
}
|
60
63
|
while (grpc_byte_buffer_reader_next(&reader, &next) != 0) {
|
61
64
|
rb_str_cat(rb_string, (const char *) GPR_SLICE_START_PTR(next),
|
62
65
|
GPR_SLICE_LENGTH(next));
|
data/src/ruby/ext/grpc/rb_call.c
CHANGED
@@ -63,27 +63,18 @@ static VALUE grpc_rb_sBatchResult;
|
|
63
63
|
* grpc_metadata_array. */
|
64
64
|
static VALUE grpc_rb_cMdAry;
|
65
65
|
|
66
|
-
/* id_cq is the name of the hidden ivar that preserves a reference to a
|
67
|
-
* completion queue */
|
68
|
-
static ID id_cq;
|
69
|
-
|
70
|
-
/* id_flags is the name of the hidden ivar that preserves the value of
|
71
|
-
* the flags used to create metadata from a Hash */
|
72
|
-
static ID id_flags;
|
73
|
-
|
74
66
|
/* id_credentials is the name of the hidden ivar that preserves the value
|
75
67
|
* of the credentials added to the call */
|
76
68
|
static ID id_credentials;
|
77
69
|
|
78
|
-
/* id_input_md is the name of the hidden ivar that preserves the hash used to
|
79
|
-
* create metadata, so that references to the strings it contains last as long
|
80
|
-
* as the call the metadata is added to. */
|
81
|
-
static ID id_input_md;
|
82
|
-
|
83
70
|
/* id_metadata is name of the attribute used to access the metadata hash
|
84
71
|
* received by the call and subsequently saved on it. */
|
85
72
|
static ID id_metadata;
|
86
73
|
|
74
|
+
/* id_trailing_metadata is the name of the attribute used to access the trailing
|
75
|
+
* metadata hash received by the call and subsequently saved on it. */
|
76
|
+
static ID id_trailing_metadata;
|
77
|
+
|
87
78
|
/* id_status is name of the attribute used to access the status object
|
88
79
|
* received by the call and subsequently saved on it. */
|
89
80
|
static ID id_status;
|
@@ -101,14 +92,27 @@ static VALUE sym_message;
|
|
101
92
|
static VALUE sym_status;
|
102
93
|
static VALUE sym_cancelled;
|
103
94
|
|
95
|
+
typedef struct grpc_rb_call {
|
96
|
+
grpc_call *wrapped;
|
97
|
+
grpc_completion_queue *queue;
|
98
|
+
} grpc_rb_call;
|
99
|
+
|
100
|
+
static void destroy_call(grpc_rb_call *call) {
|
101
|
+
/* Ensure that we only try to destroy the call once */
|
102
|
+
if (call->wrapped != NULL) {
|
103
|
+
grpc_call_destroy(call->wrapped);
|
104
|
+
call->wrapped = NULL;
|
105
|
+
grpc_rb_completion_queue_destroy(call->queue);
|
106
|
+
call->queue = NULL;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
104
110
|
/* Destroys a Call. */
|
105
111
|
static void grpc_rb_call_destroy(void *p) {
|
106
|
-
grpc_call* call = NULL;
|
107
112
|
if (p == NULL) {
|
108
113
|
return;
|
109
114
|
}
|
110
|
-
|
111
|
-
grpc_call_destroy(call);
|
115
|
+
destroy_call((grpc_rb_call*)p);
|
112
116
|
}
|
113
117
|
|
114
118
|
static size_t md_ary_datasize(const void *p) {
|
@@ -167,15 +171,15 @@ const char *grpc_call_error_detail_of(grpc_call_error err) {
|
|
167
171
|
/* Called by clients to cancel an RPC on the server.
|
168
172
|
Can be called multiple times, from any thread. */
|
169
173
|
static VALUE grpc_rb_call_cancel(VALUE self) {
|
170
|
-
|
174
|
+
grpc_rb_call *call = NULL;
|
171
175
|
grpc_call_error err;
|
172
176
|
if (RTYPEDDATA_DATA(self) == NULL) {
|
173
177
|
//This call has been closed
|
174
178
|
return Qnil;
|
175
179
|
}
|
176
180
|
|
177
|
-
TypedData_Get_Struct(self,
|
178
|
-
err = grpc_call_cancel(call, NULL);
|
181
|
+
TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
|
182
|
+
err = grpc_call_cancel(call->wrapped, NULL);
|
179
183
|
if (err != GRPC_CALL_OK) {
|
180
184
|
rb_raise(grpc_rb_eCallError, "cancel failed: %s (code=%d)",
|
181
185
|
grpc_call_error_detail_of(err), err);
|
@@ -189,10 +193,10 @@ static VALUE grpc_rb_call_cancel(VALUE self) {
|
|
189
193
|
processed.
|
190
194
|
*/
|
191
195
|
static VALUE grpc_rb_call_close(VALUE self) {
|
192
|
-
|
193
|
-
TypedData_Get_Struct(self,
|
196
|
+
grpc_rb_call *call = NULL;
|
197
|
+
TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
|
194
198
|
if(call != NULL) {
|
195
|
-
|
199
|
+
destroy_call(call);
|
196
200
|
RTYPEDDATA_DATA(self) = NULL;
|
197
201
|
}
|
198
202
|
return Qnil;
|
@@ -201,14 +205,14 @@ static VALUE grpc_rb_call_close(VALUE self) {
|
|
201
205
|
/* Called to obtain the peer that this call is connected to. */
|
202
206
|
static VALUE grpc_rb_call_get_peer(VALUE self) {
|
203
207
|
VALUE res = Qnil;
|
204
|
-
|
208
|
+
grpc_rb_call *call = NULL;
|
205
209
|
char *peer = NULL;
|
206
210
|
if (RTYPEDDATA_DATA(self) == NULL) {
|
207
211
|
rb_raise(grpc_rb_eCallError, "Cannot get peer value on closed call");
|
208
212
|
return Qnil;
|
209
213
|
}
|
210
|
-
TypedData_Get_Struct(self,
|
211
|
-
peer = grpc_call_get_peer(call);
|
214
|
+
TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
|
215
|
+
peer = grpc_call_get_peer(call->wrapped);
|
212
216
|
res = rb_str_new2(peer);
|
213
217
|
gpr_free(peer);
|
214
218
|
|
@@ -217,16 +221,16 @@ static VALUE grpc_rb_call_get_peer(VALUE self) {
|
|
217
221
|
|
218
222
|
/* Called to obtain the x509 cert of an authenticated peer. */
|
219
223
|
static VALUE grpc_rb_call_get_peer_cert(VALUE self) {
|
220
|
-
|
224
|
+
grpc_rb_call *call = NULL;
|
221
225
|
VALUE res = Qnil;
|
222
226
|
grpc_auth_context *ctx = NULL;
|
223
227
|
if (RTYPEDDATA_DATA(self) == NULL) {
|
224
228
|
rb_raise(grpc_rb_eCallError, "Cannot get peer cert on closed call");
|
225
229
|
return Qnil;
|
226
230
|
}
|
227
|
-
TypedData_Get_Struct(self,
|
231
|
+
TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
|
228
232
|
|
229
|
-
ctx = grpc_call_auth_context(call);
|
233
|
+
ctx = grpc_call_auth_context(call->wrapped);
|
230
234
|
|
231
235
|
if (!ctx || !grpc_auth_context_peer_is_authenticated(ctx)) {
|
232
236
|
return Qnil;
|
@@ -296,6 +300,30 @@ static VALUE grpc_rb_call_set_metadata(VALUE self, VALUE metadata) {
|
|
296
300
|
return rb_ivar_set(self, id_metadata, metadata);
|
297
301
|
}
|
298
302
|
|
303
|
+
/*
|
304
|
+
call-seq:
|
305
|
+
trailing_metadata = call.trailing_metadata
|
306
|
+
|
307
|
+
Gets the trailing metadata object saved on the call */
|
308
|
+
static VALUE grpc_rb_call_get_trailing_metadata(VALUE self) {
|
309
|
+
return rb_ivar_get(self, id_trailing_metadata);
|
310
|
+
}
|
311
|
+
|
312
|
+
/*
|
313
|
+
call-seq:
|
314
|
+
call.trailing_metadata = trailing_metadata
|
315
|
+
|
316
|
+
Saves the trailing metadata hash on the call. */
|
317
|
+
static VALUE grpc_rb_call_set_trailing_metadata(VALUE self, VALUE metadata) {
|
318
|
+
if (!NIL_P(metadata) && TYPE(metadata) != T_HASH) {
|
319
|
+
rb_raise(rb_eTypeError, "bad metadata: got:<%s> want: <Hash>",
|
320
|
+
rb_obj_classname(metadata));
|
321
|
+
return Qnil;
|
322
|
+
}
|
323
|
+
|
324
|
+
return rb_ivar_set(self, id_trailing_metadata, metadata);
|
325
|
+
}
|
326
|
+
|
299
327
|
/*
|
300
328
|
call-seq:
|
301
329
|
write_flag = call.write_flag
|
@@ -326,21 +354,23 @@ static VALUE grpc_rb_call_set_write_flag(VALUE self, VALUE write_flag) {
|
|
326
354
|
|
327
355
|
Sets credentials on a call */
|
328
356
|
static VALUE grpc_rb_call_set_credentials(VALUE self, VALUE credentials) {
|
329
|
-
|
357
|
+
grpc_rb_call *call = NULL;
|
330
358
|
grpc_call_credentials *creds;
|
331
359
|
grpc_call_error err;
|
332
360
|
if (RTYPEDDATA_DATA(self) == NULL) {
|
333
361
|
rb_raise(grpc_rb_eCallError, "Cannot set credentials of closed call");
|
334
362
|
return Qnil;
|
335
363
|
}
|
336
|
-
TypedData_Get_Struct(self,
|
364
|
+
TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
|
337
365
|
creds = grpc_rb_get_wrapped_call_credentials(credentials);
|
338
|
-
err = grpc_call_set_credentials(call, creds);
|
366
|
+
err = grpc_call_set_credentials(call->wrapped, creds);
|
339
367
|
if (err != GRPC_CALL_OK) {
|
340
368
|
rb_raise(grpc_rb_eCallError,
|
341
369
|
"grpc_call_set_credentials failed with %s (code=%d)",
|
342
370
|
grpc_call_error_detail_of(err), err);
|
343
371
|
}
|
372
|
+
/* We need the credentials to be alive for as long as the call is alive,
|
373
|
+
but we don't care about destruction order. */
|
344
374
|
rb_ivar_set(self, id_credentials, credentials);
|
345
375
|
return Qnil;
|
346
376
|
}
|
@@ -733,7 +763,6 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) {
|
|
733
763
|
}
|
734
764
|
|
735
765
|
/* call-seq:
|
736
|
-
cq = CompletionQueue.new
|
737
766
|
ops = {
|
738
767
|
GRPC::Core::CallOps::SEND_INITIAL_METADATA => <op_value>,
|
739
768
|
GRPC::Core::CallOps::SEND_MESSAGE => <op_value>,
|
@@ -741,7 +770,7 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) {
|
|
741
770
|
}
|
742
771
|
tag = Object.new
|
743
772
|
timeout = 10
|
744
|
-
call.start_batch(
|
773
|
+
call.start_batch(tag, timeout, ops)
|
745
774
|
|
746
775
|
Start a batch of operations defined in the array ops; when complete, post a
|
747
776
|
completion of type 'tag' to the completion queue bound to the call.
|
@@ -750,20 +779,20 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) {
|
|
750
779
|
The order of ops specified in the batch has no significance.
|
751
780
|
Only one operation of each type can be active at once in any given
|
752
781
|
batch */
|
753
|
-
static VALUE grpc_rb_call_run_batch(VALUE self, VALUE
|
754
|
-
VALUE timeout, VALUE ops_hash) {
|
782
|
+
static VALUE grpc_rb_call_run_batch(VALUE self, VALUE ops_hash) {
|
755
783
|
run_batch_stack st;
|
756
|
-
|
784
|
+
grpc_rb_call *call = NULL;
|
757
785
|
grpc_event ev;
|
758
786
|
grpc_call_error err;
|
759
787
|
VALUE result = Qnil;
|
760
788
|
VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
|
761
789
|
unsigned write_flag = 0;
|
790
|
+
void *tag = (void*)&st;
|
762
791
|
if (RTYPEDDATA_DATA(self) == NULL) {
|
763
792
|
rb_raise(grpc_rb_eCallError, "Cannot run batch on closed call");
|
764
793
|
return Qnil;
|
765
794
|
}
|
766
|
-
TypedData_Get_Struct(self,
|
795
|
+
TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
|
767
796
|
|
768
797
|
/* Validate the ops args, adding them to a ruby array */
|
769
798
|
if (TYPE(ops_hash) != T_HASH) {
|
@@ -778,7 +807,7 @@ static VALUE grpc_rb_call_run_batch(VALUE self, VALUE cqueue, VALUE tag,
|
|
778
807
|
|
779
808
|
/* call grpc_call_start_batch, then wait for it to complete using
|
780
809
|
* pluck_event */
|
781
|
-
err = grpc_call_start_batch(call, st.ops, st.op_num,
|
810
|
+
err = grpc_call_start_batch(call->wrapped, st.ops, st.op_num, tag, NULL);
|
782
811
|
if (err != GRPC_CALL_OK) {
|
783
812
|
grpc_run_batch_stack_cleanup(&st);
|
784
813
|
rb_raise(grpc_rb_eCallError,
|
@@ -786,13 +815,11 @@ static VALUE grpc_rb_call_run_batch(VALUE self, VALUE cqueue, VALUE tag,
|
|
786
815
|
grpc_call_error_detail_of(err), err);
|
787
816
|
return Qnil;
|
788
817
|
}
|
789
|
-
ev =
|
790
|
-
|
791
|
-
|
792
|
-
rb_raise(
|
793
|
-
return Qnil;
|
818
|
+
ev = rb_completion_queue_pluck(call->queue, tag,
|
819
|
+
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
|
820
|
+
if (!ev.success) {
|
821
|
+
rb_raise(grpc_rb_eCallError, "call#run_batch failed somehow");
|
794
822
|
}
|
795
|
-
|
796
823
|
/* Build and return the BatchResult struct result,
|
797
824
|
if there is an error, it's reflected in the status */
|
798
825
|
result = grpc_run_batch_stack_build_result(&st);
|
@@ -900,7 +927,7 @@ void Init_grpc_call() {
|
|
900
927
|
1);
|
901
928
|
|
902
929
|
/* Add ruby analogues of the Call methods. */
|
903
|
-
rb_define_method(grpc_rb_cCall, "run_batch", grpc_rb_call_run_batch,
|
930
|
+
rb_define_method(grpc_rb_cCall, "run_batch", grpc_rb_call_run_batch, 1);
|
904
931
|
rb_define_method(grpc_rb_cCall, "cancel", grpc_rb_call_cancel, 0);
|
905
932
|
rb_define_method(grpc_rb_cCall, "close", grpc_rb_call_close, 0);
|
906
933
|
rb_define_method(grpc_rb_cCall, "peer", grpc_rb_call_get_peer, 0);
|
@@ -909,6 +936,10 @@ void Init_grpc_call() {
|
|
909
936
|
rb_define_method(grpc_rb_cCall, "status=", grpc_rb_call_set_status, 1);
|
910
937
|
rb_define_method(grpc_rb_cCall, "metadata", grpc_rb_call_get_metadata, 0);
|
911
938
|
rb_define_method(grpc_rb_cCall, "metadata=", grpc_rb_call_set_metadata, 1);
|
939
|
+
rb_define_method(grpc_rb_cCall, "trailing_metadata",
|
940
|
+
grpc_rb_call_get_trailing_metadata, 0);
|
941
|
+
rb_define_method(grpc_rb_cCall, "trailing_metadata=",
|
942
|
+
grpc_rb_call_set_trailing_metadata, 1);
|
912
943
|
rb_define_method(grpc_rb_cCall, "write_flag", grpc_rb_call_get_write_flag, 0);
|
913
944
|
rb_define_method(grpc_rb_cCall, "write_flag=", grpc_rb_call_set_write_flag,
|
914
945
|
1);
|
@@ -917,13 +948,11 @@ void Init_grpc_call() {
|
|
917
948
|
|
918
949
|
/* Ids used to support call attributes */
|
919
950
|
id_metadata = rb_intern("metadata");
|
951
|
+
id_trailing_metadata = rb_intern("trailing_metadata");
|
920
952
|
id_status = rb_intern("status");
|
921
953
|
id_write_flag = rb_intern("write_flag");
|
922
954
|
|
923
955
|
/* Ids used by the c wrapping internals. */
|
924
|
-
id_cq = rb_intern("__cq");
|
925
|
-
id_flags = rb_intern("__flags");
|
926
|
-
id_input_md = rb_intern("__input_md");
|
927
956
|
id_credentials = rb_intern("__credentials");
|
928
957
|
|
929
958
|
/* Ids used in constructing the batch result. */
|
@@ -947,15 +976,19 @@ void Init_grpc_call() {
|
|
947
976
|
|
948
977
|
/* Gets the call from the ruby object */
|
949
978
|
grpc_call *grpc_rb_get_wrapped_call(VALUE v) {
|
950
|
-
|
951
|
-
TypedData_Get_Struct(v,
|
952
|
-
return
|
979
|
+
grpc_rb_call *call = NULL;
|
980
|
+
TypedData_Get_Struct(v, grpc_rb_call, &grpc_call_data_type, call);
|
981
|
+
return call->wrapped;
|
953
982
|
}
|
954
983
|
|
955
984
|
/* Obtains the wrapped object for a given call */
|
956
|
-
VALUE grpc_rb_wrap_call(grpc_call *c) {
|
957
|
-
|
985
|
+
VALUE grpc_rb_wrap_call(grpc_call *c, grpc_completion_queue *q) {
|
986
|
+
grpc_rb_call *wrapper;
|
987
|
+
if (c == NULL || q == NULL) {
|
958
988
|
return Qnil;
|
959
989
|
}
|
960
|
-
|
990
|
+
wrapper = ALLOC(grpc_rb_call);
|
991
|
+
wrapper->wrapped = c;
|
992
|
+
wrapper->queue = q;
|
993
|
+
return TypedData_Wrap_Struct(grpc_rb_cCall, &grpc_call_data_type, wrapper);
|
961
994
|
}
|
data/src/ruby/ext/grpc/rb_call.h
CHANGED
@@ -42,7 +42,7 @@
|
|
42
42
|
grpc_call* grpc_rb_get_wrapped_call(VALUE v);
|
43
43
|
|
44
44
|
/* Gets the VALUE corresponding to given grpc_call. */
|
45
|
-
VALUE grpc_rb_wrap_call(grpc_call*
|
45
|
+
VALUE grpc_rb_wrap_call(grpc_call *c, grpc_completion_queue *q);
|
46
46
|
|
47
47
|
/* Provides the details of an call error */
|
48
48
|
const char* grpc_call_error_detail_of(grpc_call_error err);
|
@@ -211,35 +211,6 @@ VALUE grpc_rb_wrap_call_credentials(grpc_call_credentials *c, VALUE mark) {
|
|
211
211
|
return rb_wrapper;
|
212
212
|
}
|
213
213
|
|
214
|
-
/* Clones CallCredentials instances.
|
215
|
-
Gives CallCredentials a consistent implementation of Ruby's object copy/dup
|
216
|
-
protocol. */
|
217
|
-
static VALUE grpc_rb_call_credentials_init_copy(VALUE copy, VALUE orig) {
|
218
|
-
grpc_rb_call_credentials *orig_cred = NULL;
|
219
|
-
grpc_rb_call_credentials *copy_cred = NULL;
|
220
|
-
|
221
|
-
if (copy == orig) {
|
222
|
-
return copy;
|
223
|
-
}
|
224
|
-
|
225
|
-
/* Raise an error if orig is not a credentials object or a subclass. */
|
226
|
-
if (TYPE(orig) != T_DATA ||
|
227
|
-
RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_call_credentials_free) {
|
228
|
-
rb_raise(rb_eTypeError, "not a %s",
|
229
|
-
rb_obj_classname(grpc_rb_cCallCredentials));
|
230
|
-
}
|
231
|
-
|
232
|
-
TypedData_Get_Struct(orig, grpc_rb_call_credentials,
|
233
|
-
&grpc_rb_call_credentials_data_type, orig_cred);
|
234
|
-
TypedData_Get_Struct(copy, grpc_rb_call_credentials,
|
235
|
-
&grpc_rb_call_credentials_data_type, copy_cred);
|
236
|
-
|
237
|
-
/* use ruby's MEMCPY to make a byte-for-byte copy of the credentials
|
238
|
-
* wrapper object. */
|
239
|
-
MEMCPY(copy_cred, orig_cred, grpc_rb_call_credentials, 1);
|
240
|
-
return copy;
|
241
|
-
}
|
242
|
-
|
243
214
|
/* The attribute used on the mark object to hold the callback */
|
244
215
|
static ID id_callback;
|
245
216
|
|
@@ -308,7 +279,7 @@ void Init_grpc_call_credentials() {
|
|
308
279
|
rb_define_method(grpc_rb_cCallCredentials, "initialize",
|
309
280
|
grpc_rb_call_credentials_init, 1);
|
310
281
|
rb_define_method(grpc_rb_cCallCredentials, "initialize_copy",
|
311
|
-
|
282
|
+
grpc_rb_cannot_init_copy, 1);
|
312
283
|
rb_define_method(grpc_rb_cCallCredentials, "compose",
|
313
284
|
grpc_rb_call_credentials_compose, -1);
|
314
285
|
|
@@ -39,6 +39,8 @@
|
|
39
39
|
#include <grpc/grpc.h>
|
40
40
|
#include <grpc/grpc_security.h>
|
41
41
|
#include <grpc/support/alloc.h>
|
42
|
+
#include <grpc/support/log.h>
|
43
|
+
#include <grpc/support/time.h>
|
42
44
|
#include "rb_grpc.h"
|
43
45
|
#include "rb_call.h"
|
44
46
|
#include "rb_channel_args.h"
|
@@ -55,11 +57,6 @@ static ID id_channel;
|
|
55
57
|
* GCed before the channel */
|
56
58
|
static ID id_target;
|
57
59
|
|
58
|
-
/* id_cqueue is the name of the hidden ivar that preserves a reference to the
|
59
|
-
* completion queue used to create the call, preserved so that it does not get
|
60
|
-
* GCed before the channel */
|
61
|
-
static ID id_cqueue;
|
62
|
-
|
63
60
|
/* id_insecure_channel is used to indicate that a channel is insecure */
|
64
61
|
static VALUE id_insecure_channel;
|
65
62
|
|
@@ -75,6 +72,7 @@ typedef struct grpc_rb_channel {
|
|
75
72
|
|
76
73
|
/* The actual channel */
|
77
74
|
grpc_channel *wrapped;
|
75
|
+
grpc_completion_queue *queue;
|
78
76
|
} grpc_rb_channel;
|
79
77
|
|
80
78
|
/* Destroys Channel instances. */
|
@@ -87,6 +85,7 @@ static void grpc_rb_channel_free(void *p) {
|
|
87
85
|
|
88
86
|
if (ch->wrapped != NULL) {
|
89
87
|
grpc_channel_destroy(ch->wrapped);
|
88
|
+
grpc_rb_completion_queue_destroy(ch->queue);
|
90
89
|
}
|
91
90
|
|
92
91
|
xfree(p);
|
@@ -169,6 +168,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
|
|
169
168
|
}
|
170
169
|
rb_ivar_set(self, id_target, target);
|
171
170
|
wrapper->wrapped = ch;
|
171
|
+
wrapper->queue = grpc_completion_queue_create(NULL);
|
172
172
|
return self;
|
173
173
|
}
|
174
174
|
|
@@ -207,16 +207,18 @@ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE *argv,
|
|
207
207
|
the completion queue with success=0 */
|
208
208
|
static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self,
|
209
209
|
VALUE last_state,
|
210
|
-
VALUE
|
211
|
-
VALUE deadline,
|
212
|
-
VALUE tag) {
|
210
|
+
VALUE deadline) {
|
213
211
|
grpc_rb_channel *wrapper = NULL;
|
214
212
|
grpc_channel *ch = NULL;
|
215
213
|
grpc_completion_queue *cq = NULL;
|
216
214
|
|
217
|
-
|
215
|
+
void *tag = wrapper;
|
216
|
+
|
217
|
+
grpc_event event;
|
218
|
+
|
218
219
|
TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
|
219
220
|
ch = wrapper->wrapped;
|
221
|
+
cq = wrapper->queue;
|
220
222
|
if (ch == NULL) {
|
221
223
|
rb_raise(rb_eRuntimeError, "closed!");
|
222
224
|
return Qnil;
|
@@ -226,45 +228,23 @@ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self,
|
|
226
228
|
(grpc_connectivity_state)NUM2LONG(last_state),
|
227
229
|
grpc_rb_time_timeval(deadline, /* absolute time */ 0),
|
228
230
|
cq,
|
229
|
-
|
230
|
-
|
231
|
-
return Qnil;
|
232
|
-
}
|
233
|
-
|
234
|
-
/* Clones Channel instances.
|
231
|
+
tag);
|
235
232
|
|
236
|
-
|
237
|
-
|
238
|
-
static VALUE grpc_rb_channel_init_copy(VALUE copy, VALUE orig) {
|
239
|
-
grpc_rb_channel *orig_ch = NULL;
|
240
|
-
grpc_rb_channel *copy_ch = NULL;
|
233
|
+
event = rb_completion_queue_pluck(cq, tag,
|
234
|
+
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
|
241
235
|
|
242
|
-
if (
|
243
|
-
return
|
244
|
-
}
|
245
|
-
|
246
|
-
/* Raise an error if orig is not a channel object or a subclass. */
|
247
|
-
if (TYPE(orig) != T_DATA ||
|
248
|
-
RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_channel_free) {
|
249
|
-
rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cChannel));
|
250
|
-
return Qnil;
|
236
|
+
if (event.success) {
|
237
|
+
return Qtrue;
|
238
|
+
} else {
|
239
|
+
return Qfalse;
|
251
240
|
}
|
252
|
-
|
253
|
-
TypedData_Get_Struct(orig, grpc_rb_channel, &grpc_channel_data_type, orig_ch);
|
254
|
-
TypedData_Get_Struct(copy, grpc_rb_channel, &grpc_channel_data_type, copy_ch);
|
255
|
-
|
256
|
-
/* use ruby's MEMCPY to make a byte-for-byte copy of the channel wrapper
|
257
|
-
* object. */
|
258
|
-
MEMCPY(copy_ch, orig_ch, grpc_rb_channel, 1);
|
259
|
-
return copy;
|
260
241
|
}
|
261
242
|
|
262
243
|
/* Create a call given a grpc_channel, in order to call method. The request
|
263
244
|
is not sent until grpc_call_invoke is called. */
|
264
|
-
static VALUE grpc_rb_channel_create_call(VALUE self, VALUE
|
265
|
-
VALUE
|
266
|
-
VALUE
|
267
|
-
VALUE deadline) {
|
245
|
+
static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
|
246
|
+
VALUE mask, VALUE method,
|
247
|
+
VALUE host, VALUE deadline) {
|
268
248
|
VALUE res = Qnil;
|
269
249
|
grpc_rb_channel *wrapper = NULL;
|
270
250
|
grpc_call *call = NULL;
|
@@ -284,7 +264,7 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE cqueue,
|
|
284
264
|
parent_call = grpc_rb_get_wrapped_call(parent);
|
285
265
|
}
|
286
266
|
|
287
|
-
cq =
|
267
|
+
cq = grpc_completion_queue_create(NULL);
|
288
268
|
TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
|
289
269
|
ch = wrapper->wrapped;
|
290
270
|
if (ch == NULL) {
|
@@ -301,15 +281,11 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE cqueue,
|
|
301
281
|
method_chars);
|
302
282
|
return Qnil;
|
303
283
|
}
|
304
|
-
res = grpc_rb_wrap_call(call);
|
284
|
+
res = grpc_rb_wrap_call(call, cq);
|
305
285
|
|
306
286
|
/* Make this channel an instance attribute of the call so that it is not GCed
|
307
287
|
* before the call. */
|
308
288
|
rb_ivar_set(res, id_channel, self);
|
309
|
-
|
310
|
-
/* Make the completion queue an instance attribute of the call so that it is
|
311
|
-
* not GCed before the call. */
|
312
|
-
rb_ivar_set(res, id_cqueue, cqueue);
|
313
289
|
return res;
|
314
290
|
}
|
315
291
|
|
@@ -387,7 +363,7 @@ void Init_grpc_channel() {
|
|
387
363
|
/* Provides a ruby constructor and support for dup/clone. */
|
388
364
|
rb_define_method(grpc_rb_cChannel, "initialize", grpc_rb_channel_init, -1);
|
389
365
|
rb_define_method(grpc_rb_cChannel, "initialize_copy",
|
390
|
-
|
366
|
+
grpc_rb_cannot_init_copy, 1);
|
391
367
|
|
392
368
|
/* Add ruby analogues of the Channel methods. */
|
393
369
|
rb_define_method(grpc_rb_cChannel, "connectivity_state",
|
@@ -396,13 +372,12 @@ void Init_grpc_channel() {
|
|
396
372
|
rb_define_method(grpc_rb_cChannel, "watch_connectivity_state",
|
397
373
|
grpc_rb_channel_watch_connectivity_state, 4);
|
398
374
|
rb_define_method(grpc_rb_cChannel, "create_call",
|
399
|
-
grpc_rb_channel_create_call,
|
375
|
+
grpc_rb_channel_create_call, 5);
|
400
376
|
rb_define_method(grpc_rb_cChannel, "target", grpc_rb_channel_get_target, 0);
|
401
377
|
rb_define_method(grpc_rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
|
402
378
|
rb_define_alias(grpc_rb_cChannel, "close", "destroy");
|
403
379
|
|
404
380
|
id_channel = rb_intern("__channel");
|
405
|
-
id_cqueue = rb_intern("__cqueue");
|
406
381
|
id_target = rb_intern("__target");
|
407
382
|
rb_define_const(grpc_rb_cChannel, "SSL_TARGET",
|
408
383
|
ID2SYM(rb_intern(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
|