mirror of https://github.com/grpc/grpc.git
Merge pull request #9986 from apolcyn/fix_connectivity
ruby add background channel state poller to handle disconnected transportspull/10269/head
commit
b0f3f55f8f
24 changed files with 1429 additions and 74 deletions
@ -0,0 +1,18 @@ |
|||||||
|
This directory contains some grpc-ruby end to end tests. |
||||||
|
|
||||||
|
Each test here involves two files: a "driver" and a "client". For example, |
||||||
|
the "channel_closing" test involves channel_closing_driver.rb |
||||||
|
and channel_closing_client.rb. |
||||||
|
|
||||||
|
Typically, the "driver" will start up a simple "echo" server, and then |
||||||
|
spawn a client. It gives the client the address of the "echo" server as |
||||||
|
well as an address to listen on for control rpcs. Depending on the test, the |
||||||
|
client usually starts up a "ClientControl" grpc server for the driver to |
||||||
|
interact with (the driver can tell the client process to do strange things at |
||||||
|
different times, depending on the test). |
||||||
|
|
||||||
|
So far these tests are mostly useful for testing process-shutdown related |
||||||
|
situations, since the client's run in separate processes. |
||||||
|
|
||||||
|
These tests are invoked through the "tools/run_tests/run_tests.py" script (the |
||||||
|
Rakefile doesn't start these). |
@ -0,0 +1,84 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
# Calls '#close' on a Channel when "shutdown" called. This tries to |
||||||
|
# trigger a hang or crash bug by closing a channel actively being watched |
||||||
|
class ChannelClosingClientController < ClientControl::ClientController::Service |
||||||
|
def initialize(ch) |
||||||
|
@ch = ch |
||||||
|
end |
||||||
|
|
||||||
|
def shutdown(_, _) |
||||||
|
@ch.close |
||||||
|
ClientControl::Void.new |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def main |
||||||
|
client_control_port = '' |
||||||
|
server_port = '' |
||||||
|
OptionParser.new do |opts| |
||||||
|
opts.on('--client_control_port=P', String) do |p| |
||||||
|
client_control_port = p |
||||||
|
end |
||||||
|
opts.on('--server_port=P', String) do |p| |
||||||
|
server_port = p |
||||||
|
end |
||||||
|
end.parse! |
||||||
|
|
||||||
|
ch = GRPC::Core::Channel.new("localhost:#{server_port}", {}, |
||||||
|
:this_channel_is_insecure) |
||||||
|
|
||||||
|
srv = GRPC::RpcServer.new |
||||||
|
thd = Thread.new do |
||||||
|
srv.add_http2_port("0.0.0.0:#{client_control_port}", :this_port_is_insecure) |
||||||
|
srv.handle(ChannelClosingClientController.new(ch)) |
||||||
|
srv.run |
||||||
|
end |
||||||
|
|
||||||
|
# this should break out with an exception once the channel is closed |
||||||
|
loop do |
||||||
|
begin |
||||||
|
state = ch.connectivity_state(true) |
||||||
|
ch.watch_connectivity_state(state, Time.now + 360) |
||||||
|
rescue RuntimeError => e |
||||||
|
STDERR.puts "(expected) error occurred: #{e.inspect}" |
||||||
|
break |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
srv.stop |
||||||
|
thd.join |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,67 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2016, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
# make sure that the client doesn't hang when channel is closed |
||||||
|
# explictly while it's used |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
def main |
||||||
|
STDERR.puts 'start server' |
||||||
|
server_runner = ServerRunner.new |
||||||
|
server_port = server_runner.run |
||||||
|
|
||||||
|
sleep 1 |
||||||
|
|
||||||
|
STDERR.puts 'start client' |
||||||
|
control_stub, client_pid = start_client('channel_closing_client.rb', |
||||||
|
server_port) |
||||||
|
|
||||||
|
sleep 3 |
||||||
|
|
||||||
|
begin |
||||||
|
Timeout.timeout(10) do |
||||||
|
control_stub.shutdown(ClientControl::Void.new) |
||||||
|
Process.wait(client_pid) |
||||||
|
end |
||||||
|
rescue Timeout::Error |
||||||
|
STDERR.puts "timeout wait for client pid #{client_pid}" |
||||||
|
Process.kill('SIGKILL', client_pid) |
||||||
|
Process.wait(client_pid) |
||||||
|
STDERR.puts 'killed client child' |
||||||
|
raise 'Timed out waiting for client process. It likely hangs when a ' \ |
||||||
|
'channel is closed while connectivity is watched' |
||||||
|
end |
||||||
|
|
||||||
|
server_runner.stop |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,54 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
def main |
||||||
|
server_port = '' |
||||||
|
OptionParser.new do |opts| |
||||||
|
opts.on('--client_control_port=P', String) do |
||||||
|
STDERR.puts 'client_control_port ignored' |
||||||
|
end |
||||||
|
opts.on('--server_port=P', String) do |p| |
||||||
|
server_port = p |
||||||
|
end |
||||||
|
end.parse! |
||||||
|
|
||||||
|
ch = GRPC::Core::Channel.new("localhost:#{server_port}", {}, |
||||||
|
:this_channel_is_insecure) |
||||||
|
|
||||||
|
loop do |
||||||
|
state = ch.connectivity_state |
||||||
|
ch.watch_connectivity_state(state, Time.now + 360) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,64 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2016, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
# make sure that the client doesn't hang when process ended abruptly |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
def main |
||||||
|
STDERR.puts 'start server' |
||||||
|
server_runner = ServerRunner.new |
||||||
|
server_port = server_runner.run |
||||||
|
|
||||||
|
sleep 1 |
||||||
|
|
||||||
|
STDERR.puts 'start client' |
||||||
|
_, client_pid = start_client('channel_state_client.rb', server_port) |
||||||
|
|
||||||
|
sleep 3 |
||||||
|
|
||||||
|
Process.kill('SIGTERM', client_pid) |
||||||
|
|
||||||
|
begin |
||||||
|
Timeout.timeout(10) { Process.wait(client_pid) } |
||||||
|
rescue Timeout::Error |
||||||
|
STDERR.puts "timeout wait for client pid #{client_pid}" |
||||||
|
Process.kill('SIGKILL', client_pid) |
||||||
|
Process.wait(client_pid) |
||||||
|
STDERR.puts 'killed client child' |
||||||
|
raise 'Timed out waiting for client process. ' \ |
||||||
|
'It likely hangs when ended abruptly' |
||||||
|
end |
||||||
|
|
||||||
|
server_runner.stop |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,109 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||||
|
protos_lib_dir = File.join(this_dir, 'lib') |
||||||
|
grpc_lib_dir = File.join(File.dirname(this_dir), 'lib') |
||||||
|
$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir) |
||||||
|
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir) |
||||||
|
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||||
|
|
||||||
|
require 'grpc' |
||||||
|
require 'echo_services_pb' |
||||||
|
require 'client_control_services_pb' |
||||||
|
require 'socket' |
||||||
|
require 'optparse' |
||||||
|
require 'thread' |
||||||
|
require 'timeout' |
||||||
|
require 'English' # see https://github.com/bbatsov/rubocop/issues/1747 |
||||||
|
|
||||||
|
# GreeterServer is simple server that implements the Helloworld Greeter server. |
||||||
|
class EchoServerImpl < Echo::EchoServer::Service |
||||||
|
# say_hello implements the SayHello rpc method. |
||||||
|
def echo(echo_req, _) |
||||||
|
Echo::EchoReply.new(response: echo_req.request) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# ServerRunner starts an "echo server" that test clients can make calls to |
||||||
|
class ServerRunner |
||||||
|
def initialize |
||||||
|
end |
||||||
|
|
||||||
|
def run |
||||||
|
@srv = GRPC::RpcServer.new |
||||||
|
port = @srv.add_http2_port('0.0.0.0:0', :this_port_is_insecure) |
||||||
|
@srv.handle(EchoServerImpl) |
||||||
|
|
||||||
|
@thd = Thread.new do |
||||||
|
@srv.run |
||||||
|
end |
||||||
|
@srv.wait_till_running |
||||||
|
port |
||||||
|
end |
||||||
|
|
||||||
|
def stop |
||||||
|
@srv.stop |
||||||
|
@thd.join |
||||||
|
fail 'server not stopped' unless @srv.stopped? |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def start_client(client_main, server_port) |
||||||
|
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||||
|
|
||||||
|
tmp_server = TCPServer.new(0) |
||||||
|
client_control_port = tmp_server.local_address.ip_port |
||||||
|
tmp_server.close |
||||||
|
|
||||||
|
client_path = File.join(this_dir, client_main) |
||||||
|
client_pid = Process.spawn(RbConfig.ruby, |
||||||
|
client_path, |
||||||
|
"--client_control_port=#{client_control_port}", |
||||||
|
"--server_port=#{server_port}") |
||||||
|
sleep 1 |
||||||
|
control_stub = ClientControl::ClientController::Stub.new( |
||||||
|
"localhost:#{client_control_port}", :this_channel_is_insecure) |
||||||
|
[control_stub, client_pid] |
||||||
|
end |
||||||
|
|
||||||
|
def cleanup(control_stub, client_pid, server_runner) |
||||||
|
control_stub.shutdown(ClientControl::Void.new) |
||||||
|
Process.wait(client_pid) |
||||||
|
|
||||||
|
client_exit_code = $CHILD_STATUS |
||||||
|
|
||||||
|
if client_exit_code != 0 |
||||||
|
fail "term sig test failure: client exit code: #{client_exit_code}" |
||||||
|
end |
||||||
|
|
||||||
|
server_runner.stop |
||||||
|
end |
@ -0,0 +1,32 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
# Copyright 2016, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
grpc_tools_ruby_protoc -I protos --ruby_out=lib --grpc_out=lib protos/echo.proto protos/client_control.proto |
@ -0,0 +1,17 @@ |
|||||||
|
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||||
|
# source: client_control.proto |
||||||
|
|
||||||
|
require 'google/protobuf' |
||||||
|
|
||||||
|
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||||
|
add_message "client_control.DoEchoRpcRequest" do |
||||||
|
optional :request, :string, 1 |
||||||
|
end |
||||||
|
add_message "client_control.Void" do |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
module ClientControl |
||||||
|
DoEchoRpcRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("client_control.DoEchoRpcRequest").msgclass |
||||||
|
Void = Google::Protobuf::DescriptorPool.generated_pool.lookup("client_control.Void").msgclass |
||||||
|
end |
@ -0,0 +1,53 @@ |
|||||||
|
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||||
|
# Source: client_control.proto for package 'client_control' |
||||||
|
# Original file comments: |
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
# |
||||||
|
|
||||||
|
require 'grpc' |
||||||
|
require 'client_control_pb' |
||||||
|
|
||||||
|
module ClientControl |
||||||
|
module ClientController |
||||||
|
class Service |
||||||
|
|
||||||
|
include GRPC::GenericService |
||||||
|
|
||||||
|
self.marshal_class_method = :encode |
||||||
|
self.unmarshal_class_method = :decode |
||||||
|
self.service_name = 'client_control.ClientController' |
||||||
|
|
||||||
|
rpc :DoEchoRpc, DoEchoRpcRequest, Void |
||||||
|
rpc :Shutdown, Void, Void |
||||||
|
end |
||||||
|
|
||||||
|
Stub = Service.rpc_stub_class |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,18 @@ |
|||||||
|
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||||
|
# source: echo.proto |
||||||
|
|
||||||
|
require 'google/protobuf' |
||||||
|
|
||||||
|
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||||
|
add_message "echo.EchoRequest" do |
||||||
|
optional :request, :string, 1 |
||||||
|
end |
||||||
|
add_message "echo.EchoReply" do |
||||||
|
optional :response, :string, 1 |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
module Echo |
||||||
|
EchoRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("echo.EchoRequest").msgclass |
||||||
|
EchoReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("echo.EchoReply").msgclass |
||||||
|
end |
@ -0,0 +1,52 @@ |
|||||||
|
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||||
|
# Source: echo.proto for package 'echo' |
||||||
|
# Original file comments: |
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
# |
||||||
|
|
||||||
|
require 'grpc' |
||||||
|
require 'echo_pb' |
||||||
|
|
||||||
|
module Echo |
||||||
|
module EchoServer |
||||||
|
class Service |
||||||
|
|
||||||
|
include GRPC::GenericService |
||||||
|
|
||||||
|
self.marshal_class_method = :encode |
||||||
|
self.unmarshal_class_method = :decode |
||||||
|
self.service_name = 'echo.EchoServer' |
||||||
|
|
||||||
|
rpc :Echo, EchoRequest, EchoReply |
||||||
|
end |
||||||
|
|
||||||
|
Stub = Service.rpc_stub_class |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,43 @@ |
|||||||
|
// Copyright 2015, Google Inc. |
||||||
|
// All rights reserved. |
||||||
|
// |
||||||
|
// Redistribution and use in source and binary forms, with or without |
||||||
|
// modification, are permitted provided that the following conditions are |
||||||
|
// met: |
||||||
|
// |
||||||
|
// * Redistributions of source code must retain the above copyright |
||||||
|
// notice, this list of conditions and the following disclaimer. |
||||||
|
// * Redistributions in binary form must reproduce the above |
||||||
|
// copyright notice, this list of conditions and the following disclaimer |
||||||
|
// in the documentation and/or other materials provided with the |
||||||
|
// distribution. |
||||||
|
// * Neither the name of Google Inc. nor the names of its |
||||||
|
// contributors may be used to endorse or promote products derived from |
||||||
|
// this software without specific prior written permission. |
||||||
|
// |
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
syntax = "proto3"; |
||||||
|
|
||||||
|
package client_control; |
||||||
|
|
||||||
|
service ClientController { |
||||||
|
rpc DoEchoRpc (DoEchoRpcRequest) returns (Void) {} |
||||||
|
rpc Shutdown(Void) returns (Void) {} |
||||||
|
} |
||||||
|
|
||||||
|
message DoEchoRpcRequest { |
||||||
|
string request = 1; |
||||||
|
} |
||||||
|
|
||||||
|
message Void{} |
@ -0,0 +1,46 @@ |
|||||||
|
// Copyright 2015, Google Inc. |
||||||
|
// All rights reserved. |
||||||
|
// |
||||||
|
// Redistribution and use in source and binary forms, with or without |
||||||
|
// modification, are permitted provided that the following conditions are |
||||||
|
// met: |
||||||
|
// |
||||||
|
// * Redistributions of source code must retain the above copyright |
||||||
|
// notice, this list of conditions and the following disclaimer. |
||||||
|
// * Redistributions in binary form must reproduce the above |
||||||
|
// copyright notice, this list of conditions and the following disclaimer |
||||||
|
// in the documentation and/or other materials provided with the |
||||||
|
// distribution. |
||||||
|
// * Neither the name of Google Inc. nor the names of its |
||||||
|
// contributors may be used to endorse or promote products derived from |
||||||
|
// this software without specific prior written permission. |
||||||
|
// |
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
syntax = "proto3"; |
||||||
|
|
||||||
|
package echo; |
||||||
|
|
||||||
|
service EchoServer { |
||||||
|
rpc Echo (EchoRequest) returns (EchoReply) {} |
||||||
|
} |
||||||
|
|
||||||
|
// The request message containing the user's name. |
||||||
|
message EchoRequest { |
||||||
|
string request = 1; |
||||||
|
} |
||||||
|
|
||||||
|
// The response message containing the greetings |
||||||
|
message EchoReply { |
||||||
|
string response = 1; |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
# Test client. Sends RPC's as normal but process also has signal handlers |
||||||
|
class SigHandlingClientController < ClientControl::ClientController::Service |
||||||
|
def initialize(srv, stub) |
||||||
|
@srv = srv |
||||||
|
@stub = stub |
||||||
|
end |
||||||
|
|
||||||
|
def do_echo_rpc(req, _) |
||||||
|
response = @stub.echo(Echo::EchoRequest.new(request: req.request)) |
||||||
|
fail 'bad response' unless response.response == req.request |
||||||
|
ClientControl::Void.new |
||||||
|
end |
||||||
|
|
||||||
|
def shutdown(_, _) |
||||||
|
Thread.new do |
||||||
|
# TODO(apolcyn) There is a race between stopping the |
||||||
|
# server and the "shutdown" rpc completing, |
||||||
|
# See if stop method on server can end active RPC cleanly, to |
||||||
|
# avoid this sleep. |
||||||
|
sleep 3 |
||||||
|
@srv.stop |
||||||
|
end |
||||||
|
ClientControl::Void.new |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def main |
||||||
|
client_control_port = '' |
||||||
|
server_port = '' |
||||||
|
OptionParser.new do |opts| |
||||||
|
opts.on('--client_control_port=P', String) do |p| |
||||||
|
client_control_port = p |
||||||
|
end |
||||||
|
opts.on('--server_port=P', String) do |p| |
||||||
|
server_port = p |
||||||
|
end |
||||||
|
end.parse! |
||||||
|
|
||||||
|
Signal.trap('TERM') do |
||||||
|
STDERR.puts 'SIGTERM received' |
||||||
|
end |
||||||
|
|
||||||
|
Signal.trap('INT') do |
||||||
|
STDERR.puts 'SIGINT received' |
||||||
|
end |
||||||
|
|
||||||
|
srv = GRPC::RpcServer.new |
||||||
|
srv.add_http2_port("0.0.0.0:#{client_control_port}", |
||||||
|
:this_port_is_insecure) |
||||||
|
stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", |
||||||
|
:this_channel_is_insecure) |
||||||
|
srv.handle(SigHandlingClientController.new(srv, stub)) |
||||||
|
srv.run |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,61 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2016, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
# smoke test for a grpc-using app that receives and |
||||||
|
# handles process-ending signals |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
def main |
||||||
|
STDERR.puts 'start server' |
||||||
|
server_runner = ServerRunner.new |
||||||
|
server_port = server_runner.run |
||||||
|
|
||||||
|
sleep 1 |
||||||
|
|
||||||
|
STDERR.puts 'start client' |
||||||
|
control_stub, client_pid = start_client('sig_handling_client.rb', server_port) |
||||||
|
|
||||||
|
sleep 1 |
||||||
|
|
||||||
|
count = 0 |
||||||
|
while count < 5 |
||||||
|
control_stub.do_echo_rpc( |
||||||
|
ClientControl::DoEchoRpcRequest.new(request: 'hello')) |
||||||
|
Process.kill('SIGTERM', client_pid) |
||||||
|
Process.kill('SIGINT', client_pid) |
||||||
|
count += 1 |
||||||
|
end |
||||||
|
|
||||||
|
cleanup(control_stub, client_pid, server_runner) |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,70 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
# Start polling the channel state in both the main thread |
||||||
|
# and a child thread. Try to get the driver to send process-ending |
||||||
|
# interrupt while both a child thread and the main thread are in the |
||||||
|
# middle of a blocking connectivity_state call. |
||||||
|
def main |
||||||
|
server_port = '' |
||||||
|
OptionParser.new do |opts| |
||||||
|
opts.on('--client_control_port=P', String) do |
||||||
|
STDERR.puts 'client_control_port not used' |
||||||
|
end |
||||||
|
opts.on('--server_port=P', String) do |p| |
||||||
|
server_port = p |
||||||
|
end |
||||||
|
end.parse! |
||||||
|
|
||||||
|
thd = Thread.new do |
||||||
|
child_thread_channel = GRPC::Core::Channel.new("localhost:#{server_port}", |
||||||
|
{}, |
||||||
|
:this_channel_is_insecure) |
||||||
|
loop do |
||||||
|
state = child_thread_channel.connectivity_state(false) |
||||||
|
child_thread_channel.watch_connectivity_state(state, Time.now + 360) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
main_channel = GRPC::Core::Channel.new("localhost:#{server_port}", |
||||||
|
{}, |
||||||
|
:this_channel_is_insecure) |
||||||
|
loop do |
||||||
|
state = main_channel.connectivity_state(false) |
||||||
|
main_channel.watch_connectivity_state(state, Time.now + 360) |
||||||
|
end |
||||||
|
|
||||||
|
thd.join |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,69 @@ |
|||||||
|
#!/usr/bin/env ruby |
||||||
|
|
||||||
|
# Copyright 2016, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
# abruptly end a process that has active calls to |
||||||
|
# Channel.watch_connectivity_state |
||||||
|
|
||||||
|
require_relative './end2end_common' |
||||||
|
|
||||||
|
def main |
||||||
|
STDERR.puts 'start server' |
||||||
|
server_runner = ServerRunner.new |
||||||
|
server_port = server_runner.run |
||||||
|
|
||||||
|
sleep 1 |
||||||
|
|
||||||
|
STDERR.puts 'start client' |
||||||
|
_, client_pid = start_client('sig_int_during_channel_watch_client.rb', |
||||||
|
server_port) |
||||||
|
|
||||||
|
# give time for the client to get into the middle |
||||||
|
# of a channel state watch call |
||||||
|
sleep 1 |
||||||
|
Process.kill('SIGINT', client_pid) |
||||||
|
|
||||||
|
begin |
||||||
|
Timeout.timeout(10) do |
||||||
|
Process.wait(client_pid) |
||||||
|
end |
||||||
|
rescue Timeout::Error |
||||||
|
STDERR.puts "timeout wait for client pid #{client_pid}" |
||||||
|
Process.kill('SIGKILL', client_pid) |
||||||
|
Process.wait(client_pid) |
||||||
|
STDERR.puts 'killed client child' |
||||||
|
raise 'Timed out waiting for client process. It likely hangs when a ' \ |
||||||
|
'SIGINT is sent while there is an active connectivity_state call' |
||||||
|
end |
||||||
|
|
||||||
|
server_runner.stop |
||||||
|
end |
||||||
|
|
||||||
|
main |
@ -0,0 +1,141 @@ |
|||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
require 'grpc' |
||||||
|
|
||||||
|
# A test message |
||||||
|
class EchoMsg |
||||||
|
def self.marshal(_o) |
||||||
|
'' |
||||||
|
end |
||||||
|
|
||||||
|
def self.unmarshal(_o) |
||||||
|
EchoMsg.new |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# A test service with an echo implementation. |
||||||
|
class EchoService |
||||||
|
include GRPC::GenericService |
||||||
|
rpc :an_rpc, EchoMsg, EchoMsg |
||||||
|
attr_reader :received_md |
||||||
|
|
||||||
|
def initialize(**kw) |
||||||
|
@trailing_metadata = kw |
||||||
|
@received_md = [] |
||||||
|
end |
||||||
|
|
||||||
|
def an_rpc(req, call) |
||||||
|
GRPC.logger.info('echo service received a request') |
||||||
|
call.output_metadata.update(@trailing_metadata) |
||||||
|
@received_md << call.metadata unless call.metadata.nil? |
||||||
|
req |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
EchoStub = EchoService.rpc_stub_class |
||||||
|
|
||||||
|
def start_server(port = 0) |
||||||
|
@srv = GRPC::RpcServer.new |
||||||
|
server_port = @srv.add_http2_port("localhost:#{port}", :this_port_is_insecure) |
||||||
|
@srv.handle(EchoService) |
||||||
|
@server_thd = Thread.new { @srv.run } |
||||||
|
@srv.wait_till_running |
||||||
|
server_port |
||||||
|
end |
||||||
|
|
||||||
|
def stop_server |
||||||
|
expect(@srv.stopped?).to be(false) |
||||||
|
@srv.stop |
||||||
|
@server_thd.join |
||||||
|
expect(@srv.stopped?).to be(true) |
||||||
|
end |
||||||
|
|
||||||
|
describe 'channel connection behavior' do |
||||||
|
it 'the client channel handles temporary loss of a transport' do |
||||||
|
port = start_server |
||||||
|
stub = EchoStub.new("localhost:#{port}", :this_channel_is_insecure) |
||||||
|
req = EchoMsg.new |
||||||
|
expect(stub.an_rpc(req)).to be_a(EchoMsg) |
||||||
|
stop_server |
||||||
|
sleep 1 |
||||||
|
# TODO(apolcyn) grabbing the same port might fail, is this stable enough? |
||||||
|
start_server(port) |
||||||
|
expect(stub.an_rpc(req)).to be_a(EchoMsg) |
||||||
|
stop_server |
||||||
|
end |
||||||
|
|
||||||
|
it 'observably connects and reconnects to transient server' \ |
||||||
|
' when using the channel state API' do |
||||||
|
port = start_server |
||||||
|
ch = GRPC::Core::Channel.new("localhost:#{port}", {}, |
||||||
|
:this_channel_is_insecure) |
||||||
|
|
||||||
|
expect(ch.connectivity_state).to be(GRPC::Core::ConnectivityStates::IDLE) |
||||||
|
|
||||||
|
state = ch.connectivity_state(true) |
||||||
|
|
||||||
|
count = 0 |
||||||
|
while count < 20 && state != GRPC::Core::ConnectivityStates::READY |
||||||
|
ch.watch_connectivity_state(state, Time.now + 60) |
||||||
|
state = ch.connectivity_state(true) |
||||||
|
count += 1 |
||||||
|
end |
||||||
|
|
||||||
|
expect(state).to be(GRPC::Core::ConnectivityStates::READY) |
||||||
|
|
||||||
|
stop_server |
||||||
|
|
||||||
|
state = ch.connectivity_state |
||||||
|
|
||||||
|
count = 0 |
||||||
|
while count < 20 && state == GRPC::Core::ConnectivityStates::READY |
||||||
|
ch.watch_connectivity_state(state, Time.now + 60) |
||||||
|
state = ch.connectivity_state |
||||||
|
count += 1 |
||||||
|
end |
||||||
|
|
||||||
|
expect(state).to_not be(GRPC::Core::ConnectivityStates::READY) |
||||||
|
|
||||||
|
start_server(port) |
||||||
|
|
||||||
|
state = ch.connectivity_state(true) |
||||||
|
|
||||||
|
count = 0 |
||||||
|
while count < 20 && state != GRPC::Core::ConnectivityStates::READY |
||||||
|
ch.watch_connectivity_state(state, Time.now + 60) |
||||||
|
state = ch.connectivity_state(true) |
||||||
|
count += 1 |
||||||
|
end |
||||||
|
|
||||||
|
expect(state).to be(GRPC::Core::ConnectivityStates::READY) |
||||||
|
|
||||||
|
stop_server |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,41 @@ |
|||||||
|
#!/bin/bash |
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
set -ex |
||||||
|
|
||||||
|
# change to grpc repo root |
||||||
|
cd $(dirname $0)/../../.. |
||||||
|
|
||||||
|
EXIT_CODE=0 |
||||||
|
ruby src/ruby/end2end/sig_handling_driver.rb || EXIT_CODE=1 |
||||||
|
ruby src/ruby/end2end/channel_state_driver.rb || EXIT_CODE=1 |
||||||
|
ruby src/ruby/end2end/channel_closing_driver.rb || EXIT_CODE=1 |
||||||
|
ruby src/ruby/end2end/sig_int_during_channel_watch_driver.rb || EXIT_CODE=1 |
||||||
|
exit $EXIT_CODE |
Loading…
Reference in new issue