Merge pull request #7274 from murgatroid99/ruby_api_review_changes

Split incoming initial and trailing metadata in Ruby calls
pull/7242/head
kpayson64 9 years ago committed by GitHub
commit c1bfe124ab
  1. 33
      src/ruby/ext/grpc/rb_call.c
  2. 16
      src/ruby/lib/grpc/generic/active_call.rb
  3. 4
      src/ruby/spec/generic/rpc_server_spec.rb

@ -71,6 +71,10 @@ static ID id_credentials;
* received by the call and subsequently saved on it. */ * received by the call and subsequently saved on it. */
static ID id_metadata; static ID id_metadata;
/* id_trailing_metadata is the name of the attribute used to access the trailing
* metadata hash received by the call and subsequently saved on it. */
static ID id_trailing_metadata;
/* id_status is name of the attribute used to access the status object /* id_status is name of the attribute used to access the status object
* received by the call and subsequently saved on it. */ * received by the call and subsequently saved on it. */
static ID id_status; static ID id_status;
@ -296,6 +300,30 @@ static VALUE grpc_rb_call_set_metadata(VALUE self, VALUE metadata) {
return rb_ivar_set(self, id_metadata, metadata); return rb_ivar_set(self, id_metadata, metadata);
} }
/*
call-seq:
trailing_metadata = call.trailing_metadata
Gets the trailing metadata object saved on the call */
static VALUE grpc_rb_call_get_trailing_metadata(VALUE self) {
return rb_ivar_get(self, id_trailing_metadata);
}
/*
call-seq:
call.trailing_metadata = trailing_metadata
Saves the trailing metadata hash on the call. */
static VALUE grpc_rb_call_set_trailing_metadata(VALUE self, VALUE metadata) {
if (!NIL_P(metadata) && TYPE(metadata) != T_HASH) {
rb_raise(rb_eTypeError, "bad metadata: got:<%s> want: <Hash>",
rb_obj_classname(metadata));
return Qnil;
}
return rb_ivar_set(self, id_trailing_metadata, metadata);
}
/* /*
call-seq: call-seq:
write_flag = call.write_flag write_flag = call.write_flag
@ -908,6 +936,10 @@ void Init_grpc_call() {
rb_define_method(grpc_rb_cCall, "status=", grpc_rb_call_set_status, 1); rb_define_method(grpc_rb_cCall, "status=", grpc_rb_call_set_status, 1);
rb_define_method(grpc_rb_cCall, "metadata", grpc_rb_call_get_metadata, 0); rb_define_method(grpc_rb_cCall, "metadata", grpc_rb_call_get_metadata, 0);
rb_define_method(grpc_rb_cCall, "metadata=", grpc_rb_call_set_metadata, 1); rb_define_method(grpc_rb_cCall, "metadata=", grpc_rb_call_set_metadata, 1);
rb_define_method(grpc_rb_cCall, "trailing_metadata",
grpc_rb_call_get_trailing_metadata, 0);
rb_define_method(grpc_rb_cCall, "trailing_metadata=",
grpc_rb_call_set_trailing_metadata, 1);
rb_define_method(grpc_rb_cCall, "write_flag", grpc_rb_call_get_write_flag, 0); rb_define_method(grpc_rb_cCall, "write_flag", grpc_rb_call_get_write_flag, 0);
rb_define_method(grpc_rb_cCall, "write_flag=", grpc_rb_call_set_write_flag, rb_define_method(grpc_rb_cCall, "write_flag=", grpc_rb_call_set_write_flag,
1); 1);
@ -916,6 +948,7 @@ void Init_grpc_call() {
/* Ids used to support call attributes */ /* Ids used to support call attributes */
id_metadata = rb_intern("metadata"); id_metadata = rb_intern("metadata");
id_trailing_metadata = rb_intern("trailing_metadata");
id_status = rb_intern("status"); id_status = rb_intern("status");
id_write_flag = rb_intern("write_flag"); id_write_flag = rb_intern("write_flag");

@ -43,8 +43,7 @@ class Struct
GRPC.logger.debug("Failing with status #{status}") GRPC.logger.debug("Failing with status #{status}")
# raise BadStatus, propagating the metadata if present. # raise BadStatus, propagating the metadata if present.
md = status.metadata md = status.metadata
with_sym_keys = Hash[md.each_pair.collect { |x, y| [x.to_sym, y] }] fail GRPC::BadStatus.new(status.code, status.details, md)
fail GRPC::BadStatus.new(status.code, status.details, with_sym_keys)
end end
status status
end end
@ -61,7 +60,7 @@ module GRPC
extend Forwardable extend Forwardable
attr_reader(:deadline) attr_reader(:deadline)
def_delegators :@call, :cancel, :metadata, :write_flag, :write_flag=, def_delegators :@call, :cancel, :metadata, :write_flag, :write_flag=,
:peer, :peer_cert :peer, :peer_cert, :trailing_metadata
# client_invoke begins a client invocation. # client_invoke begins a client invocation.
# #
@ -158,6 +157,9 @@ module GRPC
ops[RECV_STATUS_ON_CLIENT] = nil if assert_finished ops[RECV_STATUS_ON_CLIENT] = nil if assert_finished
batch_result = @call.run_batch(ops) batch_result = @call.run_batch(ops)
return unless assert_finished return unless assert_finished
unless batch_result.status.nil?
@call.trailing_metadata = batch_result.status.metadata
end
@call.status = batch_result.status @call.status = batch_result.status
op_is_done op_is_done
batch_result.check_status batch_result.check_status
@ -169,11 +171,7 @@ module GRPC
def finished def finished
batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil) batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
unless batch_result.status.nil? unless batch_result.status.nil?
if @call.metadata.nil? @call.trailing_metadata = batch_result.status.metadata
@call.metadata = batch_result.status.metadata
else
@call.metadata.merge!(batch_result.status.metadata)
end
end end
@call.status = batch_result.status @call.status = batch_result.status
op_is_done op_is_done
@ -467,6 +465,6 @@ module GRPC
# a Operation on the client. # a Operation on the client.
Operation = view_class(:cancel, :cancelled?, :deadline, :execute, Operation = view_class(:cancel, :cancelled?, :deadline, :execute,
:metadata, :status, :start_call, :wait, :write_flag, :metadata, :status, :start_call, :wait, :write_flag,
:write_flag=) :write_flag=, :trailing_metadata)
end end
end end

@ -95,7 +95,7 @@ class FailingService
def initialize(_default_var = 'ignored') def initialize(_default_var = 'ignored')
@details = 'app error' @details = 'app error'
@code = 101 @code = 101
@md = { failed_method: 'an_rpc' } @md = { 'failed_method' => 'an_rpc' }
end end
def an_rpc(_req, _call) def an_rpc(_req, _call)
@ -515,7 +515,7 @@ describe GRPC::RpcServer do
op = stub.an_rpc(req, return_op: true, metadata: { k1: 'v1', k2: 'v2' }) op = stub.an_rpc(req, return_op: true, metadata: { k1: 'v1', k2: 'v2' })
expect(op.metadata).to be nil expect(op.metadata).to be nil
expect(op.execute).to be_a(EchoMsg) expect(op.execute).to be_a(EchoMsg)
expect(op.metadata).to eq(wanted_trailers) expect(op.trailing_metadata).to eq(wanted_trailers)
@srv.stop @srv.stop
t.join t.join
end end

Loading…
Cancel
Save