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; ...@@ -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) { ...@@ -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() { ...@@ -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() { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
...@@ -456,17 +454,19 @@ module GRPC ...@@ -456,17 +454,19 @@ module GRPC
# SingleReqView limits access to an ActiveCall's methods for use in server # SingleReqView limits access to an ActiveCall's methods for use in server
# handlers that receive just one request. # handlers that receive just one request.
SingleReqView = view_class(:cancelled, :deadline, :metadata, 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 # MultiReqView limits access to an ActiveCall's methods for use in
# server client_streamer handlers. # server client_streamer handlers.
MultiReqView = view_class(:cancelled, :deadline, :each_queued_msg, 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 # Operation limits access to an ActiveCall's methods for use as
# 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 ...@@ -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 ...@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment