Merge pull request #20347 from yang-g/socket_mutator

Global channel args mutator when creating a client channel
pull/20358/head
Yang Gao 5 years ago committed by GitHub
commit 26dceb6c92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      src/core/lib/channel/channel_args.cc
  2. 14
      src/core/lib/channel/channel_args.h
  3. 7
      src/core/lib/surface/channel.cc
  4. 127
      test/core/channel/channel_args_test.cc

@ -22,6 +22,8 @@
#include <string.h>
#include <grpc/grpc.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/log.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@ -361,3 +363,17 @@ char* grpc_channel_args_string(const grpc_channel_args* args) {
gpr_strvec_destroy(&v);
return result;
}
namespace {
grpc_channel_args_client_channel_creation_mutator g_mutator = nullptr;
} // namespace
void grpc_channel_args_set_client_channel_creation_mutator(
grpc_channel_args_client_channel_creation_mutator cb) {
GPR_DEBUG_ASSERT(g_mutator == nullptr);
g_mutator = cb;
}
grpc_channel_args_client_channel_creation_mutator
grpc_channel_args_get_client_channel_creation_mutator() {
return g_mutator;
}

@ -23,6 +23,8 @@
#include <grpc/grpc.h>
#include "src/core/lib/surface/channel_stack_type.h"
// Channel args are intentionally immutable, to avoid the need for locking.
/** Copy the arguments in \a src into a new instance */
@ -108,4 +110,16 @@ grpc_arg grpc_channel_arg_pointer_create(char* name, void* value,
// Callers takes ownership of result.
char* grpc_channel_args_string(const grpc_channel_args* args);
// Takes ownership of the old_args
typedef grpc_channel_args* (*grpc_channel_args_client_channel_creation_mutator)(
const char* target, grpc_channel_args* old_args,
grpc_channel_stack_type type);
// Should be called only once globaly before grpc is init'ed.
void grpc_channel_args_set_client_channel_creation_mutator(
grpc_channel_args_client_channel_creation_mutator cb);
// This will be called at the creation of each channel.
grpc_channel_args_client_channel_creation_mutator
grpc_channel_args_get_client_channel_creation_mutator();
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */

@ -257,6 +257,13 @@ grpc_channel* grpc_channel_create(const char* target,
get_default_authority(input_args);
grpc_channel_args* args =
build_channel_args(input_args, default_authority.get());
if (grpc_channel_stack_type_is_client(channel_stack_type)) {
auto channel_args_mutator =
grpc_channel_args_get_client_channel_creation_mutator();
if (channel_args_mutator != nullptr) {
args = channel_args_mutator(target, args, channel_stack_type);
}
}
grpc_channel_stack_builder_set_channel_arguments(builder, args);
grpc_channel_args_destroy(args);
grpc_channel_stack_builder_set_target(builder, target);

@ -16,43 +16,38 @@
*
*/
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/log.h>
#include <string.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/surface/channel.h"
#include "test/core/util/test_config.h"
static void test_create(void) {
grpc_core::ExecCtx exec_ctx;
grpc_arg arg_int;
grpc_arg arg_string;
grpc_arg to_add[2];
grpc_channel_args* ch_args;
arg_int.key = const_cast<char*>("int_arg");
arg_int.type = GRPC_ARG_INTEGER;
arg_int.value.integer = 123;
arg_string.key = const_cast<char*>("str key");
arg_string.type = GRPC_ARG_STRING;
arg_string.value.string = const_cast<char*>("str value");
to_add[0] = arg_int;
to_add[1] = arg_string;
to_add[0] =
grpc_channel_arg_integer_create(const_cast<char*>("int_arg"), 123);
to_add[1] = grpc_channel_arg_string_create(const_cast<char*>("str key"),
const_cast<char*>("str value"));
ch_args = grpc_channel_args_copy_and_add(nullptr, to_add, 2);
GPR_ASSERT(ch_args->num_args == 2);
GPR_ASSERT(strcmp(ch_args->args[0].key, arg_int.key) == 0);
GPR_ASSERT(ch_args->args[0].type == arg_int.type);
GPR_ASSERT(ch_args->args[0].value.integer == arg_int.value.integer);
GPR_ASSERT(strcmp(ch_args->args[0].key, to_add[0].key) == 0);
GPR_ASSERT(ch_args->args[0].type == to_add[0].type);
GPR_ASSERT(ch_args->args[0].value.integer == to_add[0].value.integer);
GPR_ASSERT(strcmp(ch_args->args[1].key, arg_string.key) == 0);
GPR_ASSERT(ch_args->args[1].type == arg_string.type);
GPR_ASSERT(strcmp(ch_args->args[1].value.string, arg_string.value.string) ==
GPR_ASSERT(strcmp(ch_args->args[1].key, to_add[1].key) == 0);
GPR_ASSERT(ch_args->args[1].type == to_add[1].type);
GPR_ASSERT(strcmp(ch_args->args[1].value.string, to_add[1].value.string) ==
0);
grpc_channel_args_destroy(ch_args);
@ -84,23 +79,15 @@ static const grpc_arg_pointer_vtable fake_pointer_arg_vtable = {
static void test_channel_create_with_args(void) {
grpc_arg client_a[3];
// adds integer arg
client_a[0].type = GRPC_ARG_INTEGER;
client_a[0].key = const_cast<char*>("arg_int");
client_a[0].value.integer = 0;
// adds const str arg
client_a[1].type = GRPC_ARG_STRING;
client_a[1].key = const_cast<char*>("arg_str");
client_a[1].value.string = const_cast<char*>("arg_str_val");
client_a[0] =
grpc_channel_arg_integer_create(const_cast<char*>("arg_int"), 0);
client_a[1] = grpc_channel_arg_string_create(
const_cast<char*>("arg_str"), const_cast<char*>("arg_str_val"));
// allocated and adds custom pointer arg
fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
fc->foo = 42;
client_a[2].type = GRPC_ARG_POINTER;
client_a[2].key = const_cast<char*>("arg_pointer");
client_a[2].value.pointer.vtable = &fake_pointer_arg_vtable;
client_a[2].value.pointer.p = fc;
client_a[2] = grpc_channel_arg_pointer_create(
const_cast<char*>("arg_pointer"), fc, &fake_pointer_arg_vtable);
// creates channel
grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
@ -111,6 +98,78 @@ static void test_channel_create_with_args(void) {
grpc_channel_destroy(c);
}
grpc_channel_args* mutate_channel_args(const char* target,
grpc_channel_args* old_args,
grpc_channel_stack_type type) {
GPR_ASSERT(old_args != nullptr);
GPR_ASSERT(grpc_channel_args_find(old_args, "arg_int")->value.integer == 0);
GPR_ASSERT(strcmp(grpc_channel_args_find(old_args, "arg_str")->value.string,
"arg_str_val") == 0);
GPR_ASSERT(
grpc_channel_args_find(old_args, "arg_pointer")->value.pointer.vtable ==
&fake_pointer_arg_vtable);
if (strcmp(target, "no_op_mutator") == 0) {
return old_args;
}
GPR_ASSERT(strcmp(target, "minimal_stack_mutator") == 0);
const char* args_to_remove[] = {"arg_int", "arg_str", "arg_pointer"};
grpc_arg no_deadline_filter_arg = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MINIMAL_STACK), 1);
grpc_channel_args* new_args = nullptr;
new_args = grpc_channel_args_copy_and_add_and_remove(
old_args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove),
&no_deadline_filter_arg, 1);
grpc_channel_args_destroy(old_args);
return new_args;
}
// Minimal stack should not have client_idle filter
static bool channel_has_client_idle_filter(grpc_channel* c) {
grpc_channel_stack* stack = grpc_channel_get_channel_stack(c);
for (size_t i = 0; i < stack->count; i++) {
if (strcmp(grpc_channel_stack_element(stack, i)->filter->name,
"client_idle") == 0) {
return true;
}
}
return false;
}
static void test_channel_create_with_global_mutator(void) {
grpc_channel_args_set_client_channel_creation_mutator(mutate_channel_args);
// We also add some custom args to make sure the ownership is correct.
grpc_arg client_a[3];
client_a[0] =
grpc_channel_arg_integer_create(const_cast<char*>("arg_int"), 0);
client_a[1] = grpc_channel_arg_string_create(
const_cast<char*>("arg_str"), const_cast<char*>("arg_str_val"));
// allocated and adds custom pointer arg
fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
fc->foo = 42;
client_a[2] = grpc_channel_arg_pointer_create(
const_cast<char*>("arg_pointer"), fc, &fake_pointer_arg_vtable);
// creates channels
grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
grpc_channel* c =
grpc_insecure_channel_create("no_op_mutator", &client_args, nullptr);
GPR_ASSERT(channel_has_client_idle_filter(c));
grpc_channel_destroy(c);
c = grpc_insecure_channel_create("minimal_stack_mutator", &client_args,
nullptr);
GPR_ASSERT(channel_has_client_idle_filter(c) == false);
grpc_channel_destroy(c);
gpr_free(fc);
auto mutator = grpc_channel_args_get_client_channel_creation_mutator();
GPR_ASSERT(mutator == &mutate_channel_args);
}
static void test_server_create_with_args(void) {
grpc_arg server_a[3];
@ -146,6 +205,8 @@ int main(int argc, char** argv) {
test_create();
test_channel_create_with_args();
test_server_create_with_args();
// This has to be the last test.
test_channel_create_with_global_mutator();
grpc_shutdown();
return 0;
}

Loading…
Cancel
Save