defer grpc_init and background threads until first grpc object init

pull/10670/head
Alexander Polcyn 8 years ago
parent bb75f3ea82
commit 2a9b5d77ed
  1. 4
      src/ruby/ext/grpc/rb_call_credentials.c
  2. 11
      src/ruby/ext/grpc/rb_channel.c
  3. 2
      src/ruby/ext/grpc/rb_channel.h
  4. 3
      src/ruby/ext/grpc/rb_channel_credentials.c
  5. 7
      src/ruby/ext/grpc/rb_compression_options.c
  6. 22
      src/ruby/ext/grpc/rb_grpc.c
  7. 2
      src/ruby/ext/grpc/rb_grpc.h
  8. 6
      src/ruby/ext/grpc/rb_server.c

@ -221,6 +221,8 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) {
grpc_call_credentials *creds = NULL;
grpc_metadata_credentials_plugin plugin;
grpc_ruby_once_init();
TypedData_Get_Struct(self, grpc_rb_call_credentials,
&grpc_rb_call_credentials_data_type, wrapper);
@ -281,8 +283,6 @@ void Init_grpc_call_credentials() {
grpc_rb_call_credentials_compose, -1);
id_callback = rb_intern("__callback");
grpc_rb_event_queue_thread_start();
}
/* Gets the wrapped grpc_call_credentials from the ruby wrapper */

@ -166,6 +166,8 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
grpc_channel_args args;
MEMZERO(&args, grpc_channel_args, 1);
grpc_ruby_once_init();
/* "3" == 3 mandatory args */
rb_scan_args(argc, argv, "3", &target, &channel_args, &credentials);
@ -521,10 +523,12 @@ static VALUE run_poll_channels_loop(VALUE arg) {
* calls - so that c-core can reconnect if needed, when there aren't any RPC's.
* TODO(apolcyn) remove this when core handles new RPCs on dead connections.
*/
static void start_poll_channels_loop() {
channel_polling_cq = grpc_completion_queue_create(NULL);
void grpc_rb_channel_polling_thread_start() {
GPR_ASSERT(!abort_channel_polling);
GPR_ASSERT(channel_polling_cq == NULL);
gpr_mu_init(&global_connection_polling_mu);
abort_channel_polling = 0;
channel_polling_cq = grpc_completion_queue_create(NULL);
rb_thread_create(run_poll_channels_loop, NULL);
}
@ -597,7 +601,6 @@ void Init_grpc_channel() {
id_insecure_channel = rb_intern("this_channel_is_insecure");
Init_grpc_propagate_masks();
Init_grpc_connectivity_states();
start_poll_channels_loop();
}
/* Gets the wrapped channel from the ruby wrapper */

@ -41,6 +41,8 @@
/* Initializes the Channel class. */
void Init_grpc_channel();
void grpc_rb_channel_polling_thread_start();
/* Gets the wrapped channel from the ruby wrapper */
grpc_channel* grpc_rb_get_wrapped_channel(VALUE v);

@ -156,6 +156,9 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self)
grpc_ssl_pem_key_cert_pair key_cert_pair;
const char *pem_root_certs_cstr = NULL;
MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1);
grpc_ruby_once_init();
/* "03" == no mandatory arg, 3 optional */
rb_scan_args(argc, argv, "03", &pem_root_certs, &pem_private_key,
&pem_cert_chain);

@ -100,8 +100,11 @@ static rb_data_type_t grpc_rb_compression_options_data_type = {
Allocate the wrapped grpc compression options and
initialize it here too. */
static VALUE grpc_rb_compression_options_alloc(VALUE cls) {
grpc_rb_compression_options *wrapper =
gpr_malloc(sizeof(grpc_rb_compression_options));
grpc_rb_compression_options *wrapper = NULL;
grpc_ruby_once_init();
wrapper = gpr_malloc(sizeof(grpc_rb_compression_options));
wrapper->wrapped = NULL;
wrapper->wrapped = gpr_malloc(sizeof(grpc_compression_options));
grpc_compression_options_init(wrapper->wrapped);

@ -50,6 +50,8 @@
#include "rb_server.h"
#include "rb_server_credentials.h"
#include "rb_compression_options.h"
#include "rb_event_thread.h"
#include "rb_channel.h"
static VALUE grpc_rb_cTimeVal = Qnil;
@ -291,17 +293,14 @@ VALUE sym_metadata = Qundef;
static gpr_once g_once_init = GPR_ONCE_INIT;
static void grpc_ruby_once_init() {
static void grpc_ruby_once_init_internal() {
grpc_init();
grpc_rb_event_queue_thread_start();
grpc_rb_channel_polling_thread_start();
atexit(grpc_rb_shutdown);
}
void Init_grpc_c() {
if (!grpc_rb_load_core()) {
rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core");
return;
}
void grpc_ruby_once_init() {
/* ruby_vm_at_exit doesn't seem to be working. It would crash once every
* blue moon, and some users are getting it repeatedly. See the discussions
* - https://github.com/grpc/grpc/pull/5337
@ -312,7 +311,14 @@ void Init_grpc_c() {
* then loaded again by another VM within the same process, we need to
* schedule our initialization and destruction only once.
*/
gpr_once_init(&g_once_init, grpc_ruby_once_init);
gpr_once_init(&g_once_init, grpc_ruby_once_init_internal);
}
void Init_grpc_c() {
if (!grpc_rb_load_core()) {
rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core");
return;
}
grpc_rb_mGRPC = rb_define_module("GRPC");
grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");

@ -82,4 +82,6 @@ VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self);
/* grpc_rb_time_timeval creates a gpr_timespec from a ruby time object. */
gpr_timespec grpc_rb_time_timeval(VALUE time, int interval);
void grpc_ruby_once_init();
#endif /* GRPC_RB_H_ */

@ -131,11 +131,15 @@ static VALUE grpc_rb_server_alloc(VALUE cls) {
Initializes server instances. */
static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args) {
grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
grpc_completion_queue *cq = NULL;
grpc_rb_server *wrapper = NULL;
grpc_server *srv = NULL;
grpc_channel_args args;
MEMZERO(&args, grpc_channel_args, 1);
grpc_ruby_once_init();
cq = grpc_completion_queue_create(NULL);
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type,
wrapper);
grpc_rb_hash_convert_to_channel_args(channel_args, &args);

Loading…
Cancel
Save