grpc 1.74.0.pre2-x86-linux-musl

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.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/etc/roots.pem +4337 -0
  3. data/grpc_c.32-msvcrt.ruby +0 -0
  4. data/grpc_c.64-ucrt.ruby +0 -0
  5. data/src/ruby/bin/math_client.rb +140 -0
  6. data/src/ruby/bin/math_pb.rb +19 -0
  7. data/src/ruby/bin/math_server.rb +191 -0
  8. data/src/ruby/bin/math_services_pb.rb +51 -0
  9. data/src/ruby/bin/noproto_client.rb +93 -0
  10. data/src/ruby/bin/noproto_server.rb +97 -0
  11. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.clang +2 -0
  12. data/src/ruby/ext/grpc/ext-export-truffleruby-with-ruby-abi-version.gcc +7 -0
  13. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.clang +2 -0
  14. data/src/ruby/ext/grpc/ext-export-with-ruby-abi-version.gcc +7 -0
  15. data/src/ruby/ext/grpc/ext-export.clang +1 -0
  16. data/src/ruby/ext/grpc/ext-export.gcc +6 -0
  17. data/src/ruby/ext/grpc/extconf.rb +269 -0
  18. data/src/ruby/ext/grpc/rb_byte_buffer.c +65 -0
  19. data/src/ruby/ext/grpc/rb_byte_buffer.h +35 -0
  20. data/src/ruby/ext/grpc/rb_call.c +1075 -0
  21. data/src/ruby/ext/grpc/rb_call.h +57 -0
  22. data/src/ruby/ext/grpc/rb_call_credentials.c +347 -0
  23. data/src/ruby/ext/grpc/rb_call_credentials.h +32 -0
  24. data/src/ruby/ext/grpc/rb_channel.c +391 -0
  25. data/src/ruby/ext/grpc/rb_channel.h +32 -0
  26. data/src/ruby/ext/grpc/rb_channel_args.c +174 -0
  27. data/src/ruby/ext/grpc/rb_channel_args.h +42 -0
  28. data/src/ruby/ext/grpc/rb_channel_credentials.c +285 -0
  29. data/src/ruby/ext/grpc/rb_channel_credentials.h +36 -0
  30. data/src/ruby/ext/grpc/rb_completion_queue.c +95 -0
  31. data/src/ruby/ext/grpc/rb_completion_queue.h +36 -0
  32. data/src/ruby/ext/grpc/rb_compression_options.c +469 -0
  33. data/src/ruby/ext/grpc/rb_compression_options.h +29 -0
  34. data/src/ruby/ext/grpc/rb_enable_cpp.cc +22 -0
  35. data/src/ruby/ext/grpc/rb_event_thread.c +167 -0
  36. data/src/ruby/ext/grpc/rb_event_thread.h +22 -0
  37. data/src/ruby/ext/grpc/rb_grpc.c +500 -0
  38. data/src/ruby/ext/grpc/rb_grpc.h +88 -0
  39. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +597 -0
  40. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +902 -0
  41. data/src/ruby/ext/grpc/rb_loader.c +57 -0
  42. data/src/ruby/ext/grpc/rb_loader.h +25 -0
  43. data/src/ruby/ext/grpc/rb_server.c +406 -0
  44. data/src/ruby/ext/grpc/rb_server.h +32 -0
  45. data/src/ruby/ext/grpc/rb_server_credentials.c +259 -0
  46. data/src/ruby/ext/grpc/rb_server_credentials.h +37 -0
  47. data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +217 -0
  48. data/src/ruby/ext/grpc/rb_xds_channel_credentials.h +36 -0
  49. data/src/ruby/ext/grpc/rb_xds_server_credentials.c +170 -0
  50. data/src/ruby/ext/grpc/rb_xds_server_credentials.h +37 -0
  51. data/src/ruby/lib/grpc/3.1/grpc_c.so +0 -0
  52. data/src/ruby/lib/grpc/3.2/grpc_c.so +0 -0
  53. data/src/ruby/lib/grpc/3.3/grpc_c.so +0 -0
  54. data/src/ruby/lib/grpc/3.4/grpc_c.so +0 -0
  55. data/src/ruby/lib/grpc/core/status_codes.rb +135 -0
  56. data/src/ruby/lib/grpc/core/time_consts.rb +56 -0
  57. data/src/ruby/lib/grpc/errors.rb +277 -0
  58. data/src/ruby/lib/grpc/generic/active_call.rb +679 -0
  59. data/src/ruby/lib/grpc/generic/bidi_call.rb +237 -0
  60. data/src/ruby/lib/grpc/generic/client_stub.rb +503 -0
  61. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  62. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  63. data/src/ruby/lib/grpc/generic/rpc_desc.rb +204 -0
  64. data/src/ruby/lib/grpc/generic/rpc_server.rb +551 -0
  65. data/src/ruby/lib/grpc/generic/service.rb +211 -0
  66. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +40 -0
  67. data/src/ruby/lib/grpc/grpc.rb +24 -0
  68. data/src/ruby/lib/grpc/logconfig.rb +57 -0
  69. data/src/ruby/lib/grpc/notifier.rb +45 -0
  70. data/src/ruby/lib/grpc/structs.rb +15 -0
  71. data/src/ruby/lib/grpc/version.rb +18 -0
  72. data/src/ruby/lib/grpc.rb +37 -0
  73. data/src/ruby/pb/README.md +42 -0
  74. data/src/ruby/pb/generate_proto_ruby.sh +46 -0
  75. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  76. data/src/ruby/pb/grpc/health/v1/health_pb.rb +21 -0
  77. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +62 -0
  78. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +44 -0
  79. data/src/ruby/pb/grpc/testing/metrics_pb.rb +19 -0
  80. data/src/ruby/pb/grpc/testing/metrics_services_pb.rb +49 -0
  81. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +17 -0
  82. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +50 -0
  83. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +19 -0
  84. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +174 -0
  85. data/src/ruby/pb/test/client.rb +785 -0
  86. data/src/ruby/pb/test/server.rb +252 -0
  87. data/src/ruby/pb/test/xds_client.rb +415 -0
  88. data/src/ruby/spec/call_credentials_spec.rb +42 -0
  89. data/src/ruby/spec/call_spec.rb +193 -0
  90. data/src/ruby/spec/channel_connection_spec.rb +126 -0
  91. data/src/ruby/spec/channel_credentials_spec.rb +124 -0
  92. data/src/ruby/spec/channel_spec.rb +209 -0
  93. data/src/ruby/spec/client_auth_spec.rb +152 -0
  94. data/src/ruby/spec/client_server_spec.rb +317 -0
  95. data/src/ruby/spec/compression_options_spec.rb +149 -0
  96. data/src/ruby/spec/core_spec.rb +22 -0
  97. data/src/ruby/spec/debug_message_spec.rb +134 -0
  98. data/src/ruby/spec/error_sanity_spec.rb +49 -0
  99. data/src/ruby/spec/errors_spec.rb +142 -0
  100. data/src/ruby/spec/generic/active_call_spec.rb +670 -0
  101. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  102. data/src/ruby/spec/generic/client_stub_spec.rb +1079 -0
  103. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  104. data/src/ruby/spec/generic/rpc_desc_spec.rb +374 -0
  105. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +127 -0
  106. data/src/ruby/spec/generic/rpc_server_spec.rb +773 -0
  107. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  108. data/src/ruby/spec/generic/service_spec.rb +263 -0
  109. data/src/ruby/spec/google_rpc_status_utils_spec.rb +282 -0
  110. data/src/ruby/spec/logconfig_spec.rb +30 -0
  111. data/src/ruby/spec/pb/codegen/grpc/testing/package_options.proto +28 -0
  112. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import.proto +22 -0
  113. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import2.proto +23 -0
  114. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +41 -0
  115. data/src/ruby/spec/pb/codegen/grpc/testing/same_package_service_name.proto +27 -0
  116. data/src/ruby/spec/pb/codegen/grpc/testing/same_ruby_package_service_name.proto +29 -0
  117. data/src/ruby/spec/pb/codegen/package_option_spec.rb +98 -0
  118. data/src/ruby/spec/pb/duplicate/codegen_spec.rb +57 -0
  119. data/src/ruby/spec/pb/health/checker_spec.rb +236 -0
  120. data/src/ruby/spec/server_credentials_spec.rb +104 -0
  121. data/src/ruby/spec/server_spec.rb +231 -0
  122. data/src/ruby/spec/spec_helper.rb +61 -0
  123. data/src/ruby/spec/support/helpers.rb +107 -0
  124. data/src/ruby/spec/support/services.rb +163 -0
  125. data/src/ruby/spec/testdata/README +1 -0
  126. data/src/ruby/spec/testdata/ca.pem +20 -0
  127. data/src/ruby/spec/testdata/client.key +28 -0
  128. data/src/ruby/spec/testdata/client.pem +20 -0
  129. data/src/ruby/spec/testdata/server1.key +28 -0
  130. data/src/ruby/spec/testdata/server1.pem +22 -0
  131. data/src/ruby/spec/time_consts_spec.rb +74 -0
  132. data/src/ruby/spec/user_agent_spec.rb +74 -0
  133. metadata +411 -0
@@ -0,0 +1,391 @@
1
+ /*
2
+ *
3
+ * Copyright 2015 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #include <ruby/ruby.h>
20
+
21
+ #include "rb_channel.h"
22
+
23
+ #include <grpc/credentials.h>
24
+ #include <grpc/grpc.h>
25
+ #include <grpc/grpc_security.h>
26
+ #include <grpc/support/alloc.h>
27
+ #include <grpc/support/log.h>
28
+ #include <grpc/support/time.h>
29
+ #include <ruby/thread.h>
30
+
31
+ #include "rb_byte_buffer.h"
32
+ #include "rb_call.h"
33
+ #include "rb_channel_args.h"
34
+ #include "rb_channel_credentials.h"
35
+ #include "rb_completion_queue.h"
36
+ #include "rb_grpc.h"
37
+ #include "rb_grpc_imports.generated.h"
38
+ #include "rb_server.h"
39
+ #include "rb_xds_channel_credentials.h"
40
+
41
+ /* id_channel is the name of the hidden ivar that preserves a reference to the
42
+ * channel on a call, so that calls are not GCed before their channel. */
43
+ static ID id_channel;
44
+
45
+ /* id_target is the name of the hidden ivar that preserves a reference to the
46
+ * target string used to create the call, preserved so that it does not get
47
+ * GCed before the channel */
48
+ static ID id_target;
49
+
50
+ /* hidden ivar that synchronizes post-fork channel re-creation */
51
+ static ID id_channel_recreation_mu;
52
+
53
+ /* id_insecure_channel is used to indicate that a channel is insecure */
54
+ static VALUE id_insecure_channel;
55
+
56
+ /* grpc_rb_cChannel is the ruby class that proxies grpc_channel. */
57
+ static VALUE grpc_rb_cChannel = Qnil;
58
+
59
+ /* Used during the conversion of a hash to channel args during channel setup */
60
+ static VALUE grpc_rb_cChannelArgs;
61
+
62
+ /* grpc_rb_channel wraps a grpc_channel. */
63
+ typedef struct grpc_rb_channel {
64
+ grpc_channel* channel;
65
+ } grpc_rb_channel;
66
+
67
+ static void grpc_rb_channel_free(void* p) {
68
+ if (p == NULL) {
69
+ return;
70
+ };
71
+ grpc_rb_channel* wrapper = (grpc_rb_channel*)p;
72
+ if (wrapper->channel != NULL) {
73
+ grpc_channel_destroy(wrapper->channel);
74
+ wrapper->channel = NULL;
75
+ }
76
+ xfree(p);
77
+ }
78
+
79
+ static rb_data_type_t grpc_channel_data_type = {
80
+ "grpc_channel",
81
+ {NULL, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
82
+ NULL,
83
+ NULL,
84
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
85
+ RUBY_TYPED_FREE_IMMEDIATELY
86
+ #endif
87
+ };
88
+
89
+ /* Allocates grpc_rb_channel instances. */
90
+ static VALUE grpc_rb_channel_alloc(VALUE cls) {
91
+ grpc_ruby_init();
92
+ grpc_rb_channel* wrapper = ALLOC(grpc_rb_channel);
93
+ wrapper->channel = NULL;
94
+ return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper);
95
+ }
96
+
97
+ /*
98
+ call-seq:
99
+ insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'},
100
+ :this_channel_is_insecure)
101
+ creds = ...
102
+ secure_channel = Channel:new("myhost:443", {'arg1': 'value1'}, creds)
103
+
104
+ Creates channel instances. */
105
+ static VALUE grpc_rb_channel_init(int argc, VALUE* argv, VALUE self) {
106
+ VALUE rb_channel_args = Qnil;
107
+ VALUE rb_credentials = Qnil;
108
+ VALUE target = Qnil;
109
+ grpc_rb_channel* wrapper = NULL;
110
+ char* target_chars = NULL;
111
+ grpc_ruby_fork_guard();
112
+ /* "3" == 3 mandatory args */
113
+ rb_scan_args(argc, argv, "3", &target, &rb_channel_args, &rb_credentials);
114
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
115
+ target_chars = StringValueCStr(target);
116
+ grpc_channel_args channel_args;
117
+ memset(&channel_args, 0, sizeof(channel_args));
118
+ grpc_rb_hash_convert_to_channel_args(rb_channel_args, &channel_args);
119
+ if (TYPE(rb_credentials) == T_SYMBOL) {
120
+ if (id_insecure_channel != SYM2ID(rb_credentials)) {
121
+ rb_raise(rb_eTypeError,
122
+ "bad creds symbol, want :this_channel_is_insecure");
123
+ return Qnil;
124
+ }
125
+ grpc_channel_credentials* insecure_creds =
126
+ grpc_insecure_credentials_create();
127
+ wrapper->channel =
128
+ grpc_channel_create(target_chars, insecure_creds, &channel_args);
129
+ grpc_channel_credentials_release(insecure_creds);
130
+ } else {
131
+ grpc_channel_credentials* creds;
132
+ if (grpc_rb_is_channel_credentials(rb_credentials)) {
133
+ creds = grpc_rb_get_wrapped_channel_credentials(rb_credentials);
134
+ } else if (grpc_rb_is_xds_channel_credentials(rb_credentials)) {
135
+ creds = grpc_rb_get_wrapped_xds_channel_credentials(rb_credentials);
136
+ } else {
137
+ rb_raise(rb_eTypeError,
138
+ "bad creds, want ChannelCredentials or XdsChannelCredentials");
139
+ return Qnil;
140
+ }
141
+ wrapper->channel = grpc_channel_create(target_chars, creds, &channel_args);
142
+ }
143
+ grpc_rb_channel_args_destroy(&channel_args);
144
+ if (wrapper->channel == NULL) {
145
+ rb_raise(rb_eRuntimeError, "could not create an rpc channel to target:%s",
146
+ target_chars);
147
+ return Qnil;
148
+ }
149
+ rb_ivar_set(self, id_target, target);
150
+ rb_ivar_set(self, id_channel_recreation_mu, rb_mutex_new());
151
+ return self;
152
+ }
153
+
154
+ /*
155
+ call-seq:
156
+ ch.connectivity_state -> state
157
+ ch.connectivity_state(true) -> state
158
+
159
+ Indicates the current state of the channel, whose value is one of the
160
+ constants defined in GRPC::Core::ConnectivityStates.
161
+
162
+ It also tries to connect if the channel is idle in the second form. */
163
+ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE* argv,
164
+ VALUE self) {
165
+ VALUE try_to_connect_param = Qfalse;
166
+ grpc_rb_channel* wrapper = NULL;
167
+ /* "01" == 0 mandatory args, 1 (try_to_connect) is optional */
168
+ rb_scan_args(argc, argv, "01", &try_to_connect_param);
169
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
170
+ if (wrapper->channel == NULL) {
171
+ rb_raise(rb_eRuntimeError, "closed!");
172
+ return Qnil;
173
+ }
174
+ bool try_to_connect = RTEST(try_to_connect_param) ? true : false;
175
+ int state =
176
+ grpc_channel_check_connectivity_state(wrapper->channel, try_to_connect);
177
+ return LONG2NUM(state);
178
+ }
179
+
180
+ /* Wait until the channel's connectivity state becomes different from
181
+ * "last_state", or "deadline" expires.
182
+ * Returns true if the channel's connectivity state becomes different
183
+ * from "last_state" within "deadline".
184
+ * Returns false if "deadline" expires before the channel's connectivity
185
+ * state changes from "last_state".
186
+ * */
187
+ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self,
188
+ VALUE last_state,
189
+ VALUE rb_deadline) {
190
+ grpc_rb_channel* wrapper = NULL;
191
+ grpc_ruby_fork_guard();
192
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
193
+ if (wrapper->channel == NULL) {
194
+ rb_raise(rb_eRuntimeError, "closed!");
195
+ return Qnil;
196
+ }
197
+ if (!FIXNUM_P(last_state)) {
198
+ rb_raise(
199
+ rb_eTypeError,
200
+ "bad type for last_state. want a GRPC::Core::ChannelState constant");
201
+ return Qnil;
202
+ }
203
+ const void* tag = &wrapper;
204
+ gpr_timespec deadline = grpc_rb_time_timeval(rb_deadline, 0);
205
+ grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(NULL);
206
+ grpc_channel_watch_connectivity_state(wrapper->channel, NUM2LONG(last_state),
207
+ deadline, cq, tag);
208
+ grpc_event event =
209
+ rb_completion_queue_pluck(cq, tag, gpr_inf_future(GPR_CLOCK_REALTIME),
210
+ "grpc_channel_watch_connectivity_state");
211
+ // TODO(apolcyn): this CQ would leak if the thread were killed
212
+ // while polling queue_pluck, e.g. with Thread#kill. One fix may be
213
+ // to make this CQ owned by the channel object. Another fix could be to
214
+ // busy-poll watch_connectivity_state with a short deadline, without
215
+ // the GIL, rather than just polling CQ pluck, and destroy the CQ
216
+ // before exitting the no-GIL block.
217
+ grpc_completion_queue_shutdown(cq);
218
+ grpc_rb_completion_queue_destroy(cq);
219
+ if (event.type == GRPC_OP_COMPLETE) {
220
+ return Qtrue;
221
+ } else if (event.type == GRPC_QUEUE_TIMEOUT) {
222
+ return Qfalse;
223
+ } else {
224
+ grpc_absl_log_int(
225
+ GPR_ERROR,
226
+ "GRPC_RUBY: unexpected grpc_channel_watch_connectivity_state result:",
227
+ event.type);
228
+ return Qfalse;
229
+ }
230
+ }
231
+
232
+ /* Create a call given a grpc_channel, in order to call method. The request
233
+ is not sent until grpc_call_invoke is called. */
234
+ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask,
235
+ VALUE method, VALUE host,
236
+ VALUE deadline) {
237
+ VALUE res = Qnil;
238
+ grpc_rb_channel* wrapper = NULL;
239
+ grpc_call* call = NULL;
240
+ grpc_call* parent_call = NULL;
241
+ grpc_completion_queue* cq = NULL;
242
+ int flags = GRPC_PROPAGATE_DEFAULTS;
243
+ grpc_slice method_slice;
244
+ grpc_slice host_slice;
245
+ grpc_slice* host_slice_ptr = NULL;
246
+ char* tmp_str = NULL;
247
+ grpc_ruby_fork_guard();
248
+ if (host != Qnil) {
249
+ host_slice =
250
+ grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host));
251
+ host_slice_ptr = &host_slice;
252
+ }
253
+ if (mask != Qnil) {
254
+ flags = NUM2UINT(mask);
255
+ }
256
+ if (parent != Qnil) {
257
+ parent_call = grpc_rb_get_wrapped_call(parent);
258
+ }
259
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
260
+ if (wrapper->channel == NULL) {
261
+ rb_raise(rb_eRuntimeError, "closed!");
262
+ return Qnil;
263
+ }
264
+ cq = grpc_completion_queue_create_for_pluck(NULL);
265
+ method_slice =
266
+ grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method));
267
+ call = grpc_channel_create_call(wrapper->channel, parent_call, flags, cq,
268
+ method_slice, host_slice_ptr,
269
+ grpc_rb_time_timeval(deadline,
270
+ /* absolute time */ 0),
271
+ NULL);
272
+ if (call == NULL) {
273
+ tmp_str = grpc_slice_to_c_string(method_slice);
274
+ rb_raise(rb_eRuntimeError, "cannot create call with method %s", tmp_str);
275
+ return Qnil;
276
+ }
277
+ grpc_slice_unref(method_slice);
278
+ if (host_slice_ptr != NULL) {
279
+ grpc_slice_unref(host_slice);
280
+ }
281
+ res = grpc_rb_wrap_call(call, cq);
282
+ /* Make this channel an instance attribute of the call so that it is not GCed
283
+ * before the call. */
284
+ rb_ivar_set(res, id_channel, self);
285
+ return res;
286
+ }
287
+
288
+ /* Closes the channel, calling it's destroy method */
289
+ /* Note this is an API-level call; a wrapped channel's finalizer doesn't call
290
+ * this */
291
+ static VALUE grpc_rb_channel_destroy(VALUE self) {
292
+ grpc_rb_channel* wrapper = NULL;
293
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
294
+ if (wrapper->channel != NULL) {
295
+ grpc_channel_destroy(wrapper->channel);
296
+ wrapper->channel = NULL;
297
+ }
298
+ return Qnil;
299
+ }
300
+
301
+ /* Called to obtain the target that this channel accesses. */
302
+ static VALUE grpc_rb_channel_get_target(VALUE self) {
303
+ grpc_rb_channel* wrapper = NULL;
304
+ VALUE res = Qnil;
305
+ char* target = NULL;
306
+ TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
307
+ target = grpc_channel_get_target(wrapper->channel);
308
+ res = rb_str_new2(target);
309
+ gpr_free(target);
310
+ return res;
311
+ }
312
+
313
+ static void Init_grpc_propagate_masks() {
314
+ /* Constants representing call propagation masks in grpc.h */
315
+ VALUE grpc_rb_mPropagateMasks =
316
+ rb_define_module_under(grpc_rb_mGrpcCore, "PropagateMasks");
317
+ rb_define_const(grpc_rb_mPropagateMasks, "DEADLINE",
318
+ UINT2NUM(GRPC_PROPAGATE_DEADLINE));
319
+ rb_define_const(grpc_rb_mPropagateMasks, "CENSUS_STATS_CONTEXT",
320
+ UINT2NUM(GRPC_PROPAGATE_CENSUS_STATS_CONTEXT));
321
+ rb_define_const(grpc_rb_mPropagateMasks, "CENSUS_TRACING_CONTEXT",
322
+ UINT2NUM(GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT));
323
+ rb_define_const(grpc_rb_mPropagateMasks, "CANCELLATION",
324
+ UINT2NUM(GRPC_PROPAGATE_CANCELLATION));
325
+ rb_define_const(grpc_rb_mPropagateMasks, "DEFAULTS",
326
+ UINT2NUM(GRPC_PROPAGATE_DEFAULTS));
327
+ }
328
+
329
+ static void Init_grpc_connectivity_states() {
330
+ /* Constants representing call propagation masks in grpc.h */
331
+ VALUE grpc_rb_mConnectivityStates =
332
+ rb_define_module_under(grpc_rb_mGrpcCore, "ConnectivityStates");
333
+ rb_define_const(grpc_rb_mConnectivityStates, "IDLE",
334
+ LONG2NUM(GRPC_CHANNEL_IDLE));
335
+ rb_define_const(grpc_rb_mConnectivityStates, "CONNECTING",
336
+ LONG2NUM(GRPC_CHANNEL_CONNECTING));
337
+ rb_define_const(grpc_rb_mConnectivityStates, "READY",
338
+ LONG2NUM(GRPC_CHANNEL_READY));
339
+ rb_define_const(grpc_rb_mConnectivityStates, "TRANSIENT_FAILURE",
340
+ LONG2NUM(GRPC_CHANNEL_TRANSIENT_FAILURE));
341
+ rb_define_const(grpc_rb_mConnectivityStates, "FATAL_FAILURE",
342
+ LONG2NUM(GRPC_CHANNEL_SHUTDOWN));
343
+ }
344
+
345
+ void Init_grpc_channel() {
346
+ grpc_rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
347
+ rb_undef_alloc_func(grpc_rb_cChannelArgs);
348
+ grpc_rb_cChannel =
349
+ rb_define_class_under(grpc_rb_mGrpcCore, "Channel", rb_cObject);
350
+
351
+ /* Allocates an object managed by the ruby runtime */
352
+ rb_define_alloc_func(grpc_rb_cChannel, grpc_rb_channel_alloc);
353
+
354
+ /* Provides a ruby constructor and support for dup/clone. */
355
+ rb_define_method(grpc_rb_cChannel, "initialize", grpc_rb_channel_init, -1);
356
+ rb_define_method(grpc_rb_cChannel, "initialize_copy",
357
+ grpc_rb_cannot_init_copy, 1);
358
+
359
+ /* Add ruby analogues of the Channel methods. */
360
+ rb_define_method(grpc_rb_cChannel, "connectivity_state",
361
+ grpc_rb_channel_get_connectivity_state, -1);
362
+ rb_define_method(grpc_rb_cChannel, "watch_connectivity_state",
363
+ grpc_rb_channel_watch_connectivity_state, 2);
364
+ rb_define_method(grpc_rb_cChannel, "create_call", grpc_rb_channel_create_call,
365
+ 5);
366
+ rb_define_method(grpc_rb_cChannel, "target", grpc_rb_channel_get_target, 0);
367
+ rb_define_method(grpc_rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
368
+ rb_define_alias(grpc_rb_cChannel, "close", "destroy");
369
+
370
+ id_channel = rb_intern("__channel");
371
+ id_target = rb_intern("__target");
372
+ id_channel_recreation_mu = rb_intern("__channel_recreation_mu");
373
+ rb_define_const(grpc_rb_cChannel, "SSL_TARGET",
374
+ ID2SYM(rb_intern(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
375
+ rb_define_const(grpc_rb_cChannel, "ENABLE_CENSUS",
376
+ ID2SYM(rb_intern(GRPC_ARG_ENABLE_CENSUS)));
377
+ rb_define_const(grpc_rb_cChannel, "MAX_CONCURRENT_STREAMS",
378
+ ID2SYM(rb_intern(GRPC_ARG_MAX_CONCURRENT_STREAMS)));
379
+ rb_define_const(grpc_rb_cChannel, "MAX_MESSAGE_LENGTH",
380
+ ID2SYM(rb_intern(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH)));
381
+ id_insecure_channel = rb_intern("this_channel_is_insecure");
382
+ Init_grpc_propagate_masks();
383
+ Init_grpc_connectivity_states();
384
+ }
385
+
386
+ /* Gets the wrapped channel from the ruby wrapper */
387
+ grpc_channel* grpc_rb_get_wrapped_channel(VALUE v) {
388
+ grpc_rb_channel* wrapper = NULL;
389
+ TypedData_Get_Struct(v, grpc_rb_channel, &grpc_channel_data_type, wrapper);
390
+ return wrapper->channel;
391
+ }
@@ -0,0 +1,32 @@
1
+ /*
2
+ *
3
+ * Copyright 2015 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #ifndef GRPC_RB_CHANNEL_H_
20
+ #define GRPC_RB_CHANNEL_H_
21
+
22
+ #include <ruby/ruby.h>
23
+
24
+ #include <grpc/grpc.h>
25
+
26
+ /* Initializes the Channel class. */
27
+ void Init_grpc_channel();
28
+
29
+ /* Gets the wrapped channel from the ruby wrapper */
30
+ grpc_channel* grpc_rb_get_wrapped_channel(VALUE v);
31
+
32
+ #endif /* GRPC_RB_CHANNEL_H_ */
@@ -0,0 +1,174 @@
1
+ /*
2
+ *
3
+ * Copyright 2015 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #include <ruby/ruby.h>
20
+
21
+ #include "rb_channel_args.h"
22
+
23
+ #include <grpc/grpc.h>
24
+ #include <grpc/support/alloc.h>
25
+ #include <grpc/support/log.h>
26
+ #include <grpc/support/string_util.h>
27
+
28
+ #include "rb_grpc.h"
29
+ #include "rb_grpc_imports.generated.h"
30
+
31
+ static rb_data_type_t grpc_rb_channel_args_data_type = {
32
+ "grpc_channel_args",
33
+ {GRPC_RB_GC_NOT_MARKED,
34
+ GRPC_RB_GC_DONT_FREE,
35
+ GRPC_RB_MEMSIZE_UNAVAILABLE,
36
+ {NULL, NULL}},
37
+ NULL,
38
+ NULL,
39
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
40
+ RUBY_TYPED_FREE_IMMEDIATELY
41
+ #endif
42
+ };
43
+
44
+ /* A callback the processes the hash key values in channel_args hash */
45
+ static int grpc_rb_channel_create_in_process_add_args_hash_cb(VALUE key,
46
+ VALUE val,
47
+ VALUE args_obj) {
48
+ const char* the_key;
49
+ grpc_channel_args* args;
50
+
51
+ switch (TYPE(key)) {
52
+ case T_STRING:
53
+ the_key = StringValuePtr(key);
54
+ break;
55
+
56
+ case T_SYMBOL:
57
+ the_key = rb_id2name(SYM2ID(key));
58
+ break;
59
+
60
+ default:
61
+ rb_raise(rb_eTypeError, "bad chan arg: got <%s>, want <String|Symbol>",
62
+ rb_obj_classname(key));
63
+ return ST_STOP;
64
+ }
65
+
66
+ TypedData_Get_Struct(args_obj, grpc_channel_args,
67
+ &grpc_rb_channel_args_data_type, args);
68
+ if (args->num_args <= 0) {
69
+ rb_raise(rb_eRuntimeError, "hash_cb bug: num_args is %lu for key:%s",
70
+ args->num_args, StringValueCStr(key));
71
+ return ST_STOP;
72
+ }
73
+
74
+ args->args[args->num_args - 1].key = gpr_strdup(the_key);
75
+ switch (TYPE(val)) {
76
+ case T_SYMBOL:
77
+ args->args[args->num_args - 1].type = GRPC_ARG_STRING;
78
+ args->args[args->num_args - 1].value.string =
79
+ gpr_strdup(rb_id2name(SYM2ID(val)));
80
+ --args->num_args;
81
+ return ST_CONTINUE;
82
+
83
+ case T_STRING:
84
+ args->args[args->num_args - 1].type = GRPC_ARG_STRING;
85
+ args->args[args->num_args - 1].value.string =
86
+ gpr_strdup(StringValueCStr(val));
87
+ --args->num_args;
88
+ return ST_CONTINUE;
89
+
90
+ case T_FIXNUM:
91
+ args->args[args->num_args - 1].type = GRPC_ARG_INTEGER;
92
+ args->args[args->num_args - 1].value.integer = NUM2INT(val);
93
+ --args->num_args;
94
+ return ST_CONTINUE;
95
+
96
+ default:
97
+ rb_raise(rb_eTypeError, "%s: bad value: got <%s>, want <String|Fixnum>",
98
+ StringValueCStr(key), rb_obj_classname(val));
99
+ return ST_STOP;
100
+ }
101
+ rb_raise(rb_eRuntimeError, "impl bug: hash_cb reached to far while on key:%s",
102
+ StringValueCStr(key));
103
+ return ST_STOP;
104
+ }
105
+
106
+ /* channel_convert_params allows the call to
107
+ grpc_rb_hash_convert_to_channel_args to be made within an rb_protect
108
+ exception-handler. This allows any allocated memory to be freed before
109
+ propagating any exception that occurs */
110
+ typedef struct channel_convert_params {
111
+ VALUE src_hash;
112
+ grpc_channel_args* dst;
113
+ } channel_convert_params;
114
+
115
+ static VALUE grpc_rb_hash_convert_to_channel_args0(VALUE as_value) {
116
+ ID id_size = rb_intern("size");
117
+ VALUE grpc_rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
118
+ rb_undef_alloc_func(grpc_rb_cChannelArgs);
119
+ channel_convert_params* params = (channel_convert_params*)as_value;
120
+ size_t num_args = 0;
121
+
122
+ if (!NIL_P(params->src_hash) && TYPE(params->src_hash) != T_HASH) {
123
+ rb_raise(rb_eTypeError, "bad channel args: got:<%s> want: a hash or nil",
124
+ rb_obj_classname(params->src_hash));
125
+ return Qnil;
126
+ }
127
+
128
+ if (TYPE(params->src_hash) == T_HASH) {
129
+ num_args = NUM2INT(rb_funcall(params->src_hash, id_size, 0));
130
+ params->dst->num_args = num_args;
131
+ params->dst->args = ALLOC_N(grpc_arg, num_args);
132
+ MEMZERO(params->dst->args, grpc_arg, num_args);
133
+ rb_hash_foreach(
134
+ params->src_hash, grpc_rb_channel_create_in_process_add_args_hash_cb,
135
+ TypedData_Wrap_Struct(grpc_rb_cChannelArgs,
136
+ &grpc_rb_channel_args_data_type, params->dst));
137
+ /* reset num_args as grpc_rb_channel_create_in_process_add_args_hash_cb
138
+ * decrements it during has processing */
139
+ params->dst->num_args = num_args;
140
+ }
141
+ return Qnil;
142
+ }
143
+
144
+ void grpc_rb_hash_convert_to_channel_args(VALUE src_hash,
145
+ grpc_channel_args* dst) {
146
+ channel_convert_params params;
147
+ int status = 0;
148
+
149
+ /* Make a protected call to grpc_rb_hash_convert_channel_args */
150
+ params.src_hash = src_hash;
151
+ params.dst = dst;
152
+ rb_protect(grpc_rb_hash_convert_to_channel_args0, (VALUE)&params, &status);
153
+ if (status != 0) {
154
+ if (dst->args != NULL) {
155
+ /* Free any allocated memory before propagating the error */
156
+ xfree(dst->args);
157
+ }
158
+ rb_jump_tag(status);
159
+ }
160
+ }
161
+
162
+ void grpc_rb_channel_args_destroy(grpc_channel_args* args) {
163
+ GRPC_RUBY_ASSERT(args != NULL);
164
+ if (args->args == NULL) return;
165
+ for (int i = 0; i < args->num_args; i++) {
166
+ // the key was created with gpr_strdup
167
+ gpr_free(args->args[i].key);
168
+ if (args->args[i].type == GRPC_ARG_STRING) {
169
+ // we own string pointers, which were created with gpr_strdup
170
+ gpr_free(args->args[i].value.string);
171
+ }
172
+ }
173
+ xfree(args->args);
174
+ }
@@ -0,0 +1,42 @@
1
+ /*
2
+ *
3
+ * Copyright 2015 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #ifndef GRPC_RB_CHANNEL_ARGS_H_
20
+ #define GRPC_RB_CHANNEL_ARGS_H_
21
+
22
+ #include <ruby/ruby.h>
23
+
24
+ #include <grpc/grpc.h>
25
+
26
+ /* Converts a hash object containing channel args to a channel args instance.
27
+ *
28
+ * This func ALLOCs args->args. The caller is responsible for freeing it. If
29
+ * a ruby error is raised during processing of the hash values, the func takes
30
+ * care to deallocate any memory allocated so far, and propagate the error.
31
+ *
32
+ * @param src_hash A ruby hash
33
+ * @param dst the grpc_channel_args that the hash entries will be added to.
34
+ */
35
+ void grpc_rb_hash_convert_to_channel_args(VALUE src_hash,
36
+ grpc_channel_args* dst);
37
+
38
+ /* Destroys inner fields of args (does not deallocate the args pointer itself)
39
+ */
40
+ void grpc_rb_channel_args_destroy(grpc_channel_args* args);
41
+
42
+ #endif /* GRPC_RB_CHANNEL_ARGS_H_ */