Change the unit to ms, clean up

pull/10318/head
Yuchen Zeng 8 years ago
parent 3835d13788
commit ca6dab39d6
  1. 16
      include/grpc/impl/codegen/grpc_types.h
  2. 193
      src/core/lib/channel/max_age_filter.c
  3. 34
      test/core/end2end/tests/max_connection_age.c
  4. 16
      test/core/end2end/tests/max_connection_idle.c

@ -164,14 +164,14 @@ typedef struct {
-1 means unlimited. */ -1 means unlimited. */
#define GRPC_ARG_MAX_SEND_MESSAGE_LENGTH "grpc.max_send_message_length" #define GRPC_ARG_MAX_SEND_MESSAGE_LENGTH "grpc.max_send_message_length"
/** Maximum time that a channel may have no outstanding rpcs. Int valued, /** Maximum time that a channel may have no outstanding rpcs. Int valued,
seconds. INT_MAX means unlimited. */ milliseconds. INT_MAX means unlimited. */
#define GRPC_ARG_MAX_CONNECTION_IDLE_S "grpc.max_connection_idle" #define GRPC_ARG_MAX_CONNECTION_IDLE_MS "grpc.max_connection_idle_ms"
/** Maximum time that a channel may exist. Int valued, seconds. INT_MAX means /** Maximum time that a channel may exist. Int valued, milliseconds. INT_MAX
unlimited. */ means unlimited. */
#define GRPC_ARG_MAX_CONNECTION_AGE_S "grpc.max_connection_age" #define GRPC_ARG_MAX_CONNECTION_AGE_MS "grpc.max_connection_age_ms"
/** Grace period after the chennel reaches its max age. Int valued, seconds. /** Grace period after the chennel reaches its max age. Int valued,
INT_MAX means unlimited. */ milliseconds. INT_MAX means unlimited. */
#define GRPC_ARG_MAX_CONNECTION_AGE_GRACE_S "grpc.max_connection_age_grace" #define GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS "grpc.max_connection_age_grace_ms"
/** Initial sequence number for http2 transports. Int valued. */ /** Initial sequence number for http2 transports. Int valued. */
#define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \ #define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
"grpc.http2.initial_sequence_number" "grpc.http2.initial_sequence_number"

@ -1,104 +1,109 @@
// /*
// Copyright 2017, Google Inc. *
// All rights reserved. * Copyright 2017, 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 * Redistribution and use in source and binary forms, with or without
// met: * 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 of source code must retain the above copyright
// * Redistributions in binary form must reproduce the above * notice, this list of conditions and the following disclaimer.
// copyright notice, this list of conditions and the following disclaimer * * Redistributions in binary form must reproduce the above
// in the documentation and/or other materials provided with the * copyright notice, this list of conditions and the following disclaimer
// distribution. * in the documentation and/or other materials provided with the
// * Neither the name of Google Inc. nor the names of its * distribution.
// contributors may be used to endorse or promote products derived from * * Neither the name of Google Inc. nor the names of its
// this software without specific prior written permission. * 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 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * (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/lib/channel/message_size_filter.h" #include "src/core/lib/channel/message_size_filter.h"
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/transport/http2_errors.h" #include "src/core/lib/transport/http2_errors.h"
#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/service_config.h"
#define DEFAULT_MAX_CONNECTION_AGE_S INT_MAX #define DEFAULT_MAX_CONNECTION_AGE_MS INT_MAX
#define DEFAULT_MAX_CONNECTION_AGE_GRACE_S INT_MAX #define DEFAULT_MAX_CONNECTION_AGE_GRACE_MS INT_MAX
#define DEFAULT_MAX_CONNECTION_IDLE_S INT_MAX #define DEFAULT_MAX_CONNECTION_IDLE_MS INT_MAX
typedef struct channel_data { typedef struct channel_data {
// We take a reference to the channel stack for the timer callback /* We take a reference to the channel stack for the timer callback */
grpc_channel_stack* channel_stack; grpc_channel_stack* channel_stack;
// Guards access to max_age_timer, max_age_timer_pending, max_age_grace_timer /* Guards access to max_age_timer, max_age_timer_pending, max_age_grace_timer
// and max_age_grace_timer_pending and max_age_grace_timer_pending */
gpr_mu max_age_timer_mu; gpr_mu max_age_timer_mu;
// True if the max_age timer callback is currently pending /* True if the max_age timer callback is currently pending */
bool max_age_timer_pending; bool max_age_timer_pending;
// True if the max_age_grace timer callback is currently pending /* True if the max_age_grace timer callback is currently pending */
bool max_age_grace_timer_pending; bool max_age_grace_timer_pending;
// The timer for checking if the channel has reached its max age /* The timer for checking if the channel has reached its max age */
grpc_timer max_age_timer; grpc_timer max_age_timer;
// The timer for checking if the max-aged channel has uesed up the grace /* The timer for checking if the max-aged channel has uesed up the grace
// period period */
grpc_timer max_age_grace_timer; grpc_timer max_age_grace_timer;
// The timer for checking if the channel's idle duration reaches /* The timer for checking if the channel's idle duration reaches
// max_connection_idle max_connection_idle */
grpc_timer max_idle_timer; grpc_timer max_idle_timer;
// Allowed max time a channel may have no outstanding rpcs /* Allowed max time a channel may have no outstanding rpcs */
gpr_timespec max_connection_idle; gpr_timespec max_connection_idle;
// Allowed max time a channel may exist /* Allowed max time a channel may exist */
gpr_timespec max_connection_age; gpr_timespec max_connection_age;
// Allowed grace period after the channel reaches its max age /* Allowed grace period after the channel reaches its max age */
gpr_timespec max_connection_age_grace; gpr_timespec max_connection_age_grace;
// Closure to run when the channel's idle duration reaches max_connection_idle /* Closure to run when the channel's idle duration reaches max_connection_idle
// and should be closed gracefully and should be closed gracefully */
grpc_closure close_max_idle_channel; grpc_closure close_max_idle_channel;
// Closure to run when the channel reaches its max age and should be closed /* Closure to run when the channel reaches its max age and should be closed
// gracefully gracefully */
grpc_closure close_max_age_channel; grpc_closure close_max_age_channel;
// Closure to run the channel uses up its max age grace time and should be /* Closure to run the channel uses up its max age grace time and should be
// closed forcibly closed forcibly */
grpc_closure force_close_max_age_channel; grpc_closure force_close_max_age_channel;
// Closure to run when the init fo channel stack is done and the max_idle /* Closure to run when the init fo channel stack is done and the max_idle
// timer should be started timer should be started */
grpc_closure start_max_idle_timer_after_init; grpc_closure start_max_idle_timer_after_init;
// Closure to run when the init fo channel stack is done and the max_age timer /* Closure to run when the init fo channel stack is done and the max_age timer
// should be started should be started */
grpc_closure start_max_age_timer_after_init; grpc_closure start_max_age_timer_after_init;
// Closure to run when the goaway op is finished and the max_age_timer /* Closure to run when the goaway op is finished and the max_age_timer */
grpc_closure start_max_age_grace_timer_after_goaway_op; grpc_closure start_max_age_grace_timer_after_goaway_op;
// Closure to run when the channel connectivity state changes /* Closure to run when the channel connectivity state changes */
grpc_closure channel_connectivity_changed; grpc_closure channel_connectivity_changed;
// Records the current connectivity state /* Records the current connectivity state */
grpc_connectivity_state connectivity_state; grpc_connectivity_state connectivity_state;
// Number of active calls /* Number of active calls */
gpr_atm call_count; gpr_atm call_count;
} channel_data; } channel_data;
/* Increase the nubmer of active calls. Before the increasement, if there are no
calls, the max_idle_timer should be cancelled. */
static void increase_call_count(grpc_exec_ctx* exec_ctx, channel_data* chand) { static void increase_call_count(grpc_exec_ctx* exec_ctx, channel_data* chand) {
if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) { if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) {
grpc_timer_cancel(exec_ctx, &chand->max_idle_timer); grpc_timer_cancel(exec_ctx, &chand->max_idle_timer);
} }
} }
/* Decrease the nubmer of active calls. After the decrement, if there are no
calls, the max_idle_timer should be started. */
static void decrease_call_count(grpc_exec_ctx* exec_ctx, channel_data* chand) { static void decrease_call_count(grpc_exec_ctx* exec_ctx, channel_data* chand) {
if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) { if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) {
GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer"); GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer");
@ -112,6 +117,9 @@ static void decrease_call_count(grpc_exec_ctx* exec_ctx, channel_data* chand) {
static void start_max_idle_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg, static void start_max_idle_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) { grpc_error* error) {
channel_data* chand = arg; channel_data* chand = arg;
/* Decrease call_count. If there are no active calls at this time,
max_idle_timer will start here. If the number of active calls is not 0,
max_idle_timer will start after all the active calls end. */
decrease_call_count(exec_ctx, chand); decrease_call_count(exec_ctx, chand);
GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack, GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->channel_stack,
"max_age start_max_idle_timer_after_init"); "max_age start_max_idle_timer_after_init");
@ -180,7 +188,6 @@ static void close_max_age_channel(grpc_exec_ctx* exec_ctx, void* arg,
chand->max_age_timer_pending = false; chand->max_age_timer_pending = false;
gpr_mu_unlock(&chand->max_age_timer_mu); gpr_mu_unlock(&chand->max_age_timer_mu);
if (error == GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) {
gpr_log(GPR_DEBUG, "close_max_age_channel");
GRPC_CHANNEL_STACK_REF(chand->channel_stack, GRPC_CHANNEL_STACK_REF(chand->channel_stack,
"max_age start_max_age_grace_timer_after_goaway_op"); "max_age start_max_age_grace_timer_after_goaway_op");
grpc_transport_op* op = grpc_make_transport_op( grpc_transport_op* op = grpc_make_transport_op(
@ -205,7 +212,6 @@ static void force_close_max_age_channel(grpc_exec_ctx* exec_ctx, void* arg,
chand->max_age_grace_timer_pending = false; chand->max_age_grace_timer_pending = false;
gpr_mu_unlock(&chand->max_age_timer_mu); gpr_mu_unlock(&chand->max_age_timer_mu);
if (error == GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) {
gpr_log(GPR_DEBUG, "force_close_max_age_channel");
grpc_transport_op* op = grpc_make_transport_op(NULL); grpc_transport_op* op = grpc_make_transport_op(NULL);
op->disconnect_with_error = op->disconnect_with_error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel reaches max age"); GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel reaches max age");
@ -239,11 +245,14 @@ static void channel_connectivity_changed(grpc_exec_ctx* exec_ctx, void* arg,
chand->max_age_grace_timer_pending = false; chand->max_age_grace_timer_pending = false;
} }
gpr_mu_unlock(&chand->max_age_timer_mu); gpr_mu_unlock(&chand->max_age_timer_mu);
/* If there are no active calls, this increasement will cancel
max_idle_timer, and prevent max_idle_timer from being started in the
future. */
increase_call_count(exec_ctx, chand); increase_call_count(exec_ctx, chand);
} }
} }
// Constructor for call_data. /* Constructor for call_data. */
static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx, static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
grpc_call_element* elem, grpc_call_element* elem,
const grpc_call_element_args* args) { const grpc_call_element_args* args) {
@ -252,7 +261,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
// Destructor for call_data. /* Destructor for call_data. */
static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
const grpc_call_final_info* final_info, const grpc_call_final_info* final_info,
grpc_closure* ignored) { grpc_closure* ignored) {
@ -260,7 +269,7 @@ static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
decrease_call_count(exec_ctx, chand); decrease_call_count(exec_ctx, chand);
} }
// Constructor for channel_data. /* Constructor for channel_data. */
static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx, static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
grpc_channel_element* elem, grpc_channel_element* elem,
grpc_channel_element_args* args) { grpc_channel_element_args* args) {
@ -270,44 +279,44 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
chand->max_age_grace_timer_pending = false; chand->max_age_grace_timer_pending = false;
chand->channel_stack = args->channel_stack; chand->channel_stack = args->channel_stack;
chand->max_connection_age = chand->max_connection_age =
DEFAULT_MAX_CONNECTION_AGE_S == INT_MAX DEFAULT_MAX_CONNECTION_AGE_MS == INT_MAX
? gpr_inf_future(GPR_TIMESPAN) ? gpr_inf_future(GPR_TIMESPAN)
: gpr_time_from_seconds(DEFAULT_MAX_CONNECTION_AGE_S, GPR_TIMESPAN); : gpr_time_from_millis(DEFAULT_MAX_CONNECTION_AGE_MS, GPR_TIMESPAN);
chand->max_connection_age_grace = chand->max_connection_age_grace =
DEFAULT_MAX_CONNECTION_AGE_GRACE_S == INT_MAX DEFAULT_MAX_CONNECTION_AGE_GRACE_MS == INT_MAX
? gpr_inf_future(GPR_TIMESPAN) ? gpr_inf_future(GPR_TIMESPAN)
: gpr_time_from_seconds(DEFAULT_MAX_CONNECTION_AGE_GRACE_S, : gpr_time_from_millis(DEFAULT_MAX_CONNECTION_AGE_GRACE_MS,
GPR_TIMESPAN); GPR_TIMESPAN);
chand->max_connection_idle = chand->max_connection_idle =
DEFAULT_MAX_CONNECTION_IDLE_S == INT_MAX DEFAULT_MAX_CONNECTION_IDLE_MS == INT_MAX
? gpr_inf_future(GPR_TIMESPAN) ? gpr_inf_future(GPR_TIMESPAN)
: gpr_time_from_seconds(DEFAULT_MAX_CONNECTION_IDLE_S, GPR_TIMESPAN); : gpr_time_from_millis(DEFAULT_MAX_CONNECTION_IDLE_MS, GPR_TIMESPAN);
for (size_t i = 0; i < args->channel_args->num_args; ++i) { for (size_t i = 0; i < args->channel_args->num_args; ++i) {
if (0 == strcmp(args->channel_args->args[i].key, if (0 == strcmp(args->channel_args->args[i].key,
GRPC_ARG_MAX_CONNECTION_AGE_S)) { GRPC_ARG_MAX_CONNECTION_AGE_MS)) {
const int value = grpc_channel_arg_get_integer( const int value = grpc_channel_arg_get_integer(
&args->channel_args->args[i], &args->channel_args->args[i],
(grpc_integer_options){DEFAULT_MAX_CONNECTION_AGE_S, 1, INT_MAX}); (grpc_integer_options){DEFAULT_MAX_CONNECTION_AGE_MS, 1, INT_MAX});
chand->max_connection_age = chand->max_connection_age =
value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN) value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN)
: gpr_time_from_seconds(value, GPR_TIMESPAN); : gpr_time_from_millis(value, GPR_TIMESPAN);
} else if (0 == strcmp(args->channel_args->args[i].key, } else if (0 == strcmp(args->channel_args->args[i].key,
GRPC_ARG_MAX_CONNECTION_AGE_GRACE_S)) { GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS)) {
const int value = grpc_channel_arg_get_integer( const int value = grpc_channel_arg_get_integer(
&args->channel_args->args[i], &args->channel_args->args[i],
(grpc_integer_options){DEFAULT_MAX_CONNECTION_AGE_GRACE_S, 0, (grpc_integer_options){DEFAULT_MAX_CONNECTION_AGE_GRACE_MS, 0,
INT_MAX}); INT_MAX});
chand->max_connection_age_grace = chand->max_connection_age_grace =
value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN) value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN)
: gpr_time_from_seconds(value, GPR_TIMESPAN); : gpr_time_from_millis(value, GPR_TIMESPAN);
} else if (0 == strcmp(args->channel_args->args[i].key, } else if (0 == strcmp(args->channel_args->args[i].key,
GRPC_ARG_MAX_CONNECTION_IDLE_S)) { GRPC_ARG_MAX_CONNECTION_IDLE_MS)) {
const int value = grpc_channel_arg_get_integer( const int value = grpc_channel_arg_get_integer(
&args->channel_args->args[i], &args->channel_args->args[i],
(grpc_integer_options){DEFAULT_MAX_CONNECTION_IDLE_S, 1, INT_MAX}); (grpc_integer_options){DEFAULT_MAX_CONNECTION_IDLE_MS, 1, INT_MAX});
chand->max_connection_idle = chand->max_connection_idle =
value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN) value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN)
: gpr_time_from_seconds(value, GPR_TIMESPAN); : gpr_time_from_millis(value, GPR_TIMESPAN);
} }
} }
grpc_closure_init(&chand->close_max_idle_channel, close_max_idle_channel, grpc_closure_init(&chand->close_max_idle_channel, close_max_idle_channel,
@ -332,19 +341,21 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
if (gpr_time_cmp(chand->max_connection_age, gpr_inf_future(GPR_TIMESPAN)) != if (gpr_time_cmp(chand->max_connection_age, gpr_inf_future(GPR_TIMESPAN)) !=
0) { 0) {
// When the channel reaches its max age, we send down an op with /* When the channel reaches its max age, we send down an op with
// goaway_error set. However, we can't send down any ops until after the goaway_error set. However, we can't send down any ops until after the
// channel stack is fully initialized. If we start the timer here, we have channel stack is fully initialized. If we start the timer here, we have
// no guarantee that the timer won't pop before channel stack initialization no guarantee that the timer won't pop before channel stack initialization
// is finished. To avoid that problem, we create a closure to start the is finished. To avoid that problem, we create a closure to start the
// timer, and we schedule that closure to be run after call stack timer, and we schedule that closure to be run after call stack
// initialization is done. initialization is done. */
GRPC_CHANNEL_STACK_REF(chand->channel_stack, GRPC_CHANNEL_STACK_REF(chand->channel_stack,
"max_age start_max_age_timer_after_init"); "max_age start_max_age_timer_after_init");
grpc_closure_sched(exec_ctx, &chand->start_max_age_timer_after_init, grpc_closure_sched(exec_ctx, &chand->start_max_age_timer_after_init,
GRPC_ERROR_NONE); GRPC_ERROR_NONE);
} }
/* Initialize the number of calls as 1, so that the max_idle_timer will not
start until start_max_idle_timer_after_init is invoked. */
gpr_atm_rel_store(&chand->call_count, 1); gpr_atm_rel_store(&chand->call_count, 1);
if (gpr_time_cmp(chand->max_connection_idle, gpr_inf_future(GPR_TIMESPAN)) != if (gpr_time_cmp(chand->max_connection_idle, gpr_inf_future(GPR_TIMESPAN)) !=
0) { 0) {
@ -356,14 +367,14 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
// Destructor for channel_data. /* Destructor for channel_data. */
static void destroy_channel_elem(grpc_exec_ctx* exec_ctx, static void destroy_channel_elem(grpc_exec_ctx* exec_ctx,
grpc_channel_element* elem) {} grpc_channel_element* elem) {}
const grpc_channel_filter grpc_max_age_filter = { const grpc_channel_filter grpc_max_age_filter = {
grpc_call_next_op, grpc_call_next_op,
grpc_channel_next_op, grpc_channel_next_op,
0, // sizeof_call_data 0, /* sizeof_call_data */
init_call_elem, init_call_elem,
grpc_call_stack_ignore_set_pollset_or_pollset_set, grpc_call_stack_ignore_set_pollset_or_pollset_set,
destroy_call_elem, destroy_call_elem,

@ -36,18 +36,16 @@
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/sync.h> #include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h> #include <grpc/support/time.h>
#include <grpc/support/useful.h> #include <grpc/support/useful.h>
#include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/cq_verifier.h"
#define MAX_CONNECTION_AGE_S 1 #define MAX_CONNECTION_AGE_MS 500
#define MAX_CONNECTION_AGE_GRACE_S 2 #define MAX_CONNECTION_AGE_GRACE_MS 1000
#define MAX_CONNECTION_IDLE_S 99 #define MAX_CONNECTION_IDLE_MS 9999
static void *tag(intptr_t t) { return (void *)t; } static void *tag(intptr_t t) { return (void *)t; }
@ -84,14 +82,14 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL); grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq); cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER, grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_AGE_S, .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
.value.integer = MAX_CONNECTION_AGE_S}, .value.integer = MAX_CONNECTION_AGE_MS},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_S, .key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS,
.value.integer = MAX_CONNECTION_AGE_GRACE_S}, .value.integer = MAX_CONNECTION_AGE_GRACE_MS},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_IDLE_S, .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
.value.integer = MAX_CONNECTION_IDLE_S}}; .value.integer = MAX_CONNECTION_IDLE_MS}};
grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a), grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
.args = server_a}; .args = server_a};
@ -159,7 +157,7 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) {
cq_verify(cqv); cq_verify(cqv);
/* Wait for the channel to reach its max age */ /* Wait for the channel to reach its max age */
cq_verify_empty_timeout(cqv, MAX_CONNECTION_AGE_S + 1); cq_verify_empty_timeout(cqv, 1);
/* After the channel reaches its max age, we still do nothing here. And wait /* After the channel reaches its max age, we still do nothing here. And wait
for it to use up its max age grace period. */ for it to use up its max age grace period. */
@ -221,14 +219,14 @@ static void test_max_age_gracefully_close(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL); grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq); cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER, grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_AGE_S, .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
.value.integer = MAX_CONNECTION_AGE_S}, .value.integer = MAX_CONNECTION_AGE_MS},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_S, .key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS,
.value.integer = INT_MAX}, .value.integer = INT_MAX},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_IDLE_S, .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
.value.integer = MAX_CONNECTION_IDLE_S}}; .value.integer = MAX_CONNECTION_IDLE_MS}};
grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a), grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
.args = server_a}; .args = server_a};
@ -296,7 +294,7 @@ static void test_max_age_gracefully_close(grpc_end2end_test_config config) {
cq_verify(cqv); cq_verify(cqv);
/* Wait for the channel to reach its max age */ /* Wait for the channel to reach its max age */
cq_verify_empty_timeout(cqv, MAX_CONNECTION_AGE_S + 1); cq_verify_empty_timeout(cqv, 1);
/* The connection is shutting down gracefully. In-progress rpc should not be /* The connection is shutting down gracefully. In-progress rpc should not be
closed, hence the completion queue should see nothing here. */ closed, hence the completion queue should see nothing here. */

@ -36,17 +36,15 @@
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/sync.h> #include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h> #include <grpc/support/time.h>
#include <grpc/support/useful.h> #include <grpc/support/useful.h>
#include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/cq_verifier.h"
#define MAX_CONNECTION_IDLE_S 1 #define MAX_CONNECTION_IDLE_MS 500
#define MAX_CONNECTION_AGE_S 99 #define MAX_CONNECTION_AGE_MS 9999
static void *tag(intptr_t t) { return (void *)t; } static void *tag(intptr_t t) { return (void *)t; }
@ -59,11 +57,11 @@ static void test_max_connection_idle(grpc_end2end_test_config config) {
.key = "grpc.testing.fixed_reconnect_backoff_ms", .key = "grpc.testing.fixed_reconnect_backoff_ms",
.value.integer = 1000}}; .value.integer = 1000}};
grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER, grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_IDLE_S, .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
.value.integer = MAX_CONNECTION_IDLE_S}, .value.integer = MAX_CONNECTION_IDLE_MS},
{.type = GRPC_ARG_INTEGER, {.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_MAX_CONNECTION_AGE_S, .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
.value.integer = MAX_CONNECTION_AGE_S}}; .value.integer = MAX_CONNECTION_AGE_MS}};
grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(client_a), grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(client_a),
.args = client_a}; .args = client_a};
grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a), grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
@ -91,7 +89,7 @@ static void test_max_connection_idle(grpc_end2end_test_config config) {
/* wait for the channel to reach its maximum idle time */ /* wait for the channel to reach its maximum idle time */
grpc_channel_watch_connectivity_state( grpc_channel_watch_connectivity_state(
f.client, GRPC_CHANNEL_READY, f.client, GRPC_CHANNEL_READY,
grpc_timeout_seconds_to_deadline(MAX_CONNECTION_IDLE_S + 1), f.cq, grpc_timeout_milliseconds_to_deadline(MAX_CONNECTION_IDLE_MS + 500), f.cq,
tag(99)); tag(99));
CQ_EXPECT_COMPLETION(cqv, tag(99), 1); CQ_EXPECT_COMPLETION(cqv, tag(99), 1);
cq_verify(cqv); cq_verify(cqv);

Loading…
Cancel
Save