Allow fetching service config via grpc_channel_get_info().

pull/8617/head
Mark D. Roth 8 years ago
parent c56c3ad259
commit c625c7a023
  1. 3
      include/grpc/impl/codegen/grpc_types.h
  2. 16
      src/core/ext/client_channel/client_channel.c
  3. 37
      test/core/client_channel/lb_policies_test.c

@ -473,6 +473,9 @@ typedef struct {
/* If non-NULL, will be set to point to a string indicating the LB
* policy name. Caller takes ownership. */
char **lb_policy_name;
/* If non-NULL, will be set to point to a string containing the
* service config used by the channel in JSON form. */
char **service_config_json;
} grpc_channel_info;
typedef struct grpc_resource_quota grpc_resource_quota;

@ -144,6 +144,8 @@ typedef struct client_channel_channel_data {
/** currently active load balancer */
char *lb_policy_name;
grpc_lb_policy *lb_policy;
/** service config in JSON form */
char *service_config_json;
/** maps method names to method_parameters structs */
grpc_mdstr_hash_table *method_params_table;
/** incoming resolver result - set by resolver.next() */
@ -250,6 +252,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
bool exit_idle = false;
grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy");
char *service_config_json = NULL;
if (chand->resolver_result != NULL) {
// Find LB policy name.
@ -305,8 +308,9 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVICE_CONFIG);
if (channel_arg != NULL) {
GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
service_config_json = gpr_strdup(channel_arg->value.string);
grpc_service_config *service_config =
grpc_service_config_create(channel_arg->value.string);
grpc_service_config_create(service_config_json);
if (service_config != NULL) {
method_params_table = grpc_service_config_create_method_config_table(
service_config, method_parameters_create_from_json,
@ -334,6 +338,10 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
}
old_lb_policy = chand->lb_policy;
chand->lb_policy = lb_policy;
if (service_config_json != NULL) {
gpr_free(chand->service_config_json);
chand->service_config_json = service_config_json;
}
if (chand->method_params_table != NULL) {
grpc_mdstr_hash_table_unref(chand->method_params_table);
}
@ -469,6 +477,11 @@ static void cc_get_channel_info(grpc_exec_ctx *exec_ctx,
? NULL
: gpr_strdup(chand->lb_policy_name);
}
if (info->service_config_json != NULL) {
*info->service_config_json = chand->service_config_json == NULL
? NULL
: gpr_strdup(chand->service_config_json);
}
gpr_mu_unlock(&chand->mu);
}
@ -512,6 +525,7 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
}
gpr_free(chand->lb_policy_name);
gpr_free(chand->service_config_json);
if (chand->method_params_table != NULL) {
grpc_mdstr_hash_table_unref(chand->method_params_table);
}

@ -43,6 +43,7 @@
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/client_channel/lb_policy_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/channel.h"
@ -642,21 +643,43 @@ static void test_pending_calls(size_t concurrent_calls) {
}
static void test_get_channel_info() {
grpc_channel *channel = grpc_insecure_channel_create(
"test:127.0.0.1:1234?lb_policy=round_robin", NULL, NULL);
grpc_channel *channel =
grpc_insecure_channel_create("ipv4:127.0.0.1:1234", NULL, NULL);
// Ensures that resolver returns.
grpc_channel_check_connectivity_state(channel, true /* try_to_connect */);
// Use grpc_channel_get_info() to get LB policy name.
char *lb_policy_name = NULL;
// First, request no fields. This is a no-op.
grpc_channel_info channel_info;
memset(&channel_info, 0, sizeof(channel_info));
grpc_channel_get_info(channel, &channel_info);
// Request LB policy name.
char *lb_policy_name = NULL;
channel_info.lb_policy_name = &lb_policy_name;
grpc_channel_get_info(channel, &channel_info);
GPR_ASSERT(lb_policy_name != NULL);
GPR_ASSERT(strcmp(lb_policy_name, "round_robin") == 0);
GPR_ASSERT(strcmp(lb_policy_name, "pick_first") == 0);
gpr_free(lb_policy_name);
// Try again without requesting anything. This is a no-op.
channel_info.lb_policy_name = NULL;
// Request service config, which does not exist, so we'll get nothing back.
memset(&channel_info, 0, sizeof(channel_info));
char *service_config_json = "dummy_string";
channel_info.service_config_json = &service_config_json;
grpc_channel_get_info(channel, &channel_info);
GPR_ASSERT(service_config_json == NULL);
// Recreate the channel such that it has a service config.
grpc_channel_destroy(channel);
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVICE_CONFIG;
arg.value.string = "{\"lb_policy_name\": \"round_robin\"}";
grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
channel = grpc_insecure_channel_create("ipv4:127.0.0.1:1234", args, NULL);
grpc_channel_args_destroy(args);
// Ensures that resolver returns.
grpc_channel_check_connectivity_state(channel, true /* try_to_connect */);
// Now request the service config again.
grpc_channel_get_info(channel, &channel_info);
GPR_ASSERT(service_config_json != NULL);
GPR_ASSERT(strcmp(service_config_json, arg.value.string) == 0);
gpr_free(service_config_json);
// Clean up.
grpc_channel_destroy(channel);
}

Loading…
Cancel
Save