示例#1
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;
}
示例#2
0
文件: rb_call.c 项目: Saviio/grpc
/* call-seq:
   cq = CompletionQueue.new
   ops = {
     GRPC::Core::CallOps::SEND_INITIAL_METADATA => <op_value>,
     GRPC::Core::CallOps::SEND_MESSAGE => <op_value>,
     ...
   }
   tag = Object.new
   timeout = 10
   call.start_batch(cqueue, 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 cqueue, VALUE tag,
                                    VALUE timeout, VALUE ops_hash) {
  run_batch_stack st;
  grpc_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;
  TypedData_Get_Struct(self, grpc_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);
  }
  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, st.ops, st.op_num, ROBJECT(tag), NULL);
  if (err != GRPC_CALL_OK) {
    grpc_run_batch_stack_cleanup(&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 = grpc_rb_completion_queue_pluck_event(cqueue, tag, timeout);
  if (ev.type == GRPC_QUEUE_TIMEOUT) {
    grpc_run_batch_stack_cleanup(&st);
    rb_raise(grpc_rb_eOutOfTime, "grpc_call_start_batch timed out");
    return Qnil;
  }

  /* 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);
  return result;
}
示例#3
0
/* call-seq:
   cq = CompletionQueue.new
   ops = {
     GRPC::Core::CallOps::SEND_INITIAL_METADATA => <op_value>,
     GRPC::Core::CallOps::SEND_MESSAGE => <op_value>,
     ...
   }
   tag = Object.new
   timeout = 10
   call.start_batch(cqueue, 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 cqueue, VALUE tag,
                                    VALUE timeout, VALUE ops_hash) {
  run_batch_stack st;
  grpc_call *call = NULL;
  grpc_event *ev = NULL;
  grpc_call_error err;
  VALUE result = Qnil;
  Data_Get_Struct(self, grpc_call, 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;
  }
  grpc_run_batch_stack_init(&st);
  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, st.ops, st.op_num, ROBJECT(tag));
  if (err != GRPC_CALL_OK) {
    grpc_run_batch_stack_cleanup(&st);
    rb_raise(grpc_rb_eCallError,
             "grpc_call_start_batch failed with %s (code=%d)",
             grpc_call_error_detail_of(err), err);
    return;
  }
  ev = grpc_rb_completion_queue_pluck_event(cqueue, tag, timeout);
  if (ev == NULL) {
    grpc_run_batch_stack_cleanup(&st);
    rb_raise(grpc_rb_eOutOfTime, "grpc_call_start_batch timed out");
    return;
  }
  if (ev->data.op_complete != GRPC_OP_OK) {
    grpc_run_batch_stack_cleanup(&st);
    rb_raise(grpc_rb_eCallError, "start_batch completion failed, (code=%d)",
             ev->data.op_complete);
    return;
  }

  /* Build and return the BatchResult struct result */
  result = grpc_run_batch_stack_build_result(&st);
  grpc_run_batch_stack_cleanup(&st);
  return result;
}