commit
51b48176ca
187 changed files with 8833 additions and 3367 deletions
@ -0,0 +1,77 @@ |
||||
Connection Backoff Interop Test Descriptions |
||||
=============================================== |
||||
|
||||
This test is to verify the client is reconnecting the server with correct |
||||
backoffs as specified in |
||||
[the spec](http://github.com/grpc/grpc/blob/master/doc/connection-backoff.md). |
||||
The test server has a port (control_port) running a rpc service for controlling |
||||
the server and another port (retry_port) to close any incoming tcp connections. |
||||
The test has the following flow: |
||||
|
||||
1. The server starts listening on control_port. |
||||
2. The client calls Start rpc on server control_port. |
||||
3. The server starts listening on retry_port. |
||||
4. The client connects to server retry_port and retries with backoff for 540s, |
||||
which translates to about 13 retries. |
||||
5. The client calls Stop rpc on server control port. |
||||
6. The client checks the response to see whether the server thinks the backoffs |
||||
are conforming the spec or do its own check on the backoffs in the response. |
||||
|
||||
Client and server use |
||||
[test.proto](https://github.com/grpc/grpc/blob/master/test/proto/test.proto). |
||||
Each language should implement its own client. The C++ server is shared among |
||||
languages. |
||||
|
||||
Client |
||||
------ |
||||
|
||||
Clients should accept these arguments: |
||||
* --server_control_port=PORT |
||||
* The server port to connect to for rpc. For example, "8080" |
||||
* --server_retry_port=PORT |
||||
* The server port to connect to for testing backoffs. For example, "8081" |
||||
|
||||
The client must connect to the control port without TLS. The client should |
||||
either assert on the server returned backoff status or check the returned |
||||
backoffs on its own. |
||||
|
||||
Procedure of client: |
||||
|
||||
1. Calls Start on server control port with a large deadline or no deadline, |
||||
waits for its finish and checks it succeeded. |
||||
2. Initiates a channel connection to server retry port, which should perform |
||||
reconnections with proper backoffs. A convienent way to achieve this is to |
||||
call Start with a deadline of 540s. The rpc should fail with deadline exceeded. |
||||
3. Calls Stop on server control port and checks it succeeded. |
||||
4. Checks the response to see whether the server thinks the backoffs passed the |
||||
test. |
||||
5. Optionally, the client can do its own check on the returned backoffs. |
||||
|
||||
|
||||
Server |
||||
------ |
||||
|
||||
A C++ server can be used for the test. Other languages do NOT need to implement |
||||
a server. To minimize the network delay, the server binary should run on the |
||||
same machine or on a nearby machine (in terms of network distance) with the |
||||
client binary. |
||||
|
||||
A server implements the ReconnectService to its state. It also opens a |
||||
tcp server on the retry_port, which just shuts down all incoming tcp |
||||
connections to simulate connection failures. The server will keep a record of |
||||
all the reconnection timestamps and return the connection backoffs in the |
||||
response in milliseconds. The server also checks the backoffs to see whether |
||||
they conform the spec and returns whether the client passes the test. |
||||
|
||||
If the server receives a Start call when another client is being tested, it |
||||
finishes the call when the other client is done. If some other host connects |
||||
to the server retry_port when a client is being tested, the server will log an |
||||
error but likely would think the client fails the test. |
||||
|
||||
The server accepts these arguments: |
||||
|
||||
* --control_port=PORT |
||||
* The port to listen on for control rpcs. For example, "8080" |
||||
* --retry_port=PORT |
||||
* The tcp server port. For example, "8081" |
||||
|
@ -1,57 +0,0 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
/* GRPC <--> CENSUS context interface */ |
||||
|
||||
#ifndef CENSUS_GRPC_CONTEXT_H |
||||
#define CENSUS_GRPC_CONTEXT_H |
||||
|
||||
#include <grpc/census.h> |
||||
#include "src/core/surface/call.h" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Set census context for the call; Must be called before first call to
|
||||
grpc_call_start_batch(). */ |
||||
void grpc_census_call_set_context(grpc_call *call, census_context *context); |
||||
|
||||
/* Retrieve the calls current census context. */ |
||||
census_context *grpc_census_call_get_context(grpc_call *call); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* CENSUS_GRPC_CONTEXT_H */ |
@ -0,0 +1,191 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#include "src/core/surface/channel.h" |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
|
||||
#include "src/core/channel/client_channel.h" |
||||
#include "src/core/iomgr/alarm.h" |
||||
#include "src/core/surface/completion_queue.h" |
||||
|
||||
grpc_connectivity_state grpc_channel_check_connectivity_state( |
||||
grpc_channel *channel, int try_to_connect) { |
||||
/* forward through to the underlying client channel */ |
||||
grpc_channel_element *client_channel_elem = |
||||
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); |
||||
if (client_channel_elem->filter != &grpc_client_channel_filter) { |
||||
gpr_log(GPR_ERROR, |
||||
"grpc_channel_check_connectivity_state called on something that is " |
||||
"not a client channel, but '%s'", |
||||
client_channel_elem->filter->name); |
||||
return GRPC_CHANNEL_FATAL_FAILURE; |
||||
} |
||||
return grpc_client_channel_check_connectivity_state(client_channel_elem, |
||||
try_to_connect); |
||||
} |
||||
|
||||
typedef enum { |
||||
WAITING, |
||||
CALLING_BACK, |
||||
CALLING_BACK_AND_FINISHED, |
||||
CALLED_BACK |
||||
} callback_phase; |
||||
|
||||
typedef struct { |
||||
gpr_mu mu; |
||||
callback_phase phase; |
||||
int success; |
||||
grpc_iomgr_closure on_complete; |
||||
grpc_alarm alarm; |
||||
grpc_connectivity_state state; |
||||
grpc_connectivity_state *optional_new_state; |
||||
grpc_completion_queue *cq; |
||||
grpc_cq_completion completion_storage; |
||||
grpc_channel *channel; |
||||
void *tag; |
||||
} state_watcher; |
||||
|
||||
static void delete_state_watcher(state_watcher *w) { |
||||
grpc_channel_element *client_channel_elem = |
||||
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(w->channel)); |
||||
grpc_client_channel_del_interested_party(client_channel_elem, grpc_cq_pollset(w->cq)); |
||||
GRPC_CHANNEL_INTERNAL_UNREF(w->channel, "watch_connectivity"); |
||||
gpr_mu_destroy(&w->mu); |
||||
gpr_free(w); |
||||
} |
||||
|
||||
static void finished_completion(void *pw, grpc_cq_completion *ignored) { |
||||
int delete = 0; |
||||
state_watcher *w = pw; |
||||
gpr_mu_lock(&w->mu); |
||||
switch (w->phase) { |
||||
case WAITING: |
||||
case CALLED_BACK: |
||||
gpr_log(GPR_ERROR, "should never reach here"); |
||||
abort(); |
||||
break; |
||||
case CALLING_BACK: |
||||
w->phase = CALLED_BACK; |
||||
break; |
||||
case CALLING_BACK_AND_FINISHED: |
||||
delete = 1; |
||||
break; |
||||
} |
||||
gpr_mu_unlock(&w->mu); |
||||
|
||||
if (delete) { |
||||
delete_state_watcher(w); |
||||
} |
||||
} |
||||
|
||||
static void partly_done(state_watcher *w, int due_to_completion) { |
||||
int delete = 0; |
||||
|
||||
if (due_to_completion) { |
||||
gpr_mu_lock(&w->mu); |
||||
w->success = 1; |
||||
gpr_mu_unlock(&w->mu); |
||||
grpc_alarm_cancel(&w->alarm); |
||||
} |
||||
|
||||
gpr_mu_lock(&w->mu); |
||||
switch (w->phase) { |
||||
case WAITING: |
||||
w->phase = CALLING_BACK; |
||||
if (w->optional_new_state) { |
||||
*w->optional_new_state = w->state; |
||||
} |
||||
grpc_cq_end_op(w->cq, w->tag, w->success, finished_completion, w, |
||||
&w->completion_storage); |
||||
break; |
||||
case CALLING_BACK: |
||||
w->phase = CALLING_BACK_AND_FINISHED; |
||||
break; |
||||
case CALLING_BACK_AND_FINISHED: |
||||
gpr_log(GPR_ERROR, "should never reach here"); |
||||
abort(); |
||||
break; |
||||
case CALLED_BACK: |
||||
delete = 1; |
||||
break; |
||||
} |
||||
gpr_mu_unlock(&w->mu); |
||||
|
||||
if (delete) { |
||||
delete_state_watcher(w); |
||||
} |
||||
} |
||||
|
||||
static void watch_complete(void *pw, int success) { partly_done(pw, 1); } |
||||
|
||||
static void timeout_complete(void *pw, int success) { partly_done(pw, 0); } |
||||
|
||||
void grpc_channel_watch_connectivity_state( |
||||
grpc_channel *channel, grpc_connectivity_state last_observed_state, |
||||
grpc_connectivity_state *optional_new_state, gpr_timespec deadline, |
||||
grpc_completion_queue *cq, void *tag) { |
||||
grpc_channel_element *client_channel_elem = |
||||
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); |
||||
state_watcher *w = gpr_malloc(sizeof(*w)); |
||||
|
||||
grpc_cq_begin_op(cq); |
||||
|
||||
gpr_mu_init(&w->mu); |
||||
grpc_iomgr_closure_init(&w->on_complete, watch_complete, w); |
||||
w->phase = WAITING; |
||||
w->state = last_observed_state; |
||||
w->success = 0; |
||||
w->optional_new_state = optional_new_state; |
||||
w->cq = cq; |
||||
w->tag = tag; |
||||
w->channel = channel; |
||||
|
||||
grpc_alarm_init( |
||||
&w->alarm, gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
|
||||
timeout_complete, w, gpr_now(GPR_CLOCK_MONOTONIC)); |
||||
|
||||
if (client_channel_elem->filter != &grpc_client_channel_filter) { |
||||
gpr_log(GPR_ERROR, |
||||
"grpc_channel_watch_connectivity_state called on something that is " |
||||
"not a client channel, but '%s'", |
||||
client_channel_elem->filter->name); |
||||
grpc_iomgr_add_delayed_callback(&w->on_complete, 1); |
||||
} else { |
||||
GRPC_CHANNEL_INTERNAL_REF(channel, "watch_connectivity"); |
||||
grpc_client_channel_add_interested_party(client_channel_elem, grpc_cq_pollset(cq)); |
||||
grpc_client_channel_watch_connectivity_state(client_channel_elem, &w->state, |
||||
&w->on_complete); |
||||
} |
||||
} |
Binary file not shown.
@ -0,0 +1,5 @@ |
||||
Contents |
||||
-------- |
||||
|
||||
- Grpc.public.snk: |
||||
Public key to verify strong name of gRPC assemblies. |
@ -0,0 +1,22 @@ |
||||
{ |
||||
"tags": { |
||||
"allowUnknownTags": true |
||||
}, |
||||
"source": { |
||||
"include": [ "index.js", "src" ], |
||||
"includePattern": ".+\\.js(doc)?$", |
||||
"excludePattern": "(^|\\/|\\\\)_" |
||||
}, |
||||
"opts": { |
||||
"package": "package.json", |
||||
"readme": "README.md" |
||||
}, |
||||
"plugins": [], |
||||
"templates": { |
||||
"cleverLinks": false, |
||||
"monospaceLinks": false, |
||||
"default": { |
||||
"outputSourceFiles": true |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue