grpc 1.56.2-x86-mingw32 → 1.57.0-x86-mingw32
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.
- checksums.yaml +4 -4
- data/grpc_c.32-msvcrt.ruby +0 -0
- data/src/ruby/bin/math_pb.rb +24 -18
- data/src/ruby/ext/grpc/extconf.rb +19 -18
- data/src/ruby/ext/grpc/rb_call.c +62 -39
- data/src/ruby/ext/grpc/rb_call_credentials.c +0 -1
- data/src/ruby/ext/grpc/rb_channel.c +109 -84
- data/src/ruby/ext/grpc/rb_channel.h +1 -0
- data/src/ruby/ext/grpc/rb_channel_args.c +16 -2
- data/src/ruby/ext/grpc/rb_channel_args.h +4 -0
- data/src/ruby/ext/grpc/rb_channel_credentials.c +0 -1
- data/src/ruby/ext/grpc/rb_compression_options.c +0 -1
- data/src/ruby/ext/grpc/rb_event_thread.c +22 -6
- data/src/ruby/ext/grpc/rb_event_thread.h +1 -0
- data/src/ruby/ext/grpc/rb_grpc.c +192 -30
- data/src/ruby/ext/grpc/rb_grpc.h +8 -2
- data/src/ruby/ext/grpc/rb_server.c +62 -45
- data/src/ruby/ext/grpc/rb_server_credentials.c +0 -1
- data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +0 -1
- data/src/ruby/ext/grpc/rb_xds_server_credentials.c +0 -1
- data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/3.0/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/3.1/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/3.2/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/generic/bidi_call.rb +2 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/grpc/health/v1/health_pb.rb +24 -13
- data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +24 -3
- data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +25 -111
- data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +25 -2
- metadata +3 -3
data/src/ruby/ext/grpc/rb_grpc.c
CHANGED
@@ -44,6 +44,11 @@
|
|
44
44
|
#include <grpc/support/log.h>
|
45
45
|
#include <grpc/support/time.h>
|
46
46
|
|
47
|
+
#ifdef GPR_LINUX
|
48
|
+
#include <sys/syscall.h>
|
49
|
+
#include <unistd.h>
|
50
|
+
#endif
|
51
|
+
|
47
52
|
static VALUE grpc_rb_cTimeVal = Qnil;
|
48
53
|
|
49
54
|
static rb_data_type_t grpc_rb_timespec_data_type = {
|
@@ -224,20 +229,51 @@ static void Init_grpc_time_consts() {
|
|
224
229
|
id_tv_nsec = rb_intern("tv_nsec");
|
225
230
|
}
|
226
231
|
|
232
|
+
static bool g_enable_fork_support;
|
233
|
+
|
234
|
+
#ifdef GPR_LINUX
|
235
|
+
static long sys_gettid() { return syscall(__NR_gettid); }
|
236
|
+
static bool can_enable_fork_support() { return true; }
|
237
|
+
#else
|
238
|
+
static long sys_gettid() { return 0; }
|
239
|
+
static bool can_enable_fork_support() { return false; }
|
240
|
+
#endif
|
241
|
+
|
227
242
|
#if GPR_WINDOWS
|
228
|
-
static void
|
229
|
-
static bool
|
243
|
+
static void grpc_ruby_basic_init(void) {}
|
244
|
+
static bool grpc_ruby_initial_pid(void) { return true; }
|
245
|
+
static bool grpc_ruby_initial_thread(void) { return true; }
|
246
|
+
static void grpc_ruby_reset_init_state(void) {}
|
230
247
|
#else
|
231
|
-
static pid_t
|
248
|
+
static pid_t g_init_pid;
|
249
|
+
static long g_init_tid;
|
232
250
|
|
233
|
-
static
|
234
|
-
GPR_ASSERT(
|
235
|
-
|
251
|
+
static bool grpc_ruby_initial_pid(void) {
|
252
|
+
GPR_ASSERT(g_init_pid != 0);
|
253
|
+
return g_init_pid == getpid();
|
236
254
|
}
|
237
255
|
|
238
|
-
static bool
|
239
|
-
GPR_ASSERT(
|
240
|
-
return
|
256
|
+
static bool grpc_ruby_initial_thread(void) {
|
257
|
+
GPR_ASSERT(g_init_tid != 0);
|
258
|
+
return sys_gettid() == g_init_tid;
|
259
|
+
}
|
260
|
+
|
261
|
+
static void grpc_ruby_reset_init_state(void) {
|
262
|
+
g_init_pid = getpid();
|
263
|
+
g_init_tid = sys_gettid();
|
264
|
+
}
|
265
|
+
|
266
|
+
static void grpc_ruby_basic_init(void) {
|
267
|
+
GPR_ASSERT(g_init_pid == 0);
|
268
|
+
GPR_ASSERT(g_init_tid == 0);
|
269
|
+
grpc_ruby_reset_init_state();
|
270
|
+
// TODO(apolcyn): ideally, we should share logic with C-core
|
271
|
+
// for determining whether or not fork support is enabled, rather
|
272
|
+
// than parsing the environment variable ourselves.
|
273
|
+
const char* res = getenv("GRPC_ENABLE_FORK_SUPPORT");
|
274
|
+
if (res != NULL && strcmp(res, "1") == 0) {
|
275
|
+
g_enable_fork_support = can_enable_fork_support();
|
276
|
+
}
|
241
277
|
}
|
242
278
|
#endif
|
243
279
|
|
@@ -258,59 +294,175 @@ VALUE sym_details = Qundef;
|
|
258
294
|
VALUE sym_metadata = Qundef;
|
259
295
|
|
260
296
|
static gpr_once g_once_init = GPR_ONCE_INIT;
|
297
|
+
static int64_t g_grpc_rb_prefork_pending; // synchronized by the GIL
|
298
|
+
static int64_t g_grpc_rb_num_fork_unsafe_threads; // synchronized by the GIL
|
261
299
|
|
262
300
|
void grpc_ruby_fork_guard() {
|
263
|
-
if
|
264
|
-
|
301
|
+
// Check if we're using gRPC between prefork and postfork
|
302
|
+
gpr_once_init(&g_once_init, grpc_ruby_basic_init);
|
303
|
+
if (g_grpc_rb_prefork_pending) {
|
304
|
+
rb_raise(rb_eRuntimeError,
|
305
|
+
"grpc cannot be used between calls to GRPC.prefork and "
|
306
|
+
"GRPC.postfork_child or GRPC.postfork_parent");
|
307
|
+
}
|
308
|
+
if (!grpc_ruby_initial_pid()) {
|
309
|
+
if (g_enable_fork_support) {
|
310
|
+
// Only way we can get here is by enabling for support and forking but not
|
311
|
+
// calling prefork
|
312
|
+
rb_raise(rb_eRuntimeError,
|
313
|
+
"grpc is in a broken state: GRPC.prefork must be called before "
|
314
|
+
"calling fork from a process using grpc");
|
315
|
+
} else {
|
316
|
+
rb_raise(rb_eRuntimeError,
|
317
|
+
"grpc cannot be used before and after forking unless the "
|
318
|
+
"GRPC_ENABLE_FORK_SUPPORT env var is set to \"1\" and the "
|
319
|
+
"platform supports it (linux only)");
|
320
|
+
}
|
265
321
|
}
|
266
322
|
}
|
267
323
|
|
268
|
-
static VALUE
|
269
|
-
static
|
324
|
+
static VALUE g_bg_thread_init_rb_mu = Qundef;
|
325
|
+
static bool g_bg_thread_init_done;
|
270
326
|
|
271
327
|
static void grpc_ruby_init_threads() {
|
272
328
|
// Avoid calling into ruby library (when creating threads here)
|
273
329
|
// in gpr_once_init. In general, it appears to be unsafe to call
|
274
330
|
// into the ruby library while holding a non-ruby mutex, because a gil yield
|
275
331
|
// could end up trying to lock onto that same mutex and deadlocking.
|
276
|
-
|
277
|
-
|
332
|
+
gpr_log(GPR_INFO,
|
333
|
+
"GRPC_RUBY: grpc_ruby_init_threads g_bg_thread_init_done=%d",
|
334
|
+
g_bg_thread_init_done);
|
335
|
+
rb_mutex_lock(g_bg_thread_init_rb_mu);
|
336
|
+
if (!g_bg_thread_init_done) {
|
278
337
|
grpc_rb_event_queue_thread_start();
|
279
338
|
grpc_rb_channel_polling_thread_start();
|
280
|
-
|
339
|
+
g_bg_thread_init_done = true;
|
281
340
|
}
|
282
|
-
rb_mutex_unlock(
|
341
|
+
rb_mutex_unlock(g_bg_thread_init_rb_mu);
|
283
342
|
}
|
284
343
|
|
285
344
|
static int64_t g_grpc_ruby_init_count;
|
286
345
|
|
287
346
|
void grpc_ruby_init() {
|
288
|
-
gpr_once_init(&g_once_init,
|
347
|
+
gpr_once_init(&g_once_init, grpc_ruby_basic_init);
|
348
|
+
grpc_ruby_fork_guard();
|
289
349
|
grpc_init();
|
290
350
|
grpc_ruby_init_threads();
|
291
351
|
// (only gpr_log after logging has been initialized)
|
292
352
|
gpr_log(GPR_DEBUG,
|
293
|
-
"GRPC_RUBY: grpc_ruby_init - prev
|
294
|
-
g_grpc_ruby_init_count
|
353
|
+
"GRPC_RUBY: grpc_ruby_init - g_enable_fork_support=%d prev "
|
354
|
+
"g_grpc_ruby_init_count:%" PRId64,
|
355
|
+
g_enable_fork_support, g_grpc_ruby_init_count++);
|
356
|
+
}
|
357
|
+
|
358
|
+
// fork APIs, useable on linux with env var: GRPC_ENABLE_FORK_SUPPORT=1
|
359
|
+
//
|
360
|
+
// Must be called once and only once before forking. Must be called on the
|
361
|
+
// same threads that gRPC was (lazy-)initialized on. One must not call
|
362
|
+
// into the gRPC library during or after prefork has been called, until
|
363
|
+
// the corresponding postfork_{parent,child} APIs have been called.
|
364
|
+
static VALUE grpc_rb_prefork(VALUE self) {
|
365
|
+
// This might be the first time we've called into the grpc library, so make
|
366
|
+
// sure basic one-time initialization is taken care of. Note that if this is
|
367
|
+
// the case, then grpc_init() will start up c-core threads; that's OK since
|
368
|
+
// they will be shut down in C-core's pthread_atfork handler.
|
369
|
+
gpr_once_init(&g_once_init, grpc_ruby_basic_init);
|
370
|
+
grpc_init();
|
371
|
+
if (!g_enable_fork_support) {
|
372
|
+
rb_raise(rb_eRuntimeError,
|
373
|
+
"forking with gRPC/Ruby is only supported on linux with env var: "
|
374
|
+
"GRPC_ENABLE_FORK_SUPPORT=1");
|
375
|
+
}
|
376
|
+
if (g_grpc_rb_prefork_pending) {
|
377
|
+
rb_raise(rb_eRuntimeError,
|
378
|
+
"GRPC.prefork already called without a matching "
|
379
|
+
"GRPC.postfork_{parent,child}");
|
380
|
+
}
|
381
|
+
if (!grpc_ruby_initial_thread()) {
|
382
|
+
rb_raise(rb_eRuntimeError,
|
383
|
+
"GRPC.prefork and fork need to be called from the same thread "
|
384
|
+
"that GRPC was initialized on (GRPC lazy-initializes when when "
|
385
|
+
"the first GRPC object is created");
|
386
|
+
}
|
387
|
+
if (g_grpc_rb_num_fork_unsafe_threads > 0) {
|
388
|
+
rb_raise(
|
389
|
+
rb_eRuntimeError,
|
390
|
+
"Detected at least %ld threads actively using grpc, so it is not safe "
|
391
|
+
"call GRPC.prefork or fork. Note that grpc-ruby servers and "
|
392
|
+
"bidirectional "
|
393
|
+
"streams manage background threads and are not fork safe.",
|
394
|
+
g_grpc_rb_num_fork_unsafe_threads);
|
395
|
+
}
|
396
|
+
g_grpc_rb_prefork_pending = true;
|
397
|
+
rb_mutex_lock(g_bg_thread_init_rb_mu);
|
398
|
+
if (g_bg_thread_init_done) {
|
399
|
+
grpc_rb_channel_polling_thread_stop();
|
400
|
+
grpc_rb_event_queue_thread_stop();
|
401
|
+
// all ruby-level background threads joined at this point
|
402
|
+
g_bg_thread_init_done = false;
|
403
|
+
}
|
404
|
+
rb_mutex_unlock(g_bg_thread_init_rb_mu);
|
405
|
+
return Qnil;
|
295
406
|
}
|
296
407
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
408
|
+
static VALUE grpc_rb_postfork_child(VALUE self) {
|
409
|
+
if (!g_grpc_rb_prefork_pending) {
|
410
|
+
rb_raise(rb_eRuntimeError,
|
411
|
+
"GRPC::postfork_child can only be called once following a "
|
412
|
+
"GRPC::prefork");
|
413
|
+
}
|
414
|
+
if (grpc_ruby_initial_pid()) {
|
415
|
+
rb_raise(rb_eRuntimeError,
|
416
|
+
"GRPC.postfork_child must be called only from the child process "
|
417
|
+
"after a fork");
|
418
|
+
}
|
419
|
+
grpc_ruby_reset_init_state();
|
420
|
+
grpc_ruby_init_threads();
|
421
|
+
g_grpc_rb_prefork_pending = false;
|
422
|
+
return Qnil;
|
304
423
|
}
|
305
424
|
|
425
|
+
static VALUE grpc_rb_postfork_parent(VALUE self) {
|
426
|
+
// TODO(apolcyn): check calling thread vs. thread that gRPC was initialized on
|
427
|
+
if (!g_grpc_rb_prefork_pending) {
|
428
|
+
rb_raise(rb_eRuntimeError,
|
429
|
+
"GRPC::postfork_parent can only be called once following a "
|
430
|
+
"GRPC::prefork");
|
431
|
+
}
|
432
|
+
if (!grpc_ruby_initial_pid()) {
|
433
|
+
rb_raise(rb_eRuntimeError,
|
434
|
+
"GRPC.postfork_parent must be called only from the parent process "
|
435
|
+
"after a fork");
|
436
|
+
}
|
437
|
+
if (!grpc_ruby_initial_thread()) {
|
438
|
+
rb_raise(rb_eRuntimeError,
|
439
|
+
"GRPC.postfork_parent needs to be called from the same thread "
|
440
|
+
"that GRPC.prefork (and fork) was called from");
|
441
|
+
}
|
442
|
+
grpc_ruby_init_threads();
|
443
|
+
g_grpc_rb_prefork_pending = false;
|
444
|
+
return Qnil;
|
445
|
+
}
|
446
|
+
|
447
|
+
// APIs to mark fork-unsafe sections from C-extension code
|
448
|
+
void grpc_rb_fork_unsafe_begin() { g_grpc_rb_num_fork_unsafe_threads++; }
|
449
|
+
|
450
|
+
void grpc_rb_fork_unsafe_end() { g_grpc_rb_num_fork_unsafe_threads--; }
|
451
|
+
|
452
|
+
// APIs to mark fork-unsafe sections from ruby code
|
453
|
+
static VALUE grpc_rb_fork_unsafe_begin_api() { grpc_rb_fork_unsafe_begin(); }
|
454
|
+
|
455
|
+
static VALUE grpc_rb_fork_unsafe_end_api() { grpc_rb_fork_unsafe_end(); }
|
456
|
+
|
457
|
+
// One-time initialization
|
306
458
|
void Init_grpc_c() {
|
307
459
|
if (!grpc_rb_load_core()) {
|
308
460
|
rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core");
|
309
461
|
return;
|
310
462
|
}
|
311
463
|
|
312
|
-
rb_global_variable(&
|
313
|
-
|
464
|
+
rb_global_variable(&g_bg_thread_init_rb_mu);
|
465
|
+
g_bg_thread_init_rb_mu = rb_mutex_new();
|
314
466
|
|
315
467
|
grpc_rb_mGRPC = rb_define_module("GRPC");
|
316
468
|
grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");
|
@@ -320,7 +472,7 @@ void Init_grpc_c() {
|
|
320
472
|
sym_code = ID2SYM(rb_intern("code"));
|
321
473
|
sym_details = ID2SYM(rb_intern("details"));
|
322
474
|
sym_metadata = ID2SYM(rb_intern("metadata"));
|
323
|
-
|
475
|
+
// init C-defined classes
|
324
476
|
Init_grpc_channel();
|
325
477
|
Init_grpc_call();
|
326
478
|
Init_grpc_call_credentials();
|
@@ -331,4 +483,14 @@ void Init_grpc_c() {
|
|
331
483
|
Init_grpc_xds_server_credentials();
|
332
484
|
Init_grpc_time_consts();
|
333
485
|
Init_grpc_compression_options();
|
486
|
+
// define fork APIs
|
487
|
+
rb_define_module_function(grpc_rb_mGRPC, "prefork", grpc_rb_prefork, 0);
|
488
|
+
rb_define_module_function(grpc_rb_mGRPC, "postfork_child",
|
489
|
+
grpc_rb_postfork_child, 0);
|
490
|
+
rb_define_module_function(grpc_rb_mGRPC, "postfork_parent",
|
491
|
+
grpc_rb_postfork_parent, 0);
|
492
|
+
rb_define_module_function(grpc_rb_mGrpcCore, "fork_unsafe_begin",
|
493
|
+
grpc_rb_fork_unsafe_begin_api, 0);
|
494
|
+
rb_define_module_function(grpc_rb_mGrpcCore, "fork_unsafe_end",
|
495
|
+
grpc_rb_fork_unsafe_end_api, 0);
|
334
496
|
}
|
data/src/ruby/ext/grpc/rb_grpc.h
CHANGED
@@ -70,8 +70,14 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval);
|
|
70
70
|
|
71
71
|
void grpc_ruby_fork_guard();
|
72
72
|
|
73
|
-
|
73
|
+
/* To be called once and only once before entering code section that is
|
74
|
+
* definitely not fork-safe. Used in conjunction with GRPC.prefork
|
75
|
+
* to catch for-unsafe processes and raise errors. */
|
76
|
+
void grpc_rb_fork_unsafe_begin();
|
77
|
+
|
78
|
+
/* To be called once and only once after each grpc_rb_fork_unsafe_begin*/
|
79
|
+
void grpc_rb_fork_unsafe_end();
|
74
80
|
|
75
|
-
void
|
81
|
+
void grpc_ruby_init();
|
76
82
|
|
77
83
|
#endif /* GRPC_RB_H_ */
|
@@ -106,10 +106,7 @@ static void grpc_rb_server_free_internal(void* p) {
|
|
106
106
|
}
|
107
107
|
|
108
108
|
/* Destroys server instances. */
|
109
|
-
static void grpc_rb_server_free(void* p) {
|
110
|
-
grpc_rb_server_free_internal(p);
|
111
|
-
grpc_ruby_shutdown();
|
112
|
-
}
|
109
|
+
static void grpc_rb_server_free(void* p) { grpc_rb_server_free_internal(p); }
|
113
110
|
|
114
111
|
static const rb_data_type_t grpc_rb_server_data_type = {
|
115
112
|
"grpc_server",
|
@@ -155,10 +152,7 @@ static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args) {
|
|
155
152
|
wrapper);
|
156
153
|
grpc_rb_hash_convert_to_channel_args(channel_args, &args);
|
157
154
|
srv = grpc_server_create(&args, NULL);
|
158
|
-
|
159
|
-
if (args.args != NULL) {
|
160
|
-
xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
|
161
|
-
}
|
155
|
+
grpc_rb_channel_args_destroy(&args);
|
162
156
|
if (srv == NULL) {
|
163
157
|
rb_raise(rb_eRuntimeError, "could not create a gRPC server, not sure why");
|
164
158
|
}
|
@@ -191,65 +185,88 @@ static void grpc_request_call_stack_cleanup(request_call_stack* st) {
|
|
191
185
|
grpc_call_details_destroy(&st->details);
|
192
186
|
}
|
193
187
|
|
194
|
-
|
195
|
-
|
188
|
+
struct server_request_call_args {
|
189
|
+
grpc_rb_server* server;
|
190
|
+
grpc_completion_queue* call_queue;
|
191
|
+
request_call_stack st;
|
192
|
+
};
|
193
|
+
|
194
|
+
static VALUE grpc_rb_server_request_call_try(VALUE value_args) {
|
195
|
+
grpc_rb_fork_unsafe_begin();
|
196
|
+
struct server_request_call_args* args =
|
197
|
+
(struct server_request_call_args*)value_args;
|
196
198
|
|
197
|
-
Requests notification of a new call on a server. */
|
198
|
-
static VALUE grpc_rb_server_request_call(VALUE self) {
|
199
|
-
grpc_rb_server* s = NULL;
|
200
199
|
grpc_call* call = NULL;
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
void* tag = (void*)&st;
|
206
|
-
grpc_completion_queue* call_queue =
|
207
|
-
grpc_completion_queue_create_for_pluck(NULL);
|
208
|
-
gpr_timespec deadline;
|
200
|
+
void* tag = (void*)&args->st;
|
201
|
+
|
202
|
+
args->call_queue = grpc_completion_queue_create_for_pluck(NULL);
|
203
|
+
grpc_request_call_stack_init(&args->st);
|
209
204
|
|
210
|
-
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
|
211
|
-
if (s->wrapped == NULL) {
|
212
|
-
rb_raise(rb_eRuntimeError, "destroyed!");
|
213
|
-
return Qnil;
|
214
|
-
}
|
215
|
-
grpc_request_call_stack_init(&st);
|
216
205
|
/* call grpc_server_request_call, then wait for it to complete using
|
217
206
|
* pluck_event */
|
218
|
-
err = grpc_server_request_call(
|
219
|
-
|
207
|
+
grpc_call_error err = grpc_server_request_call(
|
208
|
+
args->server->wrapped, &call, &args->st.details, &args->st.md_ary,
|
209
|
+
args->call_queue, args->server->queue, tag);
|
220
210
|
if (err != GRPC_CALL_OK) {
|
221
|
-
grpc_request_call_stack_cleanup(&st);
|
222
211
|
rb_raise(grpc_rb_eCallError,
|
223
212
|
"grpc_server_request_call failed: %s (code=%d)",
|
224
213
|
grpc_call_error_detail_of(err), err);
|
225
|
-
return Qnil;
|
226
214
|
}
|
227
215
|
|
228
|
-
ev = rb_completion_queue_pluck(
|
229
|
-
|
216
|
+
grpc_event ev = rb_completion_queue_pluck(
|
217
|
+
args->server->queue, tag, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
|
230
218
|
if (!ev.success) {
|
231
|
-
grpc_request_call_stack_cleanup(&st);
|
232
219
|
rb_raise(grpc_rb_eCallError, "request_call completion failed");
|
233
|
-
return Qnil;
|
234
220
|
}
|
235
221
|
|
236
222
|
/* build the NewServerRpc struct result */
|
237
|
-
deadline =
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
223
|
+
gpr_timespec deadline =
|
224
|
+
gpr_convert_clock_type(args->st.details.deadline, GPR_CLOCK_REALTIME);
|
225
|
+
VALUE result =
|
226
|
+
rb_struct_new(grpc_rb_sNewServerRpc,
|
227
|
+
grpc_rb_slice_to_ruby_string(args->st.details.method),
|
228
|
+
grpc_rb_slice_to_ruby_string(args->st.details.host),
|
229
|
+
rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
|
230
|
+
INT2NUM(deadline.tv_nsec / 1000)),
|
231
|
+
grpc_rb_md_ary_to_h(&args->st.md_ary),
|
232
|
+
grpc_rb_wrap_call(call, args->call_queue), NULL);
|
233
|
+
args->call_queue = NULL;
|
246
234
|
return result;
|
247
235
|
}
|
248
236
|
|
237
|
+
static VALUE grpc_rb_server_request_call_ensure(VALUE value_args) {
|
238
|
+
grpc_rb_fork_unsafe_end();
|
239
|
+
struct server_request_call_args* args =
|
240
|
+
(struct server_request_call_args*)value_args;
|
241
|
+
|
242
|
+
if (args->call_queue) {
|
243
|
+
grpc_rb_completion_queue_destroy(args->call_queue);
|
244
|
+
}
|
245
|
+
|
246
|
+
grpc_request_call_stack_cleanup(&args->st);
|
247
|
+
|
248
|
+
return Qnil;
|
249
|
+
}
|
250
|
+
|
251
|
+
/* call-seq:
|
252
|
+
server.request_call
|
253
|
+
|
254
|
+
Requests notification of a new call on a server. */
|
255
|
+
static VALUE grpc_rb_server_request_call(VALUE self) {
|
256
|
+
grpc_rb_server* s;
|
257
|
+
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
|
258
|
+
grpc_ruby_fork_guard();
|
259
|
+
if (s->wrapped == NULL) {
|
260
|
+
rb_raise(rb_eRuntimeError, "destroyed!");
|
261
|
+
}
|
262
|
+
struct server_request_call_args args = {.server = s, .call_queue = NULL};
|
263
|
+
return rb_ensure(grpc_rb_server_request_call_try, (VALUE)&args,
|
264
|
+
grpc_rb_server_request_call_ensure, (VALUE)&args);
|
265
|
+
}
|
266
|
+
|
249
267
|
static VALUE grpc_rb_server_start(VALUE self) {
|
250
268
|
grpc_rb_server* s = NULL;
|
251
269
|
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
|
252
|
-
|
253
270
|
grpc_ruby_fork_guard();
|
254
271
|
if (s->wrapped == NULL) {
|
255
272
|
rb_raise(rb_eRuntimeError, "destroyed!");
|
@@ -62,7 +62,6 @@ static void grpc_rb_server_credentials_free_internal(void* p) {
|
|
62
62
|
/* Destroys the server credentials instances. */
|
63
63
|
static void grpc_rb_server_credentials_free(void* p) {
|
64
64
|
grpc_rb_server_credentials_free_internal(p);
|
65
|
-
grpc_ruby_shutdown();
|
66
65
|
}
|
67
66
|
|
68
67
|
/* Protects the mark object from GC */
|
@@ -62,7 +62,6 @@ static void grpc_rb_xds_channel_credentials_free_internal(void* p) {
|
|
62
62
|
/* Destroys the credentials instances. */
|
63
63
|
static void grpc_rb_xds_channel_credentials_free(void* p) {
|
64
64
|
grpc_rb_xds_channel_credentials_free_internal(p);
|
65
|
-
grpc_ruby_shutdown();
|
66
65
|
}
|
67
66
|
|
68
67
|
/* Protects the mark object from GC */
|
@@ -63,7 +63,6 @@ static void grpc_rb_xds_server_credentials_free_internal(void* p) {
|
|
63
63
|
/* Destroys the server credentials instances. */
|
64
64
|
static void grpc_rb_xds_server_credentials_free(void* p) {
|
65
65
|
grpc_rb_xds_server_credentials_free_internal(p);
|
66
|
-
grpc_ruby_shutdown();
|
67
66
|
}
|
68
67
|
|
69
68
|
/* Protects the mark object from GC */
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -141,6 +141,7 @@ module GRPC
|
|
141
141
|
# set_output_stream_done is relevant on client-side
|
142
142
|
# rubocop:disable Metrics/PerceivedComplexity
|
143
143
|
def write_loop(requests, is_client: true, set_output_stream_done: nil)
|
144
|
+
GRPC::Core.fork_unsafe_begin
|
144
145
|
GRPC.logger.debug('bidi-write-loop: starting')
|
145
146
|
count = 0
|
146
147
|
requests.each do |req|
|
@@ -181,6 +182,7 @@ module GRPC
|
|
181
182
|
raise e
|
182
183
|
end
|
183
184
|
ensure
|
185
|
+
GRPC::Core.fork_unsafe_end
|
184
186
|
set_output_stream_done.call if is_client
|
185
187
|
end
|
186
188
|
# rubocop:enable Metrics/PerceivedComplexity
|
@@ -1,23 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
3
|
# source: grpc/health/v1/health.proto
|
3
4
|
|
4
5
|
require 'google/protobuf'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
7
|
+
|
8
|
+
descriptor_data = "\n\x1bgrpc/health/v1/health.proto\x12\x0egrpc.health.v1\"%\n\x12HealthCheckRequest\x12\x0f\n\x07service\x18\x01 \x01(\t\"\xa9\x01\n\x13HealthCheckResponse\x12\x41\n\x06status\x18\x01 \x01(\x0e\x32\x31.grpc.health.v1.HealthCheckResponse.ServingStatus\"O\n\rServingStatus\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07SERVING\x10\x01\x12\x0f\n\x0bNOT_SERVING\x10\x02\x12\x13\n\x0fSERVICE_UNKNOWN\x10\x03\x32\xae\x01\n\x06Health\x12P\n\x05\x43heck\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse\x12R\n\x05Watch\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse0\x01\x42\x61\n\x11io.grpc.health.v1B\x0bHealthProtoP\x01Z,google.golang.org/grpc/health/grpc_health_v1\xaa\x02\x0eGrpc.Health.V1b\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
|
12
|
+
begin
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
rescue TypeError => e
|
15
|
+
# Compatibility code: will be removed in the next major version.
|
16
|
+
require 'google/protobuf/descriptor_pb'
|
17
|
+
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
18
|
+
parsed.clear_dependency
|
19
|
+
serialized = parsed.class.encode(parsed)
|
20
|
+
file = pool.add_serialized_file(serialized)
|
21
|
+
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
22
|
+
imports = [
|
23
|
+
]
|
24
|
+
imports.each do |type_name, expected_filename|
|
25
|
+
import_file = pool.lookup(type_name).file_descriptor
|
26
|
+
if import_file.name != expected_filename
|
27
|
+
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
19
28
|
end
|
20
29
|
end
|
30
|
+
warn "Each proto file must use a consistent fully-qualified name."
|
31
|
+
warn "This will become an error in the next major version."
|
21
32
|
end
|
22
33
|
|
23
34
|
module Grpc
|
@@ -1,13 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
3
|
# source: src/proto/grpc/testing/empty.proto
|
3
4
|
|
4
5
|
require 'google/protobuf'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
descriptor_data = "\n\"src/proto/grpc/testing/empty.proto\x12\x0cgrpc.testing\"\x07\n\x05\x45mptyb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
|
12
|
+
begin
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
rescue TypeError => e
|
15
|
+
# Compatibility code: will be removed in the next major version.
|
16
|
+
require 'google/protobuf/descriptor_pb'
|
17
|
+
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
18
|
+
parsed.clear_dependency
|
19
|
+
serialized = parsed.class.encode(parsed)
|
20
|
+
file = pool.add_serialized_file(serialized)
|
21
|
+
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
22
|
+
imports = [
|
23
|
+
]
|
24
|
+
imports.each do |type_name, expected_filename|
|
25
|
+
import_file = pool.lookup(type_name).file_descriptor
|
26
|
+
if import_file.name != expected_filename
|
27
|
+
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
9
28
|
end
|
10
29
|
end
|
30
|
+
warn "Each proto file must use a consistent fully-qualified name."
|
31
|
+
warn "This will become an error in the next major version."
|
11
32
|
end
|
12
33
|
|
13
34
|
module Grpc
|