Skip to content
Snippets Groups Projects
Commit e69f088c authored by murgatroid99's avatar murgatroid99
Browse files

Split incoming initial and trailing metadata in Ruby calls

parent 2cbe7542
No related branches found
No related tags found
No related merge requests found
......@@ -71,6 +71,10 @@ static ID id_credentials;
* received by the call and subsequently saved on it. */
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
* received by the call and subsequently saved on it. */
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);
}
/*
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:
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, "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, "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_set_write_flag,
1);
......@@ -916,6 +948,7 @@ void Init_grpc_call() {
/* Ids used to support call attributes */
id_metadata = rb_intern("metadata");
id_trailing_metadata = rb_intern("trailing_metadata");
id_status = rb_intern("status");
id_write_flag = rb_intern("write_flag");
......
......@@ -43,8 +43,7 @@ class Struct
GRPC.logger.debug("Failing with status #{status}")
# raise BadStatus, propagating the metadata if present.
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, with_sym_keys)
fail GRPC::BadStatus.new(status.code, status.details, md)
end
status
end
......@@ -61,7 +60,7 @@ module GRPC
extend Forwardable
attr_reader(:deadline)
def_delegators :@call, :cancel, :metadata, :write_flag, :write_flag=,
:peer, :peer_cert
:peer, :peer_cert, :trailing_metadata
# client_invoke begins a client invocation.
#
......@@ -158,6 +157,9 @@ module GRPC
ops[RECV_STATUS_ON_CLIENT] = nil if assert_finished
batch_result = @call.run_batch(ops)
return unless assert_finished
unless batch_result.status.nil?
@call.trailing_metadata = batch_result.status.metadata
end
@call.status = batch_result.status
op_is_done
batch_result.check_status
......@@ -169,11 +171,7 @@ module GRPC
def finished
batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
unless batch_result.status.nil?
if @call.metadata.nil?
@call.metadata = batch_result.status.metadata
else
@call.metadata.merge!(batch_result.status.metadata)
end
@call.trailing_metadata = batch_result.status.metadata
end
@call.status = batch_result.status
op_is_done
......@@ -456,17 +454,19 @@ module GRPC
# SingleReqView limits access to an ActiveCall's methods for use in server
# handlers that receive just one request.
SingleReqView = view_class(:cancelled, :deadline, :metadata,
:output_metadata, :peer, :peer_cert)
:output_metadata, :peer, :peer_cert,
:trailing_metadata)
# MultiReqView limits access to an ActiveCall's methods for use in
# server client_streamer handlers.
MultiReqView = view_class(:cancelled, :deadline, :each_queued_msg,
:each_remote_read, :metadata, :output_metadata)
:each_remote_read, :metadata, :output_metadata,
:trailing_metadata)
# Operation limits access to an ActiveCall's methods for use as
# a Operation on the client.
Operation = view_class(:cancel, :cancelled, :deadline, :execute,
:metadata, :status, :start_call, :wait, :write_flag,
:write_flag=)
:write_flag=, :trailing_metadata)
end
end
......@@ -95,7 +95,7 @@ class FailingService
def initialize(_default_var = 'ignored')
@details = 'app error'
@code = 101
@md = { failed_method: 'an_rpc' }
@md = { 'failed_method' => 'an_rpc' }
end
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' })
expect(op.metadata).to be nil
expect(op.execute).to be_a(EchoMsg)
expect(op.metadata).to eq(wanted_trailers)
expect(op.trailing_metadata).to eq(wanted_trailers)
@srv.stop
t.join
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment