コード例 #1
0
ファイル: rb_server.c プロジェクト: Alex-duzhichao/grpc
static void destroy_server(grpc_rb_server *server, gpr_timespec deadline) {
  grpc_event ev;
  if (server->wrapped != NULL) {
    grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
    ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
    if (ev.type == GRPC_QUEUE_TIMEOUT) {
      grpc_server_cancel_all_calls(server->wrapped);
      rb_completion_queue_pluck(server->queue, NULL,
                                gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
    }
    grpc_server_destroy(server->wrapped);
    grpc_rb_completion_queue_destroy(server->queue);
    server->wrapped = NULL;
    server->queue = NULL;
  }
}
コード例 #2
0
ファイル: rb_server.c プロジェクト: deepaklukose/grpc
static void destroy_server(grpc_rb_server* server, gpr_timespec deadline) {
  grpc_event ev;
  // This can be started by app or implicitly by GC. Avoid a race between these.
  if (gpr_atm_full_fetch_add(&server->shutdown_started, (gpr_atm)1) == 0) {
    if (server->wrapped != NULL) {
      grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
      ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
      if (ev.type == GRPC_QUEUE_TIMEOUT) {
        grpc_server_cancel_all_calls(server->wrapped);
        rb_completion_queue_pluck(server->queue, NULL,
                                  gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
      }
      grpc_server_destroy(server->wrapped);
      grpc_rb_completion_queue_destroy(server->queue);
      server->wrapped = NULL;
      server->queue = NULL;
    }
  }
}
コード例 #3
0
ファイル: rb_server.c プロジェクト: royalharsh/grpc
/* call-seq:
   server.request_call

   Requests notification of a new call on a server. */
static VALUE grpc_rb_server_request_call(VALUE self) {
  grpc_rb_server *s = NULL;
  grpc_call *call = NULL;
  grpc_event ev;
  grpc_call_error err;
  request_call_stack st;
  VALUE result;
  void *tag = (void*)&st;
  grpc_completion_queue *call_queue = grpc_completion_queue_create(NULL);
  gpr_timespec deadline;

  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
  if (s->wrapped == NULL) {
    rb_raise(rb_eRuntimeError, "destroyed!");
    return Qnil;
  }
  grpc_request_call_stack_init(&st);
  /* call grpc_server_request_call, then wait for it to complete using
   * pluck_event */
  err = grpc_server_request_call(
      s->wrapped, &call, &st.details, &st.md_ary,
      call_queue, s->queue, tag);
  if (err != GRPC_CALL_OK) {
    grpc_request_call_stack_cleanup(&st);
    rb_raise(grpc_rb_eCallError,
             "grpc_server_request_call failed: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
    return Qnil;
  }

  ev = rb_completion_queue_pluck(s->queue, tag,
                                 gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  if (!ev.success) {
    grpc_request_call_stack_cleanup(&st);
    rb_raise(grpc_rb_eCallError, "request_call completion failed");
    return Qnil;
  }



  /* build the NewServerRpc struct result */
  deadline = gpr_convert_clock_type(st.details.deadline, GPR_CLOCK_REALTIME);
  result = rb_struct_new(
      grpc_rb_sNewServerRpc, grpc_rb_slice_to_ruby_string(st.details.method),
      grpc_rb_slice_to_ruby_string(st.details.host),
      rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
                 INT2NUM(deadline.tv_nsec / 1000)),
      grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call, call_queue),
      NULL);
  grpc_request_call_stack_cleanup(&st);
  return result;
}
コード例 #4
0
ファイル: rb_call.c プロジェクト: makdharma/grpc
/* call-seq:
   ops = {
     GRPC::Core::CallOps::SEND_INITIAL_METADATA => <op_value>,
     GRPC::Core::CallOps::SEND_MESSAGE => <op_value>,
     ...
   }
   tag = Object.new
   timeout = 10
   call.start_batch(tag, timeout, ops)

   Start a batch of operations defined in the array ops; when complete, post a
   completion of type 'tag' to the completion queue bound to the call.

   Also waits for the batch to complete, until timeout is reached.
   The order of ops specified in the batch has no significance.
   Only one operation of each type can be active at once in any given
   batch */
static VALUE grpc_rb_call_run_batch(VALUE self, VALUE ops_hash) {
  run_batch_stack *st = NULL;
  grpc_rb_call *call = NULL;
  grpc_event ev;
  grpc_call_error err;
  VALUE result = Qnil;
  VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
  unsigned write_flag = 0;
  void *tag = (void *)&st;

  if (RTYPEDDATA_DATA(self) == NULL) {
    rb_raise(grpc_rb_eCallError, "Cannot run batch on closed call");
    return Qnil;
  }
  TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);

  /* Validate the ops args, adding them to a ruby array */
  if (TYPE(ops_hash) != T_HASH) {
    rb_raise(rb_eTypeError, "call#run_batch: ops hash should be a hash");
    return Qnil;
  }
  if (rb_write_flag != Qnil) {
    write_flag = NUM2UINT(rb_write_flag);
  }
  st = gpr_malloc(sizeof(run_batch_stack));
  grpc_run_batch_stack_init(st, write_flag);
  grpc_run_batch_stack_fill_ops(st, ops_hash);

  /* call grpc_call_start_batch, then wait for it to complete using
   * pluck_event */
  err = grpc_call_start_batch(call->wrapped, st->ops, st->op_num, tag, NULL);
  if (err != GRPC_CALL_OK) {
    grpc_run_batch_stack_cleanup(st);
    gpr_free(st);
    rb_raise(grpc_rb_eCallError,
             "grpc_call_start_batch failed with %s (code=%d)",
             grpc_call_error_detail_of(err), err);
    return Qnil;
  }
  ev = rb_completion_queue_pluck(call->queue, tag,
                                 gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  if (!ev.success) {
    rb_raise(grpc_rb_eCallError, "call#run_batch failed somehow");
  }
  /* Build and return the BatchResult struct result,
     if there is an error, it's reflected in the status */
  result = grpc_run_batch_stack_build_result(st);
  grpc_run_batch_stack_cleanup(st);
  gpr_free(st);
  return result;
}