|
|
|
@ -30,6 +30,22 @@ |
|
|
|
|
require 'forwardable' |
|
|
|
|
require 'grpc/generic/bidi_call' |
|
|
|
|
|
|
|
|
|
class Struct |
|
|
|
|
# BatchResult is the struct returned by calls to call#start_batch. |
|
|
|
|
class BatchResult |
|
|
|
|
# check_status returns the status, raising an error if the status |
|
|
|
|
# is non-nil and not OK. |
|
|
|
|
def check_status |
|
|
|
|
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) |
|
|
|
|
end |
|
|
|
|
status |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# GRPC contains the General RPC module. |
|
|
|
|
module GRPC |
|
|
|
|
# The ActiveCall class provides simple methods for sending marshallable |
|
|
|
@ -38,7 +54,9 @@ module GRPC |
|
|
|
|
include Core::StatusCodes |
|
|
|
|
include Core::TimeConsts |
|
|
|
|
include Core::CallOps |
|
|
|
|
extend Forwardable |
|
|
|
|
attr_reader(:deadline) |
|
|
|
|
def_delegators :@call, :cancel, :metadata |
|
|
|
|
|
|
|
|
|
# client_invoke begins a client invocation. |
|
|
|
|
# |
|
|
|
@ -101,50 +119,6 @@ module GRPC |
|
|
|
|
@metadata_tag = metadata_tag |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# Obtains the status of the call. |
|
|
|
|
# |
|
|
|
|
# this value is nil until the call completes |
|
|
|
|
# @return this call's status |
|
|
|
|
def status |
|
|
|
|
@call.status |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# Obtains the metadata of the call. |
|
|
|
|
# |
|
|
|
|
# At the start of the call this will be nil. During the call this gets |
|
|
|
|
# some values as soon as the other end of the connection acknowledges the |
|
|
|
|
# request. |
|
|
|
|
# |
|
|
|
|
# @return this calls's metadata |
|
|
|
|
def metadata |
|
|
|
|
@call.metadata |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# Cancels the call. |
|
|
|
|
# |
|
|
|
|
# Cancels the call. The call does not return any result, but once this it |
|
|
|
|
# has been called, the call should eventually terminate. Due to potential |
|
|
|
|
# races between the execution of the cancel and the in-flight request, the |
|
|
|
|
# result of the call after calling #cancel is indeterminate: |
|
|
|
|
# |
|
|
|
|
# - the call may terminate with a BadStatus exception, with code=CANCELLED |
|
|
|
|
# - the call may terminate with OK Status, and return a response |
|
|
|
|
# - the call may terminate with a different BadStatus exception if that |
|
|
|
|
# was happening |
|
|
|
|
def cancel |
|
|
|
|
@call.cancel |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# indicates if the call is shutdown |
|
|
|
|
def shutdown |
|
|
|
|
@shutdown ||= false |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# indicates if the call is cancelled. |
|
|
|
|
def cancelled |
|
|
|
|
@cancelled ||= false |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# multi_req_view provides a restricted view of this ActiveCall for use |
|
|
|
|
# in a server client-streaming handler. |
|
|
|
|
def multi_req_view |
|
|
|
@ -176,9 +150,9 @@ module GRPC |
|
|
|
|
SEND_CLOSE_FROM_CLIENT => nil |
|
|
|
|
} |
|
|
|
|
ops[RECV_STATUS_ON_CLIENT] = nil if assert_finished |
|
|
|
|
@call.run_batch(@cq, self, INFINITE_FUTURE, ops) |
|
|
|
|
batch_result = @call.run_batch(@cq, self, INFINITE_FUTURE, ops) |
|
|
|
|
return unless assert_finished |
|
|
|
|
@call.status |
|
|
|
|
batch_result.check_status |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# finished waits until a client call is completed. |
|
|
|
@ -192,17 +166,12 @@ module GRPC |
|
|
|
|
elsif !batch_result.metadata.nil? |
|
|
|
|
@call.metadata.merge!(batch_result.metadata) |
|
|
|
|
end |
|
|
|
|
if batch_result.status.code != Core::StatusCodes::OK |
|
|
|
|
fail BadStatus.new(batch_result.status.code, |
|
|
|
|
batch_result.status.details) |
|
|
|
|
end |
|
|
|
|
batch_result |
|
|
|
|
batch_result.check_status |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# remote_send sends a request to the remote endpoint. |
|
|
|
|
# |
|
|
|
|
# It blocks until the remote endpoint acknowledges by sending a |
|
|
|
|
# WRITE_ACCEPTED. req can be marshalled already. |
|
|
|
|
# It blocks until the remote endpoint accepts the message. |
|
|
|
|
# |
|
|
|
|
# @param req [Object, String] the object to send or it's marshal form. |
|
|
|
|
# @param marshalled [false, true] indicates if the object is already |
|
|
|
@ -332,6 +301,9 @@ module GRPC |
|
|
|
|
response = remote_read |
|
|
|
|
finished unless response.is_a? Struct::Status |
|
|
|
|
response |
|
|
|
|
rescue GRPC::Core::CallError => e |
|
|
|
|
finished # checks for Cancelled |
|
|
|
|
raise e |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# client_streamer sends a stream of requests to a GRPC server, and |
|
|
|
@ -355,6 +327,9 @@ module GRPC |
|
|
|
|
response = remote_read |
|
|
|
|
finished unless response.is_a? Struct::Status |
|
|
|
|
response |
|
|
|
|
rescue GRPC::Core::CallError => e |
|
|
|
|
finished # checks for Cancelled |
|
|
|
|
raise e |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# server_streamer sends one request to the GRPC server, which yields a |
|
|
|
@ -381,6 +356,9 @@ module GRPC |
|
|
|
|
replies = enum_for(:each_remote_read_then_finish) |
|
|
|
|
return replies unless block_given? |
|
|
|
|
replies.each { |r| yield r } |
|
|
|
|
rescue GRPC::Core::CallError => e |
|
|
|
|
finished # checks for Cancelled |
|
|
|
|
raise e |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# bidi_streamer sends a stream of requests to the GRPC server, and yields |
|
|
|
@ -416,6 +394,9 @@ module GRPC |
|
|
|
|
start_call(**kw) unless @started |
|
|
|
|
bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline) |
|
|
|
|
bd.run_on_client(requests, &blk) |
|
|
|
|
rescue GRPC::Core::CallError => e |
|
|
|
|
finished # checks for Cancelled |
|
|
|
|
raise e |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
# run_server_bidi orchestrates a BiDi stream processing on a server. |
|
|
|
@ -436,9 +417,10 @@ module GRPC |
|
|
|
|
|
|
|
|
|
private |
|
|
|
|
|
|
|
|
|
# Starts the call if not already started |
|
|
|
|
def start_call(**kw) |
|
|
|
|
tags = ActiveCall.client_invoke(@call, @cq, @deadline, **kw) |
|
|
|
|
@finished_tag, @read_metadata_tag = tags |
|
|
|
|
return if @started |
|
|
|
|
@metadata_tag = ActiveCall.client_invoke(@call, @cq, @deadline, **kw) |
|
|
|
|
@started = true |
|
|
|
|
end |
|
|
|
|
|
|
|
|
@ -466,6 +448,6 @@ module GRPC |
|
|
|
|
# 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) |
|
|
|
|
:metadata, :status, :start_call) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|