Ejemplo n.º 1
0
/*
  call-seq:
     call.invoke(completion_queue, tag, flags=nil)

   Invoke the RPC. Starts sending metadata and request headers on the wire.
   flags is a bit-field combination of the write flags defined above.
   REQUIRES: Can be called at most once per call.
             Can only be called on the client.
   Produces a GRPC_INVOKE_ACCEPTED event on completion. */
static VALUE grpc_rb_call_invoke(int argc, VALUE *argv, VALUE self) {
  VALUE cqueue = Qnil;
  VALUE metadata_read_tag = Qnil;
  VALUE finished_tag = Qnil;
  VALUE flags = Qnil;
  grpc_call *call = NULL;
  grpc_completion_queue *cq = NULL;
  grpc_call_error err;

  /* "31" == 3 mandatory args, 1 (flags) is optional */
  rb_scan_args(argc, argv, "31", &cqueue, &metadata_read_tag, &finished_tag,
               &flags);
  if (NIL_P(flags)) {
    flags = UINT2NUM(0); /* Default to no flags */
  }
  cq = grpc_rb_get_wrapped_completion_queue(cqueue);
  Data_Get_Struct(self, grpc_call, call);
  err = grpc_call_invoke_old(call, cq, ROBJECT(metadata_read_tag),
                             ROBJECT(finished_tag), NUM2UINT(flags));
  if (err != GRPC_CALL_OK) {
    rb_raise(rb_eCallError, "invoke failed: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }

  /* Add the completion queue as an instance attribute, prevents it from being
   * GCed until this call object is GCed */
  rb_ivar_set(self, id_cq, cqueue);

  return Qnil;
}
Ejemplo n.º 2
0
/* call-seq:
   cq = CompletionQueue.new
   tag = Object.new
   timeout = 10
   server.request_call(cqueue, tag, timeout)

   Requests notification of a new call on a server. */
static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
                                         VALUE tag_new, VALUE timeout) {
  grpc_rb_server *s = NULL;
  grpc_call *call = NULL;
  grpc_event *ev = NULL;
  grpc_call_error err;
  request_call_stack st;
  VALUE result;
  Data_Get_Struct(self, grpc_rb_server, s);
  if (s->wrapped == NULL) {
    rb_raise(rb_eRuntimeError, "closed!");
    return Qnil;
  } else {
    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,
        grpc_rb_get_wrapped_completion_queue(cqueue),
        ROBJECT(tag_new));
    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 = grpc_rb_completion_queue_pluck_event(cqueue, tag_new, timeout);
    if (ev == NULL) {
      grpc_request_call_stack_cleanup(&st);
      return Qnil;
    }
    if (ev->data.op_complete != GRPC_OP_OK) {
      grpc_request_call_stack_cleanup(&st);
      grpc_event_finish(ev);
      rb_raise(grpc_rb_eCallError, "request_call completion failed: (code=%d)",
               ev->data.op_complete);
      return Qnil;
    }

    /* build the NewServerRpc struct result */
    result = rb_struct_new(
        grpc_rb_sNewServerRpc,
        rb_str_new2(st.details.method),
        rb_str_new2(st.details.host),
        rb_funcall(rb_cTime, id_at, 2, INT2NUM(st.details.deadline.tv_sec),
                   INT2NUM(st.details.deadline.tv_nsec)),
        grpc_rb_md_ary_to_h(&st.md_ary),
        grpc_rb_wrap_call(call),
        NULL);
    grpc_event_finish(ev);
    grpc_request_call_stack_cleanup(&st);
    return result;
  }
  return Qnil;
}
Ejemplo n.º 3
0
/* grpc_rb_call_add_metadata_hash_cb is the hash iteration callback used by
   grpc_rb_call_add_metadata.
*/
int grpc_rb_call_add_metadata_hash_cb(VALUE key, VALUE val, VALUE call_obj) {
  grpc_call *call = NULL;
  grpc_metadata *md = NULL;
  VALUE md_obj = Qnil;
  VALUE md_obj_args[2];
  VALUE flags = rb_ivar_get(call_obj, id_flags);
  grpc_call_error err;
  int array_length;
  int i;

  /* Construct a metadata object from key and value and add it */
  Data_Get_Struct(call_obj, grpc_call, call);
  md_obj_args[0] = key;

  if (TYPE(val) == T_ARRAY) {
    /* If the value is an array, add each value in the array separately */
    array_length = RARRAY_LEN(val);
    for (i = 0; i < array_length; i++) {
      md_obj_args[1] = rb_ary_entry(val, i);
      md_obj = rb_class_new_instance(2, md_obj_args, rb_cMetadata);
      md = grpc_rb_get_wrapped_metadata(md_obj);
      err = grpc_call_add_metadata_old(call, md, NUM2UINT(flags));
      if (err != GRPC_CALL_OK) {
        rb_raise(rb_eCallError, "add metadata failed: %s (code=%d)",
                 grpc_call_error_detail_of(err), err);
        return ST_STOP;
      }
    }
  } else {
    md_obj_args[1] = val;
    md_obj = rb_class_new_instance(2, md_obj_args, rb_cMetadata);
    md = grpc_rb_get_wrapped_metadata(md_obj);
    err = grpc_call_add_metadata_old(call, md, NUM2UINT(flags));
    if (err != GRPC_CALL_OK) {
      rb_raise(rb_eCallError, "add metadata failed: %s (code=%d)",
               grpc_call_error_detail_of(err), err);
      return ST_STOP;
    }
  }

  return ST_CONTINUE;
}
Ejemplo n.º 4
0
/* call-seq:
   cq = CompletionQueue.new
   tag = Object.new
   timeout = 10
   server.request_call(cqueue, tag, timeout)

   Requests notification of a new call on a server. */
static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
        VALUE tag_new, VALUE timeout) {
    grpc_rb_server *s = NULL;
    grpc_call *call = NULL;
    grpc_event ev;
    grpc_call_error err;
    request_call_stack st;
    VALUE result;
    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;
    } else {
        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,
                  grpc_rb_get_wrapped_completion_queue(cqueue),
                  grpc_rb_get_wrapped_completion_queue(cqueue),
                  ROBJECT(tag_new));
        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 = grpc_rb_completion_queue_pluck_event(cqueue, tag_new, timeout);
        if (ev.type == GRPC_QUEUE_TIMEOUT) {
            grpc_request_call_stack_cleanup(&st);
            return Qnil;
        }
        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, rb_str_new2(st.details.method),
                     rb_str_new2(st.details.host),
                     rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
                                INT2NUM(deadline.tv_nsec)),
                     grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call), NULL);
        grpc_request_call_stack_cleanup(&st);
        return result;
    }
    return Qnil;
}
Ejemplo n.º 5
0
/* No more messages to send.
   REQUIRES: No other writes are pending on the call. */
static VALUE grpc_rb_call_writes_done(VALUE self, VALUE tag) {
  grpc_call *call = NULL;
  grpc_call_error err;
  Data_Get_Struct(self, grpc_call, call);
  err = grpc_call_writes_done_old(call, ROBJECT(tag));
  if (err != GRPC_CALL_OK) {
    rb_raise(rb_eCallError, "writes done: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }

  return Qnil;
}
Ejemplo n.º 6
0
/* Called by clients to cancel an RPC on the server.
   Can be called multiple times, from any thread. */
static VALUE grpc_rb_call_cancel(VALUE self) {
  grpc_call *call = NULL;
  grpc_call_error err;
  TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
  err = grpc_call_cancel(call);
  if (err != GRPC_CALL_OK) {
    rb_raise(grpc_rb_eCallError, "cancel failed: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }

  return Qnil;
}
Ejemplo n.º 7
0
/* 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;
}
Ejemplo n.º 8
0
/* 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;
}
Ejemplo n.º 9
0
/* Queue a status for writing.

   call-seq:
      tag = Object.new
      call.write_status(200, "OK", tag)

   REQUIRES: No other writes are pending on the call. It is only safe to
   start the next write after the corresponding write_accepted event
   is received.
   GRPC_INVOKE_ACCEPTED must have been received by the application
   prior to calling this.
   Only callable on the server.
   Produces a GRPC_FINISHED event when the status is sent and the stream is
   fully closed */
static VALUE grpc_rb_call_start_write_status(VALUE self, VALUE code,
                                             VALUE status, VALUE tag) {
  grpc_call *call = NULL;
  grpc_call_error err;
  Data_Get_Struct(self, grpc_call, call);
  err = grpc_call_start_write_status_old(call, NUM2UINT(code),
                                         StringValueCStr(status), ROBJECT(tag));
  if (err != GRPC_CALL_OK) {
    rb_raise(rb_eCallError, "start write status: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }

  return Qnil;
}
Ejemplo n.º 10
0
/*
  call-seq:
  call.set_credentials call_credentials

  Sets credentials on a call */
static VALUE grpc_rb_call_set_credentials(VALUE self, VALUE credentials) {
  grpc_call *call = NULL;
  grpc_call_credentials *creds;
  grpc_call_error err;
  TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
  creds = grpc_rb_get_wrapped_call_credentials(credentials);
  err = grpc_call_set_credentials(call, creds);
  if (err != GRPC_CALL_OK) {
    rb_raise(grpc_rb_eCallError,
             "grpc_call_set_credentials failed with %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }
  return Qnil;
}
Ejemplo n.º 11
0
/* call-seq:
     call.server_accept(completion_queue, finished_tag)

   Accept an incoming RPC, binding a completion queue to it.
   To be called before sending or receiving messages.

   REQUIRES: Can be called at most once per call.
             Can only be called on the server.
   Produces a GRPC_FINISHED event with finished_tag when the call has been
       completed (there may be other events for the call pending at this
       time) */
static VALUE grpc_rb_call_server_accept(VALUE self, VALUE cqueue,
                                        VALUE finished_tag) {
  grpc_call *call = NULL;
  grpc_completion_queue *cq = grpc_rb_get_wrapped_completion_queue(cqueue);
  grpc_call_error err;
  Data_Get_Struct(self, grpc_call, call);
  err = grpc_call_server_accept_old(call, cq, ROBJECT(finished_tag));
  if (err != GRPC_CALL_OK) {
    rb_raise(rb_eCallError, "server_accept failed: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }

  /* Add the completion queue as an instance attribute, prevents it from being
   * GCed until this call object is GCed */
  rb_ivar_set(self, id_cq, cqueue);
  return Qnil;
}
Ejemplo n.º 12
0
/* Called by clients to cancel an RPC on the server.
   Can be called multiple times, from any thread. */
static VALUE grpc_rb_call_cancel(VALUE self) {
  grpc_rb_call *call = NULL;
  grpc_call_error err;
  if (RTYPEDDATA_DATA(self) == NULL) {
    // This call has been closed
    return Qnil;
  }

  TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
  err = grpc_call_cancel(call->wrapped, NULL);
  if (err != GRPC_CALL_OK) {
    rb_raise(grpc_rb_eCallError, "cancel failed: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }

  return Qnil;
}
Ejemplo n.º 13
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;
  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;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
/* call-seq:
     call.server_end_initial_metadata(flag)

   Only to be called on servers, before sending messages.
   flags is a bit-field combination of the write flags defined above.

   REQUIRES: Can be called at most once per call.
             Can only be called on the server, must be called after
             grpc_call_server_accept
   Produces no events */
static VALUE grpc_rb_call_server_end_initial_metadata(int argc, VALUE *argv,
                                                      VALUE self) {
  VALUE flags = Qnil;
  grpc_call *call = NULL;
  grpc_call_error err;

  /* "01" == 1 (flags) is optional */
  rb_scan_args(argc, argv, "01", &flags);
  if (NIL_P(flags)) {
    flags = UINT2NUM(0); /* Default to no flags */
  }
  Data_Get_Struct(self, grpc_call, call);
  err = grpc_call_server_end_initial_metadata_old(call, NUM2UINT(flags));
  if (err != GRPC_CALL_OK) {
    rb_raise(rb_eCallError, "end_initial_metadata failed: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }
  return Qnil;
}
Ejemplo n.º 16
0
/*
  call-seq:
  call.set_credentials call_credentials

  Sets credentials on a call */
static VALUE grpc_rb_call_set_credentials(VALUE self, VALUE credentials) {
  grpc_rb_call *call = NULL;
  grpc_call_credentials *creds;
  grpc_call_error err;
  if (RTYPEDDATA_DATA(self) == NULL) {
    rb_raise(grpc_rb_eCallError, "Cannot set credentials of closed call");
    return Qnil;
  }
  TypedData_Get_Struct(self, grpc_rb_call, &grpc_call_data_type, call);
  creds = grpc_rb_get_wrapped_call_credentials(credentials);
  err = grpc_call_set_credentials(call->wrapped, creds);
  if (err != GRPC_CALL_OK) {
    rb_raise(grpc_rb_eCallError,
             "grpc_call_set_credentials failed with %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }
  /* We need the credentials to be alive for as long as the call is alive,
     but we don't care about destruction order. */
  rb_ivar_set(self, id_credentials, credentials);
  return Qnil;
}
Ejemplo n.º 17
0
/*
  call-seq:
     call.start_write(byte_buffer, tag, flags=nil)

   Queue a byte buffer for writing.
   flags is a bit-field combination of the write flags defined above.
   A write with byte_buffer null is allowed, and will not send any bytes on the
   wire. If this is performed without GRPC_WRITE_BUFFER_HINT flag it provides
   a mechanism to flush any previously buffered writes to outgoing flow control.
   REQUIRES: No other writes are pending on the call. It is only safe to
             start the next write after the corresponding write_accepted event
             is received.
             GRPC_INVOKE_ACCEPTED must have been received by the application
             prior to calling this on the client. On the server,
             grpc_call_accept must have been called successfully.
   Produces a GRPC_WRITE_ACCEPTED event. */
static VALUE grpc_rb_call_start_write(int argc, VALUE *argv, VALUE self) {
  VALUE byte_buffer = Qnil;
  VALUE tag = Qnil;
  VALUE flags = Qnil;
  grpc_call *call = NULL;
  grpc_byte_buffer *bfr = NULL;
  grpc_call_error err;

  /* "21" == 2 mandatory args, 1 (flags) is optional */
  rb_scan_args(argc, argv, "21", &byte_buffer, &tag, &flags);
  if (NIL_P(flags)) {
    flags = UINT2NUM(0); /* Default to no flags */
  }
  bfr = grpc_rb_get_wrapped_byte_buffer(byte_buffer);
  Data_Get_Struct(self, grpc_call, call);
  err = grpc_call_start_write_old(call, bfr, ROBJECT(tag), NUM2UINT(flags));
  if (err != GRPC_CALL_OK) {
    rb_raise(rb_eCallError, "start write failed: %s (code=%d)",
             grpc_call_error_detail_of(err), err);
  }

  return Qnil;
}