Use per-method wait_until_ready value.

pull/8303/head
Mark D. Roth 8 years ago
parent ef7efb1b84
commit 6336ef7bad
  1. 36
      src/core/ext/client_config/client_channel.c
  2. 20
      src/core/lib/channel/deadline_filter.c
  3. 2
      src/core/lib/channel/deadline_filter.h

@ -421,6 +421,9 @@ typedef struct client_channel_call_data {
grpc_deadline_state deadline_state;
gpr_timespec deadline;
enum { WAIT_FOR_READY_UNSET, WAIT_FOR_READY_FALSE, WAIT_FOR_READY_TRUE }
wait_for_ready_from_service_config;
// Request path.
grpc_mdstr *path;
@ -737,12 +740,24 @@ retry:
calld->connected_subchannel == NULL &&
op->send_initial_metadata != NULL) {
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
// If the application explicitly set wait_for_ready, use that.
// Otherwise, if the service config specified a value for this
// method, use that.
uint32_t initial_metadata_flags = op->send_initial_metadata_flags;
if ((initial_metadata_flags &
GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET) == 0 &&
calld->wait_for_ready_from_service_config != WAIT_FOR_READY_UNSET) {
if (calld->wait_for_ready_from_service_config == WAIT_FOR_READY_TRUE) {
initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
} else {
initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
}
}
grpc_closure_init(&calld->next_step, subchannel_ready, calld);
GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata,
op->send_initial_metadata_flags,
&calld->connected_subchannel, &calld->next_step,
GRPC_ERROR_NONE)) {
initial_metadata_flags, &calld->connected_subchannel,
&calld->next_step, GRPC_ERROR_NONE)) {
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
}
@ -782,7 +797,20 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
? NULL
: grpc_method_config_table_ref(chand->method_config_table);
gpr_mu_unlock(&chand->mu);
grpc_deadline_state_init(exec_ctx, elem, args, method_config_table);
grpc_method_config *method_config =
method_config_table == NULL
? NULL
: grpc_method_config_table_get_method_config(method_config_table,
args->path);
grpc_deadline_state_init(exec_ctx, elem, args, method_config);
calld->wait_for_ready_from_service_config = WAIT_FOR_READY_UNSET;
if (method_config != NULL) {
bool* wait_for_ready = grpc_method_config_get_wait_for_ready(method_config);
if (wait_for_ready != NULL) {
calld->wait_for_ready_from_service_config =
*wait_for_ready ? WAIT_FOR_READY_TRUE : WAIT_FOR_READY_FALSE;
}
}
grpc_method_config_table_unref(chand->method_config_table);
calld->deadline = args->deadline;
calld->path = GRPC_MDSTR_REF(args->path);

@ -124,7 +124,7 @@ static void start_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
grpc_call_element_args* args,
grpc_method_config_table* method_config_table) {
grpc_method_config* method_config) {
grpc_deadline_state* deadline_state = elem->call_data;
memset(deadline_state, 0, sizeof(*deadline_state));
deadline_state->call_stack = args->call_stack;
@ -133,16 +133,11 @@ void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
// set on clients with a finite deadline.
gpr_timespec deadline =
gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
if (method_config_table != NULL) {
grpc_method_config* method_config =
grpc_method_config_table_get_method_config(method_config_table,
args->path);
if (method_config != NULL) {
gpr_timespec* per_method_deadline =
grpc_method_config_get_timeout(method_config);
if (per_method_deadline != NULL) {
deadline = gpr_time_min(deadline, *per_method_deadline);
}
if (method_config != NULL) {
gpr_timespec* per_method_deadline =
grpc_method_config_get_timeout(method_config);
if (per_method_deadline != NULL) {
deadline = gpr_time_min(deadline, *per_method_deadline);
}
}
if (gpr_time_cmp(deadline, gpr_inf_future(GPR_CLOCK_MONOTONIC)) != 0) {
@ -222,8 +217,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
grpc_call_element_args* args) {
// Note: size of call data is different between client and server.
memset(elem->call_data, 0, elem->filter->sizeof_call_data);
grpc_deadline_state_init(exec_ctx, elem, args,
NULL /* method_config_table */);
grpc_deadline_state_init(exec_ctx, elem, args, NULL /* method_config */);
return GRPC_ERROR_NONE;
}

@ -66,7 +66,7 @@ typedef struct grpc_deadline_state {
// after the function returns.
void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
grpc_call_element_args* args,
grpc_method_config_table* method_config_table);
grpc_method_config* method_config);
void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
grpc_call_element* elem);
void grpc_deadline_state_client_start_transport_stream_op(

Loading…
Cancel
Save