aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mark D. Roth <roth@google.com>2016-09-28 14:23:05 -0700
committerGravatar Mark D. Roth <roth@google.com>2016-09-28 14:23:05 -0700
commit6336ef7bad13fbadddcfc12a7b253db6e6dfdbe7 (patch)
tree5ef4faa0d37521128136233ef647194c0bcace34
parentef7efb1b845f4eb32e35d296cc925d8ed8384538 (diff)
Use per-method wait_until_ready value.
-rw-r--r--src/core/ext/client_config/client_channel.c36
-rw-r--r--src/core/lib/channel/deadline_filter.c20
-rw-r--r--src/core/lib/channel/deadline_filter.h2
3 files changed, 40 insertions, 18 deletions
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c
index 7a80975278..3860f65f95 100644
--- a/src/core/ext/client_config/client_channel.c
+++ b/src/core/ext/client_config/client_channel.c
@@ -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);
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 89dc8dd6e8..5216338833 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -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;
}
diff --git a/src/core/lib/channel/deadline_filter.h b/src/core/lib/channel/deadline_filter.h
index 2fcee0b9ef..ce6e8ea974 100644
--- a/src/core/lib/channel/deadline_filter.h
+++ b/src/core/lib/channel/deadline_filter.h
@@ -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(