aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ruby/lib
diff options
context:
space:
mode:
authorGravatar Tim Emiola <temiola@google.com>2015-04-17 13:29:59 -0700
committerGravatar Tim Emiola <temiola@google.com>2015-04-17 13:29:59 -0700
commit8661a43f784e6c2689466355dd5a0bdab4567346 (patch)
tree3309ba4ea13f370e23b60facb753d2cd1903eb24 /src/ruby/lib
parent1c5faea6734f00dd8327a8dbca939b797fd5bdfb (diff)
Propagate metadata in BadStatus
- allow BadStatus to contain metadata that's populated by keyword args - on servers, convert raised BadStatus metadata to trailers - on clients, convert trailers to BadStatus metadata when raising BadStatus
Diffstat (limited to 'src/ruby/lib')
-rw-r--r--src/ruby/lib/grpc/generic/active_call.rb13
-rw-r--r--src/ruby/lib/grpc/generic/rpc_desc.rb10
2 files changed, 15 insertions, 8 deletions
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index 8d63de4145..274372e4d5 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -39,7 +39,10 @@ class Struct
return nil if status.nil?
fail GRPC::Cancelled if status.code == GRPC::Core::StatusCodes::CANCELLED
if status.code != GRPC::Core::StatusCodes::OK
- fail GRPC::BadStatus.new(status.code, status.details)
+ # 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)
end
status
end
@@ -192,9 +195,13 @@ module GRPC
# @param details [String] details
# @param assert_finished [true, false] when true(default), waits for
# FINISHED.
- def send_status(code = OK, details = '', assert_finished = false)
+ #
+ # == Keyword Arguments ==
+ # any keyword arguments are treated as metadata to be sent to the server
+ # if a keyword value is a list, multiple metadata for it's key are sent
+ def send_status(code = OK, details = '', assert_finished = false, **kw)
ops = {
- SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details)
+ SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details, kw)
}
ops[RECV_CLOSE_ON_SERVER] = nil if assert_finished
@call.run_batch(@cq, self, INFINITE_FUTURE, ops)
diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb
index 3e48b8e51d..22b80d8938 100644
--- a/src/ruby/lib/grpc/generic/rpc_desc.rb
+++ b/src/ruby/lib/grpc/generic/rpc_desc.rb
@@ -82,10 +82,10 @@ module GRPC
end
send_status(active_call, OK, 'OK')
rescue BadStatus => e
- # this is raised by handlers that want GRPC to send an application
- # error code and detail message.
+ # this is raised by handlers that want GRPC to send an application error
+ # code and detail message and some additional app-specific metadata.
logger.debug("app err: #{active_call}, status:#{e.code}:#{e.details}")
- send_status(active_call, e.code, e.details)
+ send_status(active_call, e.code, e.details, **e.metadata)
rescue Core::CallError => e
# This is raised by GRPC internals but should rarely, if ever happen.
# Log it, but don't notify the other endpoint..
@@ -135,9 +135,9 @@ module GRPC
"##{mth.name}: bad arg count; got:#{mth.arity}, want:#{want}, #{msg}"
end
- def send_status(active_client, code, details)
+ def send_status(active_client, code, details, **kw)
details = 'Not sure why' if details.nil?
- active_client.send_status(code, details, code == OK)
+ active_client.send_status(code, details, code == OK, **kw)
rescue StandardError => e
logger.warn("Could not send status #{code}:#{details}")
logger.warn(e)