|
|
|
@ -43,6 +43,7 @@ |
|
|
|
|
#include <grpc/support/useful.h> |
|
|
|
|
|
|
|
|
|
#include "src/core/ext/client_config/lb_policy_registry.h" |
|
|
|
|
#include "src/core/ext/client_config/method_config.h" |
|
|
|
|
#include "src/core/ext/client_config/subchannel.h" |
|
|
|
|
#include "src/core/lib/channel/channel_args.h" |
|
|
|
|
#include "src/core/lib/channel/connected_channel.h" |
|
|
|
@ -70,15 +71,14 @@ typedef struct client_channel_channel_data { |
|
|
|
|
/** client channel factory */ |
|
|
|
|
grpc_client_channel_factory *client_channel_factory; |
|
|
|
|
|
|
|
|
|
/** mutex protecting client configuration, including all
|
|
|
|
|
variables below in this data structure */ |
|
|
|
|
/** mutex protecting all variables below in this data structure */ |
|
|
|
|
gpr_mu mu; |
|
|
|
|
/** currently active load balancer - guarded by mu */ |
|
|
|
|
/** currently active load balancer */ |
|
|
|
|
grpc_lb_policy *lb_policy; |
|
|
|
|
/** incoming resolver result - set by resolver.next(), guarded by mu */ |
|
|
|
|
grpc_resolver_result *incoming_resolver_result; |
|
|
|
|
/** current resolver result */ |
|
|
|
|
grpc_resolver_result *current_resolver_result; |
|
|
|
|
/** method config table */ |
|
|
|
|
grpc_method_config_table *method_config_table; |
|
|
|
|
/** incoming resolver result - set by resolver.next() */ |
|
|
|
|
grpc_resolver_result *resolver_result; |
|
|
|
|
/** a list of closures that are all waiting for config to come in */ |
|
|
|
|
grpc_closure_list waiting_for_config_closures; |
|
|
|
|
/** resolver callback */ |
|
|
|
@ -176,23 +176,23 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
channel_data *chand = arg; |
|
|
|
|
grpc_lb_policy *lb_policy = NULL; |
|
|
|
|
grpc_lb_policy *old_lb_policy; |
|
|
|
|
grpc_method_config_table *method_config_table = NULL; |
|
|
|
|
grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE; |
|
|
|
|
bool exit_idle = false; |
|
|
|
|
grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy"); |
|
|
|
|
|
|
|
|
|
if (chand->incoming_resolver_result != NULL) { |
|
|
|
|
if (chand->resolver_result != NULL) { |
|
|
|
|
grpc_lb_policy_args lb_policy_args; |
|
|
|
|
lb_policy_args.server_name = |
|
|
|
|
grpc_resolver_result_get_server_name(chand->incoming_resolver_result); |
|
|
|
|
grpc_resolver_result_get_server_name(chand->resolver_result); |
|
|
|
|
lb_policy_args.addresses = |
|
|
|
|
grpc_resolver_result_get_addresses(chand->incoming_resolver_result); |
|
|
|
|
lb_policy_args.additional_args = grpc_resolver_result_get_lb_policy_args( |
|
|
|
|
chand->incoming_resolver_result); |
|
|
|
|
grpc_resolver_result_get_addresses(chand->resolver_result); |
|
|
|
|
lb_policy_args.additional_args = |
|
|
|
|
grpc_resolver_result_get_lb_policy_args(chand->resolver_result); |
|
|
|
|
lb_policy_args.client_channel_factory = chand->client_channel_factory; |
|
|
|
|
lb_policy = grpc_lb_policy_create( |
|
|
|
|
exec_ctx, |
|
|
|
|
grpc_resolver_result_get_lb_policy_name( |
|
|
|
|
chand->incoming_resolver_result), |
|
|
|
|
grpc_resolver_result_get_lb_policy_name(chand->resolver_result), |
|
|
|
|
&lb_policy_args); |
|
|
|
|
if (lb_policy != NULL) { |
|
|
|
|
GRPC_LB_POLICY_REF(lb_policy, "config_change"); |
|
|
|
@ -200,11 +200,15 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
state = |
|
|
|
|
grpc_lb_policy_check_connectivity(exec_ctx, lb_policy, &state_error); |
|
|
|
|
} |
|
|
|
|
if (chand->current_resolver_result != NULL) { |
|
|
|
|
grpc_resolver_result_unref(exec_ctx, chand->current_resolver_result); |
|
|
|
|
const grpc_arg *channel_arg = grpc_channel_args_find( |
|
|
|
|
lb_policy_args.additional_args, GRPC_ARG_SERVICE_CONFIG); |
|
|
|
|
if (channel_arg != NULL) { |
|
|
|
|
GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); |
|
|
|
|
method_config_table = grpc_method_config_table_ref( |
|
|
|
|
(grpc_method_config_table *)channel_arg->value.pointer.p); |
|
|
|
|
} |
|
|
|
|
chand->current_resolver_result = chand->incoming_resolver_result; |
|
|
|
|
chand->incoming_resolver_result = NULL; |
|
|
|
|
grpc_resolver_result_unref(exec_ctx, chand->resolver_result); |
|
|
|
|
chand->resolver_result = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (lb_policy != NULL) { |
|
|
|
@ -215,6 +219,10 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
gpr_mu_lock(&chand->mu); |
|
|
|
|
old_lb_policy = chand->lb_policy; |
|
|
|
|
chand->lb_policy = lb_policy; |
|
|
|
|
if (chand->method_config_table != NULL) { |
|
|
|
|
grpc_method_config_table_unref(chand->method_config_table); |
|
|
|
|
} |
|
|
|
|
chand->method_config_table = method_config_table; |
|
|
|
|
if (lb_policy != NULL) { |
|
|
|
|
grpc_exec_ctx_enqueue_list(exec_ctx, &chand->waiting_for_config_closures, |
|
|
|
|
NULL); |
|
|
|
@ -238,8 +246,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
watch_lb_policy(exec_ctx, chand, lb_policy, state); |
|
|
|
|
} |
|
|
|
|
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); |
|
|
|
|
grpc_resolver_next(exec_ctx, chand->resolver, |
|
|
|
|
&chand->incoming_resolver_result, |
|
|
|
|
grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result, |
|
|
|
|
&chand->on_resolver_result_changed); |
|
|
|
|
gpr_mu_unlock(&chand->mu); |
|
|
|
|
} else { |
|
|
|
@ -376,8 +383,8 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx, |
|
|
|
|
chand->interested_parties); |
|
|
|
|
GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); |
|
|
|
|
} |
|
|
|
|
if (chand->current_resolver_result != NULL) { |
|
|
|
|
grpc_resolver_result_unref(exec_ctx, chand->current_resolver_result); |
|
|
|
|
if (chand->method_config_table != NULL) { |
|
|
|
|
grpc_method_config_table_unref(chand->method_config_table); |
|
|
|
|
} |
|
|
|
|
grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker); |
|
|
|
|
grpc_pollset_set_destroy(chand->interested_parties); |
|
|
|
@ -512,11 +519,9 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
/* Get method config. */ |
|
|
|
|
// FIXME: need to actually use the config data!
|
|
|
|
|
// FIXME: think about refcounting vs. atomicity here
|
|
|
|
|
grpc_method_config_table* table = grpc_resolver_result_get_method_configs( |
|
|
|
|
chand->current_resolver_result); |
|
|
|
|
if (table != NULL) { |
|
|
|
|
if (chand->method_config_table != NULL) { |
|
|
|
|
calld->method_config = grpc_method_config_table_get_method_config( |
|
|
|
|
table, calld->path); |
|
|
|
|
chand->method_config_table, calld->path); |
|
|
|
|
} |
|
|
|
|
/* Create call on subchannel. */ |
|
|
|
|
grpc_subchannel_call *subchannel_call = NULL; |
|
|
|
@ -626,8 +631,7 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, |
|
|
|
|
if (chand->resolver != NULL && !chand->started_resolving) { |
|
|
|
|
chand->started_resolving = true; |
|
|
|
|
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); |
|
|
|
|
grpc_resolver_next(exec_ctx, chand->resolver, |
|
|
|
|
&chand->incoming_resolver_result, |
|
|
|
|
grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result, |
|
|
|
|
&chand->on_resolver_result_changed); |
|
|
|
|
} |
|
|
|
|
if (chand->resolver != NULL) { |
|
|
|
@ -836,7 +840,7 @@ void grpc_client_channel_finish_initialization( |
|
|
|
|
chand->exit_idle_when_lb_policy_arrives) { |
|
|
|
|
chand->started_resolving = true; |
|
|
|
|
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); |
|
|
|
|
grpc_resolver_next(exec_ctx, resolver, &chand->incoming_resolver_result, |
|
|
|
|
grpc_resolver_next(exec_ctx, resolver, &chand->resolver_result, |
|
|
|
|
&chand->on_resolver_result_changed); |
|
|
|
|
} |
|
|
|
|
chand->client_channel_factory = client_channel_factory; |
|
|
|
@ -858,8 +862,7 @@ grpc_connectivity_state grpc_client_channel_check_connectivity_state( |
|
|
|
|
if (!chand->started_resolving && chand->resolver != NULL) { |
|
|
|
|
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); |
|
|
|
|
chand->started_resolving = true; |
|
|
|
|
grpc_resolver_next(exec_ctx, chand->resolver, |
|
|
|
|
&chand->incoming_resolver_result, |
|
|
|
|
grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result, |
|
|
|
|
&chand->on_resolver_result_changed); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|