|
|
@ -470,9 +470,17 @@ static grpc_lb_policy *create_rr_locked( |
|
|
|
args.server_name = glb_policy->server_name; |
|
|
|
args.server_name = glb_policy->server_name; |
|
|
|
args.client_channel_factory = glb_policy->cc_factory; |
|
|
|
args.client_channel_factory = glb_policy->cc_factory; |
|
|
|
args.addresses = process_serverlist(serverlist); |
|
|
|
args.addresses = process_serverlist(serverlist); |
|
|
|
args.args = glb_policy->args; |
|
|
|
|
|
|
|
|
|
|
|
// Replace the LB addresses in the channel args that we pass down to
|
|
|
|
|
|
|
|
// the subchannel.
|
|
|
|
|
|
|
|
static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; |
|
|
|
|
|
|
|
const grpc_arg arg = grpc_lb_addresses_create_channel_arg(args.addresses); |
|
|
|
|
|
|
|
args.args = grpc_channel_args_copy_and_add_and_remove( |
|
|
|
|
|
|
|
glb_policy->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &arg, |
|
|
|
|
|
|
|
1); |
|
|
|
|
|
|
|
|
|
|
|
grpc_lb_policy *rr = grpc_lb_policy_create(exec_ctx, "round_robin", &args); |
|
|
|
grpc_lb_policy *rr = grpc_lb_policy_create(exec_ctx, "round_robin", &args); |
|
|
|
|
|
|
|
grpc_channel_args_destroy(args.args); |
|
|
|
|
|
|
|
|
|
|
|
if (glb_policy->addresses != NULL) { |
|
|
|
if (glb_policy->addresses != NULL) { |
|
|
|
/* dispose of the previous version */ |
|
|
|
/* dispose of the previous version */ |
|
|
@ -574,6 +582,13 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, |
|
|
|
static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, |
|
|
|
grpc_lb_policy_factory *factory, |
|
|
|
grpc_lb_policy_factory *factory, |
|
|
|
grpc_lb_policy_args *args) { |
|
|
|
grpc_lb_policy_args *args) { |
|
|
|
|
|
|
|
/* Get server name. */ |
|
|
|
|
|
|
|
const grpc_arg* arg = |
|
|
|
|
|
|
|
grpc_channel_args_find(args->args, GRPC_ARG_SERVER_NAME); |
|
|
|
|
|
|
|
const char* server_name = |
|
|
|
|
|
|
|
arg != NULL && arg->type == GRPC_ARG_STRING |
|
|
|
|
|
|
|
? arg->value.string : NULL; |
|
|
|
|
|
|
|
|
|
|
|
/* Count the number of gRPC-LB addresses. There must be at least one.
|
|
|
|
/* Count the number of gRPC-LB addresses. There must be at least one.
|
|
|
|
* TODO(roth): For now, we ignore non-balancer addresses, but in the |
|
|
|
* TODO(roth): For now, we ignore non-balancer addresses, but in the |
|
|
|
* future, we may change the behavior such that we fall back to using |
|
|
|
* future, we may change the behavior such that we fall back to using |
|
|
@ -581,22 +596,25 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, |
|
|
|
* time, this should be changed to allow a list with no balancer addresses, |
|
|
|
* time, this should be changed to allow a list with no balancer addresses, |
|
|
|
* since the resolver might fail to return a balancer address even when |
|
|
|
* since the resolver might fail to return a balancer address even when |
|
|
|
* this is the right LB policy to use. */ |
|
|
|
* this is the right LB policy to use. */ |
|
|
|
|
|
|
|
arg = grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES); |
|
|
|
|
|
|
|
GPR_ASSERT(arg != NULL && arg->type == GRPC_ARG_POINTER); |
|
|
|
|
|
|
|
grpc_lb_addresses* addresses = arg->value.pointer.p; |
|
|
|
size_t num_grpclb_addrs = 0; |
|
|
|
size_t num_grpclb_addrs = 0; |
|
|
|
for (size_t i = 0; i < args->addresses->num_addresses; ++i) { |
|
|
|
for (size_t i = 0; i < addresses->num_addresses; ++i) { |
|
|
|
if (args->addresses->addresses[i].is_balancer) ++num_grpclb_addrs; |
|
|
|
if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; |
|
|
|
} |
|
|
|
} |
|
|
|
if (num_grpclb_addrs == 0) return NULL; |
|
|
|
if (num_grpclb_addrs == 0) return NULL; |
|
|
|
|
|
|
|
|
|
|
|
glb_lb_policy *glb_policy = gpr_malloc(sizeof(*glb_policy)); |
|
|
|
glb_lb_policy *glb_policy = gpr_malloc(sizeof(*glb_policy)); |
|
|
|
memset(glb_policy, 0, sizeof(*glb_policy)); |
|
|
|
memset(glb_policy, 0, sizeof(*glb_policy)); |
|
|
|
|
|
|
|
|
|
|
|
/* All input addresses in args->addresses come from a resolver that claims
|
|
|
|
/* All input addresses in addresses come from a resolver that claims
|
|
|
|
* they are LB services. It's the resolver's responsibility to make sure |
|
|
|
* they are LB services. It's the resolver's responsibility to make sure |
|
|
|
* this |
|
|
|
* this |
|
|
|
* policy is only instantiated and used in that case. |
|
|
|
* policy is only instantiated and used in that case. |
|
|
|
* |
|
|
|
* |
|
|
|
* Create a client channel over them to communicate with a LB service */ |
|
|
|
* Create a client channel over them to communicate with a LB service */ |
|
|
|
glb_policy->server_name = gpr_strdup(args->server_name); |
|
|
|
glb_policy->server_name = gpr_strdup(server_name); |
|
|
|
glb_policy->cc_factory = args->client_channel_factory; |
|
|
|
glb_policy->cc_factory = args->client_channel_factory; |
|
|
|
glb_policy->args = grpc_channel_args_copy(args->args); |
|
|
|
glb_policy->args = grpc_channel_args_copy(args->args); |
|
|
|
GPR_ASSERT(glb_policy->cc_factory != NULL); |
|
|
|
GPR_ASSERT(glb_policy->cc_factory != NULL); |
|
|
@ -606,20 +624,20 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, |
|
|
|
* TODO(dgq): support mixed ip version */ |
|
|
|
* TODO(dgq): support mixed ip version */ |
|
|
|
char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs); |
|
|
|
char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs); |
|
|
|
size_t addr_index = 0; |
|
|
|
size_t addr_index = 0; |
|
|
|
for (size_t i = 0; i < args->addresses->num_addresses; i++) { |
|
|
|
for (size_t i = 0; i < addresses->num_addresses; i++) { |
|
|
|
if (args->addresses->addresses[i].user_data != NULL) { |
|
|
|
if (addresses->addresses[i].user_data != NULL) { |
|
|
|
gpr_log(GPR_ERROR, |
|
|
|
gpr_log(GPR_ERROR, |
|
|
|
"This LB policy doesn't support user data. It will be ignored"); |
|
|
|
"This LB policy doesn't support user data. It will be ignored"); |
|
|
|
} |
|
|
|
} |
|
|
|
if (args->addresses->addresses[i].is_balancer) { |
|
|
|
if (addresses->addresses[i].is_balancer) { |
|
|
|
if (addr_index == 0) { |
|
|
|
if (addr_index == 0) { |
|
|
|
addr_strs[addr_index++] = grpc_sockaddr_to_uri( |
|
|
|
addr_strs[addr_index++] = grpc_sockaddr_to_uri( |
|
|
|
(const struct sockaddr *)&args->addresses->addresses[i] |
|
|
|
(const struct sockaddr *)&addresses->addresses[i] |
|
|
|
.address.addr); |
|
|
|
.address.addr); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
GPR_ASSERT(grpc_sockaddr_to_string( |
|
|
|
GPR_ASSERT(grpc_sockaddr_to_string( |
|
|
|
&addr_strs[addr_index++], |
|
|
|
&addr_strs[addr_index++], |
|
|
|
(const struct sockaddr *)&args->addresses->addresses[i] |
|
|
|
(const struct sockaddr *)&addresses->addresses[i] |
|
|
|
.address.addr, |
|
|
|
.address.addr, |
|
|
|
true) > 0); |
|
|
|
true) > 0); |
|
|
|
} |
|
|
|
} |
|
|
@ -629,10 +647,29 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, |
|
|
|
char *target_uri_str = gpr_strjoin_sep((const char **)addr_strs, |
|
|
|
char *target_uri_str = gpr_strjoin_sep((const char **)addr_strs, |
|
|
|
num_grpclb_addrs, ",", &uri_path_len); |
|
|
|
num_grpclb_addrs, ",", &uri_path_len); |
|
|
|
|
|
|
|
|
|
|
|
/* will pick using pick_first */ |
|
|
|
/* Create a channel to talk to the LBs.
|
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* We strip out the channel arg for the LB policy name, since we want |
|
|
|
|
|
|
|
* to use the default (pick_first) in this case. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* We also strip out the channel arg for the resolved addresses, since |
|
|
|
|
|
|
|
* that will be generated by the name resolver used in the LB channel. |
|
|
|
|
|
|
|
* Note that the LB channel will use the sockaddr resolver, so this |
|
|
|
|
|
|
|
* won't actually generate a query to DNS (or some other name service). |
|
|
|
|
|
|
|
* However, the addresses returned by the sockaddr resolver will have |
|
|
|
|
|
|
|
* is_balancer=false, whereas our own addresses have is_balancer=true. |
|
|
|
|
|
|
|
* We need the LB channel to return addresses with is_balancer=false |
|
|
|
|
|
|
|
* so that it does not wind up recursively using the grpclb LB policy, |
|
|
|
|
|
|
|
* as per the special case logic in client_channel.c. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
static const char* keys_to_remove[] = { |
|
|
|
|
|
|
|
GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES}; |
|
|
|
|
|
|
|
grpc_channel_args *new_args = grpc_channel_args_copy_and_remove( |
|
|
|
|
|
|
|
args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove)); |
|
|
|
glb_policy->lb_channel = grpc_client_channel_factory_create_channel( |
|
|
|
glb_policy->lb_channel = grpc_client_channel_factory_create_channel( |
|
|
|
exec_ctx, glb_policy->cc_factory, target_uri_str, |
|
|
|
exec_ctx, glb_policy->cc_factory, target_uri_str, |
|
|
|
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, args->args); |
|
|
|
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args); |
|
|
|
|
|
|
|
grpc_channel_args_destroy(new_args); |
|
|
|
|
|
|
|
|
|
|
|
gpr_free(target_uri_str); |
|
|
|
gpr_free(target_uri_str); |
|
|
|
for (size_t i = 0; i < num_grpclb_addrs; i++) { |
|
|
|
for (size_t i = 0; i < num_grpclb_addrs; i++) { |
|
|
|