Merge github.com:grpc/grpc into cleaner-posix3
This commit is contained in:
commit
0ea9fceb24
12
BUILD
12
BUILD
|
|
@ -198,6 +198,7 @@ cc_library(
|
|||
"src/core/lib/channel/http_client_filter.h",
|
||||
"src/core/lib/channel/http_server_filter.h",
|
||||
"src/core/lib/channel/subchannel_call_holder.h",
|
||||
"src/core/lib/client_config/client_channel_factory.h",
|
||||
"src/core/lib/client_config/client_config.h",
|
||||
"src/core/lib/client_config/connector.h",
|
||||
"src/core/lib/client_config/initial_connect_string.h",
|
||||
|
|
@ -208,7 +209,6 @@ cc_library(
|
|||
"src/core/lib/client_config/resolver_factory.h",
|
||||
"src/core/lib/client_config/resolver_registry.h",
|
||||
"src/core/lib/client_config/subchannel.h",
|
||||
"src/core/lib/client_config/subchannel_factory.h",
|
||||
"src/core/lib/client_config/subchannel_index.h",
|
||||
"src/core/lib/client_config/uri_parser.h",
|
||||
"src/core/lib/compression/algorithm_metadata.h",
|
||||
|
|
@ -340,6 +340,7 @@ cc_library(
|
|||
"src/core/lib/channel/http_client_filter.c",
|
||||
"src/core/lib/channel/http_server_filter.c",
|
||||
"src/core/lib/channel/subchannel_call_holder.c",
|
||||
"src/core/lib/client_config/client_channel_factory.c",
|
||||
"src/core/lib/client_config/client_config.c",
|
||||
"src/core/lib/client_config/connector.c",
|
||||
"src/core/lib/client_config/default_initial_connect_string.c",
|
||||
|
|
@ -351,7 +352,6 @@ cc_library(
|
|||
"src/core/lib/client_config/resolver_factory.c",
|
||||
"src/core/lib/client_config/resolver_registry.c",
|
||||
"src/core/lib/client_config/subchannel.c",
|
||||
"src/core/lib/client_config/subchannel_factory.c",
|
||||
"src/core/lib/client_config/subchannel_index.c",
|
||||
"src/core/lib/client_config/uri_parser.c",
|
||||
"src/core/lib/compression/compression_algorithm.c",
|
||||
|
|
@ -563,6 +563,7 @@ cc_library(
|
|||
"src/core/lib/channel/http_client_filter.h",
|
||||
"src/core/lib/channel/http_server_filter.h",
|
||||
"src/core/lib/channel/subchannel_call_holder.h",
|
||||
"src/core/lib/client_config/client_channel_factory.h",
|
||||
"src/core/lib/client_config/client_config.h",
|
||||
"src/core/lib/client_config/connector.h",
|
||||
"src/core/lib/client_config/initial_connect_string.h",
|
||||
|
|
@ -573,7 +574,6 @@ cc_library(
|
|||
"src/core/lib/client_config/resolver_factory.h",
|
||||
"src/core/lib/client_config/resolver_registry.h",
|
||||
"src/core/lib/client_config/subchannel.h",
|
||||
"src/core/lib/client_config/subchannel_factory.h",
|
||||
"src/core/lib/client_config/subchannel_index.h",
|
||||
"src/core/lib/client_config/uri_parser.h",
|
||||
"src/core/lib/compression/algorithm_metadata.h",
|
||||
|
|
@ -689,6 +689,7 @@ cc_library(
|
|||
"src/core/lib/channel/http_client_filter.c",
|
||||
"src/core/lib/channel/http_server_filter.c",
|
||||
"src/core/lib/channel/subchannel_call_holder.c",
|
||||
"src/core/lib/client_config/client_channel_factory.c",
|
||||
"src/core/lib/client_config/client_config.c",
|
||||
"src/core/lib/client_config/connector.c",
|
||||
"src/core/lib/client_config/default_initial_connect_string.c",
|
||||
|
|
@ -700,7 +701,6 @@ cc_library(
|
|||
"src/core/lib/client_config/resolver_factory.c",
|
||||
"src/core/lib/client_config/resolver_registry.c",
|
||||
"src/core/lib/client_config/subchannel.c",
|
||||
"src/core/lib/client_config/subchannel_factory.c",
|
||||
"src/core/lib/client_config/subchannel_index.c",
|
||||
"src/core/lib/client_config/uri_parser.c",
|
||||
"src/core/lib/compression/compression_algorithm.c",
|
||||
|
|
@ -1397,6 +1397,7 @@ objc_library(
|
|||
"src/core/lib/channel/http_client_filter.c",
|
||||
"src/core/lib/channel/http_server_filter.c",
|
||||
"src/core/lib/channel/subchannel_call_holder.c",
|
||||
"src/core/lib/client_config/client_channel_factory.c",
|
||||
"src/core/lib/client_config/client_config.c",
|
||||
"src/core/lib/client_config/connector.c",
|
||||
"src/core/lib/client_config/default_initial_connect_string.c",
|
||||
|
|
@ -1408,7 +1409,6 @@ objc_library(
|
|||
"src/core/lib/client_config/resolver_factory.c",
|
||||
"src/core/lib/client_config/resolver_registry.c",
|
||||
"src/core/lib/client_config/subchannel.c",
|
||||
"src/core/lib/client_config/subchannel_factory.c",
|
||||
"src/core/lib/client_config/subchannel_index.c",
|
||||
"src/core/lib/client_config/uri_parser.c",
|
||||
"src/core/lib/compression/compression_algorithm.c",
|
||||
|
|
@ -1562,6 +1562,7 @@ objc_library(
|
|||
"src/core/lib/channel/http_client_filter.h",
|
||||
"src/core/lib/channel/http_server_filter.h",
|
||||
"src/core/lib/channel/subchannel_call_holder.h",
|
||||
"src/core/lib/client_config/client_channel_factory.h",
|
||||
"src/core/lib/client_config/client_config.h",
|
||||
"src/core/lib/client_config/connector.h",
|
||||
"src/core/lib/client_config/initial_connect_string.h",
|
||||
|
|
@ -1572,7 +1573,6 @@ objc_library(
|
|||
"src/core/lib/client_config/resolver_factory.h",
|
||||
"src/core/lib/client_config/resolver_registry.h",
|
||||
"src/core/lib/client_config/subchannel.h",
|
||||
"src/core/lib/client_config/subchannel_factory.h",
|
||||
"src/core/lib/client_config/subchannel_index.h",
|
||||
"src/core/lib/client_config/uri_parser.h",
|
||||
"src/core/lib/compression/algorithm_metadata.h",
|
||||
|
|
|
|||
162
Makefile
162
Makefile
|
|
@ -961,6 +961,8 @@ message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
|
|||
mlog_test: $(BINDIR)/$(CONFIG)/mlog_test
|
||||
multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test
|
||||
murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test
|
||||
nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test
|
||||
nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test
|
||||
no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
|
||||
resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test
|
||||
secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test
|
||||
|
|
@ -1076,6 +1078,7 @@ boringssl_pqueue_test: $(BINDIR)/$(CONFIG)/boringssl_pqueue_test
|
|||
boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test
|
||||
badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test
|
||||
connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
|
||||
head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test
|
||||
headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test
|
||||
initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
|
||||
server_registered_method_bad_client_test: $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test
|
||||
|
|
@ -1113,6 +1116,8 @@ h2_uds_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_nosec_test
|
|||
hpack_parser_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry
|
||||
http_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/http_fuzzer_test_one_entry
|
||||
json_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry
|
||||
nanopb_fuzzer_response_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry
|
||||
nanopb_fuzzer_serverlist_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry
|
||||
uri_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry
|
||||
|
||||
run_dep_checks:
|
||||
|
|
@ -1298,6 +1303,7 @@ buildtests_c: privatelibs_c \
|
|||
$(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \
|
||||
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
|
||||
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
|
||||
$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \
|
||||
$(BINDIR)/$(CONFIG)/headers_bad_client_test \
|
||||
$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
|
||||
$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \
|
||||
|
|
@ -1335,6 +1341,8 @@ buildtests_c: privatelibs_c \
|
|||
$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry \
|
||||
$(BINDIR)/$(CONFIG)/http_fuzzer_test_one_entry \
|
||||
$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry \
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry \
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry \
|
||||
$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry \
|
||||
|
||||
|
||||
|
|
@ -1620,6 +1628,8 @@ test_c: buildtests_c
|
|||
$(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing connection_prefix_bad_client_test"
|
||||
$(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing head_of_line_blocking_bad_client_test"
|
||||
$(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing headers_bad_client_test"
|
||||
$(Q) $(BINDIR)/$(CONFIG)/headers_bad_client_test || ( echo test headers_bad_client_test failed ; exit 1 )
|
||||
$(E) "[RUN] Testing initial_settings_frame_bad_client_test"
|
||||
|
|
@ -2487,6 +2497,7 @@ LIBGRPC_SRC = \
|
|||
src/core/lib/channel/http_client_filter.c \
|
||||
src/core/lib/channel/http_server_filter.c \
|
||||
src/core/lib/channel/subchannel_call_holder.c \
|
||||
src/core/lib/client_config/client_channel_factory.c \
|
||||
src/core/lib/client_config/client_config.c \
|
||||
src/core/lib/client_config/connector.c \
|
||||
src/core/lib/client_config/default_initial_connect_string.c \
|
||||
|
|
@ -2498,7 +2509,6 @@ LIBGRPC_SRC = \
|
|||
src/core/lib/client_config/resolver_factory.c \
|
||||
src/core/lib/client_config/resolver_registry.c \
|
||||
src/core/lib/client_config/subchannel.c \
|
||||
src/core/lib/client_config/subchannel_factory.c \
|
||||
src/core/lib/client_config/subchannel_index.c \
|
||||
src/core/lib/client_config/uri_parser.c \
|
||||
src/core/lib/compression/compression_algorithm.c \
|
||||
|
|
@ -2845,6 +2855,7 @@ LIBGRPC_UNSECURE_SRC = \
|
|||
src/core/lib/channel/http_client_filter.c \
|
||||
src/core/lib/channel/http_server_filter.c \
|
||||
src/core/lib/channel/subchannel_call_holder.c \
|
||||
src/core/lib/client_config/client_channel_factory.c \
|
||||
src/core/lib/client_config/client_config.c \
|
||||
src/core/lib/client_config/connector.c \
|
||||
src/core/lib/client_config/default_initial_connect_string.c \
|
||||
|
|
@ -2856,7 +2867,6 @@ LIBGRPC_UNSECURE_SRC = \
|
|||
src/core/lib/client_config/resolver_factory.c \
|
||||
src/core/lib/client_config/resolver_registry.c \
|
||||
src/core/lib/client_config/subchannel.c \
|
||||
src/core/lib/client_config/subchannel_factory.c \
|
||||
src/core/lib/client_config/subchannel_index.c \
|
||||
src/core/lib/client_config/uri_parser.c \
|
||||
src/core/lib/compression/compression_algorithm.c \
|
||||
|
|
@ -8661,6 +8671,70 @@ endif
|
|||
endif
|
||||
|
||||
|
||||
NANOPB_FUZZER_RESPONSE_TEST_SRC = \
|
||||
test/core/nanopb/fuzzer_response.c \
|
||||
|
||||
NANOPB_FUZZER_RESPONSE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(NANOPB_FUZZER_RESPONSE_TEST_SRC))))
|
||||
ifeq ($(NO_SECURE),true)
|
||||
|
||||
# You can't build secure targets if you don't have OpenSSL.
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: openssl_dep_error
|
||||
|
||||
else
|
||||
|
||||
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
$(E) "[LD] Linking $@"
|
||||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test
|
||||
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
deps_nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS:.o=.dep)
|
||||
|
||||
ifneq ($(NO_SECURE),true)
|
||||
ifneq ($(NO_DEPS),true)
|
||||
-include $(NANOPB_FUZZER_RESPONSE_TEST_OBJS:.o=.dep)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
NANOPB_FUZZER_SERVERLIST_TEST_SRC = \
|
||||
test/core/nanopb/fuzzer_serverlist.c \
|
||||
|
||||
NANOPB_FUZZER_SERVERLIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(NANOPB_FUZZER_SERVERLIST_TEST_SRC))))
|
||||
ifeq ($(NO_SECURE),true)
|
||||
|
||||
# You can't build secure targets if you don't have OpenSSL.
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: openssl_dep_error
|
||||
|
||||
else
|
||||
|
||||
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
$(E) "[LD] Linking $@"
|
||||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test
|
||||
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
deps_nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS:.o=.dep)
|
||||
|
||||
ifneq ($(NO_SECURE),true)
|
||||
ifneq ($(NO_DEPS),true)
|
||||
-include $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS:.o=.dep)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
NO_SERVER_TEST_SRC = \
|
||||
test/core/end2end/no_server_test.c \
|
||||
|
||||
|
|
@ -12678,6 +12752,26 @@ ifneq ($(NO_DEPS),true)
|
|||
endif
|
||||
|
||||
|
||||
HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \
|
||||
test/core/bad_client/tests/head_of_line_blocking.c \
|
||||
|
||||
HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC))))
|
||||
|
||||
|
||||
$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
$(E) "[LD] Linking $@"
|
||||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
deps_head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS:.o=.dep)
|
||||
|
||||
ifneq ($(NO_DEPS),true)
|
||||
-include $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS:.o=.dep)
|
||||
endif
|
||||
|
||||
|
||||
HEADERS_BAD_CLIENT_TEST_SRC = \
|
||||
test/core/bad_client/tests/headers.c \
|
||||
|
||||
|
|
@ -13670,6 +13764,70 @@ endif
|
|||
endif
|
||||
|
||||
|
||||
NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_SRC = \
|
||||
test/core/nanopb/fuzzer_response.c \
|
||||
|
||||
NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_SRC))))
|
||||
ifeq ($(NO_SECURE),true)
|
||||
|
||||
# You can't build secure targets if you don't have OpenSSL.
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: openssl_dep_error
|
||||
|
||||
else
|
||||
|
||||
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libone_input_fuzzer.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
$(E) "[LD] Linking $@"
|
||||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libone_input_fuzzer.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry
|
||||
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libone_input_fuzzer.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
deps_nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS:.o=.dep)
|
||||
|
||||
ifneq ($(NO_SECURE),true)
|
||||
ifneq ($(NO_DEPS),true)
|
||||
-include $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS:.o=.dep)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_SRC = \
|
||||
test/core/nanopb/fuzzer_serverlist.c \
|
||||
|
||||
NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_SRC))))
|
||||
ifeq ($(NO_SECURE),true)
|
||||
|
||||
# You can't build secure targets if you don't have OpenSSL.
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: openssl_dep_error
|
||||
|
||||
else
|
||||
|
||||
|
||||
|
||||
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libone_input_fuzzer.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
$(E) "[LD] Linking $@"
|
||||
$(Q) mkdir -p `dirname $@`
|
||||
$(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libone_input_fuzzer.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry
|
||||
|
||||
endif
|
||||
|
||||
$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libone_input_fuzzer.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
|
||||
|
||||
deps_nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS:.o=.dep)
|
||||
|
||||
ifneq ($(NO_SECURE),true)
|
||||
ifneq ($(NO_DEPS),true)
|
||||
-include $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS:.o=.dep)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
URI_FUZZER_TEST_ONE_ENTRY_SRC = \
|
||||
test/core/client_config/uri_fuzzer_test.c \
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
[](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Copyright 2015-2016 Google Inc.
|
||||
Copyright 2015 Google Inc.
|
||||
|
||||
#Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -607,6 +607,7 @@
|
|||
'src/core/lib/channel/http_client_filter.c',
|
||||
'src/core/lib/channel/http_server_filter.c',
|
||||
'src/core/lib/channel/subchannel_call_holder.c',
|
||||
'src/core/lib/client_config/client_channel_factory.c',
|
||||
'src/core/lib/client_config/client_config.c',
|
||||
'src/core/lib/client_config/connector.c',
|
||||
'src/core/lib/client_config/default_initial_connect_string.c',
|
||||
|
|
@ -618,7 +619,6 @@
|
|||
'src/core/lib/client_config/resolver_factory.c',
|
||||
'src/core/lib/client_config/resolver_registry.c',
|
||||
'src/core/lib/client_config/subchannel.c',
|
||||
'src/core/lib/client_config/subchannel_factory.c',
|
||||
'src/core/lib/client_config/subchannel_index.c',
|
||||
'src/core/lib/client_config/uri_parser.c',
|
||||
'src/core/lib/compression/compression_algorithm.c',
|
||||
|
|
|
|||
28
build.yaml
28
build.yaml
|
|
@ -264,6 +264,7 @@ filegroups:
|
|||
- src/core/lib/channel/http_client_filter.h
|
||||
- src/core/lib/channel/http_server_filter.h
|
||||
- src/core/lib/channel/subchannel_call_holder.h
|
||||
- src/core/lib/client_config/client_channel_factory.h
|
||||
- src/core/lib/client_config/client_config.h
|
||||
- src/core/lib/client_config/connector.h
|
||||
- src/core/lib/client_config/initial_connect_string.h
|
||||
|
|
@ -274,7 +275,6 @@ filegroups:
|
|||
- src/core/lib/client_config/resolver_factory.h
|
||||
- src/core/lib/client_config/resolver_registry.h
|
||||
- src/core/lib/client_config/subchannel.h
|
||||
- src/core/lib/client_config/subchannel_factory.h
|
||||
- src/core/lib/client_config/subchannel_index.h
|
||||
- src/core/lib/client_config/uri_parser.h
|
||||
- src/core/lib/compression/algorithm_metadata.h
|
||||
|
|
@ -353,6 +353,7 @@ filegroups:
|
|||
- src/core/lib/channel/http_client_filter.c
|
||||
- src/core/lib/channel/http_server_filter.c
|
||||
- src/core/lib/channel/subchannel_call_holder.c
|
||||
- src/core/lib/client_config/client_channel_factory.c
|
||||
- src/core/lib/client_config/client_config.c
|
||||
- src/core/lib/client_config/connector.c
|
||||
- src/core/lib/client_config/default_initial_connect_string.c
|
||||
|
|
@ -364,7 +365,6 @@ filegroups:
|
|||
- src/core/lib/client_config/resolver_factory.c
|
||||
- src/core/lib/client_config/resolver_registry.c
|
||||
- src/core/lib/client_config/subchannel.c
|
||||
- src/core/lib/client_config/subchannel_factory.c
|
||||
- src/core/lib/client_config/subchannel_index.c
|
||||
- src/core/lib/client_config/uri_parser.c
|
||||
- src/core/lib/compression/compression_algorithm.c
|
||||
|
|
@ -1897,6 +1897,30 @@ targets:
|
|||
deps:
|
||||
- gpr_test_util
|
||||
- gpr
|
||||
- name: nanopb_fuzzer_response_test
|
||||
build: fuzzer
|
||||
language: c
|
||||
src:
|
||||
- test/core/nanopb/fuzzer_response.c
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- grpc
|
||||
- gpr_test_util
|
||||
- gpr
|
||||
corpus_dirs:
|
||||
- test/core/nanopb/corpus_response
|
||||
- name: nanopb_fuzzer_serverlist_test
|
||||
build: fuzzer
|
||||
language: c
|
||||
src:
|
||||
- test/core/nanopb/fuzzer_serverlist.c
|
||||
deps:
|
||||
- grpc_test_util
|
||||
- grpc
|
||||
- gpr_test_util
|
||||
- gpr
|
||||
corpus_dirs:
|
||||
- test/core/nanopb/corpus_serverlist
|
||||
- name: no_server_test
|
||||
cpu_cost: 0.1
|
||||
build: test
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ if test "$PHP_GRPC" != "no"; then
|
|||
src/core/lib/channel/http_client_filter.c \
|
||||
src/core/lib/channel/http_server_filter.c \
|
||||
src/core/lib/channel/subchannel_call_holder.c \
|
||||
src/core/lib/client_config/client_channel_factory.c \
|
||||
src/core/lib/client_config/client_config.c \
|
||||
src/core/lib/client_config/connector.c \
|
||||
src/core/lib/client_config/default_initial_connect_string.c \
|
||||
|
|
@ -140,7 +141,6 @@ if test "$PHP_GRPC" != "no"; then
|
|||
src/core/lib/client_config/resolver_factory.c \
|
||||
src/core/lib/client_config/resolver_registry.c \
|
||||
src/core/lib/client_config/subchannel.c \
|
||||
src/core/lib/client_config/subchannel_factory.c \
|
||||
src/core/lib/client_config/subchannel_index.c \
|
||||
src/core/lib/client_config/uri_parser.c \
|
||||
src/core/lib/compression/compression_algorithm.c \
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/channel/http_client_filter.h',
|
||||
'src/core/lib/channel/http_server_filter.h',
|
||||
'src/core/lib/channel/subchannel_call_holder.h',
|
||||
'src/core/lib/client_config/client_channel_factory.h',
|
||||
'src/core/lib/client_config/client_config.h',
|
||||
'src/core/lib/client_config/connector.h',
|
||||
'src/core/lib/client_config/initial_connect_string.h',
|
||||
|
|
@ -210,7 +211,6 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/client_config/resolver_factory.h',
|
||||
'src/core/lib/client_config/resolver_registry.h',
|
||||
'src/core/lib/client_config/subchannel.h',
|
||||
'src/core/lib/client_config/subchannel_factory.h',
|
||||
'src/core/lib/client_config/subchannel_index.h',
|
||||
'src/core/lib/client_config/uri_parser.h',
|
||||
'src/core/lib/compression/algorithm_metadata.h',
|
||||
|
|
@ -359,6 +359,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/channel/http_client_filter.c',
|
||||
'src/core/lib/channel/http_server_filter.c',
|
||||
'src/core/lib/channel/subchannel_call_holder.c',
|
||||
'src/core/lib/client_config/client_channel_factory.c',
|
||||
'src/core/lib/client_config/client_config.c',
|
||||
'src/core/lib/client_config/connector.c',
|
||||
'src/core/lib/client_config/default_initial_connect_string.c',
|
||||
|
|
@ -370,7 +371,6 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/client_config/resolver_factory.c',
|
||||
'src/core/lib/client_config/resolver_registry.c',
|
||||
'src/core/lib/client_config/subchannel.c',
|
||||
'src/core/lib/client_config/subchannel_factory.c',
|
||||
'src/core/lib/client_config/subchannel_index.c',
|
||||
'src/core/lib/client_config/uri_parser.c',
|
||||
'src/core/lib/compression/compression_algorithm.c',
|
||||
|
|
@ -525,6 +525,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/channel/http_client_filter.h',
|
||||
'src/core/lib/channel/http_server_filter.h',
|
||||
'src/core/lib/channel/subchannel_call_holder.h',
|
||||
'src/core/lib/client_config/client_channel_factory.h',
|
||||
'src/core/lib/client_config/client_config.h',
|
||||
'src/core/lib/client_config/connector.h',
|
||||
'src/core/lib/client_config/initial_connect_string.h',
|
||||
|
|
@ -535,7 +536,6 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/client_config/resolver_factory.h',
|
||||
'src/core/lib/client_config/resolver_registry.h',
|
||||
'src/core/lib/client_config/subchannel.h',
|
||||
'src/core/lib/client_config/subchannel_factory.h',
|
||||
'src/core/lib/client_config/subchannel_index.h',
|
||||
'src/core/lib/client_config/uri_parser.h',
|
||||
'src/core/lib/compression/algorithm_metadata.h',
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ Gem::Specification.new do |s|
|
|||
s.files += %w( src/core/lib/channel/http_client_filter.h )
|
||||
s.files += %w( src/core/lib/channel/http_server_filter.h )
|
||||
s.files += %w( src/core/lib/channel/subchannel_call_holder.h )
|
||||
s.files += %w( src/core/lib/client_config/client_channel_factory.h )
|
||||
s.files += %w( src/core/lib/client_config/client_config.h )
|
||||
s.files += %w( src/core/lib/client_config/connector.h )
|
||||
s.files += %w( src/core/lib/client_config/initial_connect_string.h )
|
||||
|
|
@ -206,7 +207,6 @@ Gem::Specification.new do |s|
|
|||
s.files += %w( src/core/lib/client_config/resolver_factory.h )
|
||||
s.files += %w( src/core/lib/client_config/resolver_registry.h )
|
||||
s.files += %w( src/core/lib/client_config/subchannel.h )
|
||||
s.files += %w( src/core/lib/client_config/subchannel_factory.h )
|
||||
s.files += %w( src/core/lib/client_config/subchannel_index.h )
|
||||
s.files += %w( src/core/lib/client_config/uri_parser.h )
|
||||
s.files += %w( src/core/lib/compression/algorithm_metadata.h )
|
||||
|
|
@ -342,6 +342,7 @@ Gem::Specification.new do |s|
|
|||
s.files += %w( src/core/lib/channel/http_client_filter.c )
|
||||
s.files += %w( src/core/lib/channel/http_server_filter.c )
|
||||
s.files += %w( src/core/lib/channel/subchannel_call_holder.c )
|
||||
s.files += %w( src/core/lib/client_config/client_channel_factory.c )
|
||||
s.files += %w( src/core/lib/client_config/client_config.c )
|
||||
s.files += %w( src/core/lib/client_config/connector.c )
|
||||
s.files += %w( src/core/lib/client_config/default_initial_connect_string.c )
|
||||
|
|
@ -353,7 +354,6 @@ Gem::Specification.new do |s|
|
|||
s.files += %w( src/core/lib/client_config/resolver_factory.c )
|
||||
s.files += %w( src/core/lib/client_config/resolver_registry.c )
|
||||
s.files += %w( src/core/lib/client_config/subchannel.c )
|
||||
s.files += %w( src/core/lib/client_config/subchannel_factory.c )
|
||||
s.files += %w( src/core/lib/client_config/subchannel_index.c )
|
||||
s.files += %w( src/core/lib/client_config/uri_parser.c )
|
||||
s.files += %w( src/core/lib/compression/compression_algorithm.c )
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
|
|||
const W& request, void* tag)
|
||||
: context_(context), call_(channel->CreateCall(method, context, cq)) {
|
||||
init_ops_.set_output_tag(tag);
|
||||
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
|
||||
init_ops_.SendInitialMetadata(context->send_initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
// TODO(ctiller): don't assert
|
||||
GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
|
||||
init_ops_.ClientSendClose();
|
||||
|
|
@ -173,7 +174,8 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
|
|||
finish_ops_.RecvMessage(response);
|
||||
|
||||
init_ops_.set_output_tag(tag);
|
||||
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
|
||||
init_ops_.SendInitialMetadata(context->send_initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
call_.PerformOps(&init_ops_);
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +242,8 @@ class ClientAsyncReaderWriter GRPC_FINAL
|
|||
void* tag)
|
||||
: context_(context), call_(channel->CreateCall(method, context, cq)) {
|
||||
init_ops_.set_output_tag(tag);
|
||||
init_ops_.SendInitialMetadata(context->send_initial_metadata_);
|
||||
init_ops_.SendInitialMetadata(context->send_initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
call_.PerformOps(&init_ops_);
|
||||
}
|
||||
|
||||
|
|
@ -305,7 +308,8 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
|
||||
|
||||
meta_ops_.set_output_tag(tag);
|
||||
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
call_.PerformOps(&meta_ops_);
|
||||
}
|
||||
|
|
@ -319,7 +323,8 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
void Finish(const W& msg, const Status& status, void* tag) {
|
||||
finish_ops_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
// The response is dropped if the status is not OK.
|
||||
|
|
@ -336,7 +341,8 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
GPR_CODEGEN_ASSERT(!status.ok());
|
||||
finish_ops_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
|
||||
|
|
@ -366,7 +372,8 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
|
||||
|
||||
meta_ops_.set_output_tag(tag);
|
||||
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
call_.PerformOps(&meta_ops_);
|
||||
}
|
||||
|
|
@ -374,7 +381,8 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
|
||||
write_ops_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
write_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
// TODO(ctiller): don't assert
|
||||
|
|
@ -385,7 +393,8 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
void Finish(const Status& status, void* tag) {
|
||||
finish_ops_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
|
||||
|
|
@ -415,7 +424,8 @@ class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
|
||||
|
||||
meta_ops_.set_output_tag(tag);
|
||||
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
call_.PerformOps(&meta_ops_);
|
||||
}
|
||||
|
|
@ -429,7 +439,8 @@ class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
void Write(const W& msg, void* tag) GRPC_OVERRIDE {
|
||||
write_ops_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
write_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
// TODO(ctiller): don't assert
|
||||
|
|
@ -440,7 +451,8 @@ class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
|
|||
void Finish(const Status& status, void* tag) {
|
||||
finish_ops_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ class ClientAsyncResponseReader GRPC_FINAL
|
|||
call_(channel->CreateCall(method, context, cq)),
|
||||
collection_(new CallOpSetCollection) {
|
||||
collection_->init_buf_.SetCollection(collection_);
|
||||
collection_->init_buf_.SendInitialMetadata(context->send_initial_metadata_);
|
||||
collection_->init_buf_.SendInitialMetadata(
|
||||
context->send_initial_metadata_, context->initial_metadata_flags());
|
||||
// TODO(ctiller): don't assert
|
||||
GPR_CODEGEN_ASSERT(collection_->init_buf_.SendMessage(request).ok());
|
||||
collection_->init_buf_.ClientSendClose();
|
||||
|
|
@ -122,7 +123,8 @@ class ServerAsyncResponseWriter GRPC_FINAL
|
|||
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
|
||||
|
||||
meta_buf_.set_output_tag(tag);
|
||||
meta_buf_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
meta_buf_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
call_.PerformOps(&meta_buf_);
|
||||
}
|
||||
|
|
@ -130,7 +132,8 @@ class ServerAsyncResponseWriter GRPC_FINAL
|
|||
void Finish(const W& msg, const Status& status, void* tag) {
|
||||
finish_buf_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
// The response is dropped if the status is not OK.
|
||||
|
|
@ -147,7 +150,8 @@ class ServerAsyncResponseWriter GRPC_FINAL
|
|||
GPR_CODEGEN_ASSERT(!status.ok());
|
||||
finish_buf_.set_output_tag(tag);
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
|
||||
|
|
|
|||
|
|
@ -181,8 +181,10 @@ class CallOpSendInitialMetadata {
|
|||
CallOpSendInitialMetadata() : send_(false) {}
|
||||
|
||||
void SendInitialMetadata(
|
||||
const std::multimap<grpc::string, grpc::string>& metadata) {
|
||||
const std::multimap<grpc::string, grpc::string>& metadata,
|
||||
uint32_t flags) {
|
||||
send_ = true;
|
||||
flags_ = flags;
|
||||
initial_metadata_count_ = metadata.size();
|
||||
initial_metadata_ = FillMetadataArray(metadata);
|
||||
}
|
||||
|
|
@ -192,7 +194,7 @@ class CallOpSendInitialMetadata {
|
|||
if (!send_) return;
|
||||
grpc_op* op = &ops[(*nops)++];
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->flags = 0;
|
||||
op->flags = flags_;
|
||||
op->reserved = NULL;
|
||||
op->data.send_initial_metadata.count = initial_metadata_count_;
|
||||
op->data.send_initial_metadata.metadata = initial_metadata_;
|
||||
|
|
@ -204,6 +206,7 @@ class CallOpSendInitialMetadata {
|
|||
}
|
||||
|
||||
bool send_;
|
||||
uint32_t flags_;
|
||||
size_t initial_metadata_count_;
|
||||
grpc_metadata* initial_metadata_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -221,6 +221,12 @@ class ClientContext {
|
|||
deadline_ = deadline_tp.raw_time();
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL: Set this request to be idempotent
|
||||
void set_idempotent(bool idempotent) { idempotent_ = idempotent; }
|
||||
|
||||
/// EXPERIMENTAL: Trigger fail-fast or not on this request
|
||||
void set_fail_fast(bool fail_fast) { fail_fast_ = fail_fast; }
|
||||
|
||||
#ifndef GRPC_CXX0X_NO_CHRONO
|
||||
/// Return the deadline for the client call.
|
||||
std::chrono::system_clock::time_point deadline() {
|
||||
|
|
@ -328,9 +334,16 @@ class ClientContext {
|
|||
grpc_call* call() { return call_; }
|
||||
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
|
||||
|
||||
uint32_t initial_metadata_flags() const {
|
||||
return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
|
||||
(fail_fast_ ? 0 : GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY);
|
||||
}
|
||||
|
||||
grpc::string authority() { return authority_; }
|
||||
|
||||
bool initial_metadata_received_;
|
||||
bool fail_fast_;
|
||||
bool idempotent_;
|
||||
std::shared_ptr<Channel> channel_;
|
||||
grpc::mutex mu_;
|
||||
grpc_call* call_;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@ Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
|
|||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_);
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
ops.RecvInitialMetadata(context);
|
||||
ops.RecvMessage(result);
|
||||
ops.ClientSendClose();
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ class RpcMethodHandler : public MethodHandler {
|
|||
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
|
||||
CallOpServerSendStatus>
|
||||
ops;
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_);
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_,
|
||||
param.server_context->initial_metadata_flags());
|
||||
if (status.ok()) {
|
||||
status = ops.SendMessage(rsp);
|
||||
}
|
||||
|
|
@ -100,7 +101,8 @@ class ClientStreamingHandler : public MethodHandler {
|
|||
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
|
||||
CallOpServerSendStatus>
|
||||
ops;
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_);
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_,
|
||||
param.server_context->initial_metadata_flags());
|
||||
if (status.ok()) {
|
||||
status = ops.SendMessage(rsp);
|
||||
}
|
||||
|
|
@ -138,7 +140,8 @@ class ServerStreamingHandler : public MethodHandler {
|
|||
|
||||
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
|
||||
if (!param.server_context->sent_initial_metadata_) {
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_);
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_,
|
||||
param.server_context->initial_metadata_flags());
|
||||
}
|
||||
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
|
||||
param.call->PerformOps(&ops);
|
||||
|
|
@ -170,7 +173,8 @@ class BidiStreamingHandler : public MethodHandler {
|
|||
|
||||
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
|
||||
if (!param.server_context->sent_initial_metadata_) {
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_);
|
||||
ops.SendInitialMetadata(param.server_context->initial_metadata_,
|
||||
param.server_context->initial_metadata_flags());
|
||||
}
|
||||
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
|
||||
param.call->PerformOps(&ops);
|
||||
|
|
@ -191,7 +195,8 @@ class UnknownMethodHandler : public MethodHandler {
|
|||
static void FillOps(ServerContext* context, T* ops) {
|
||||
Status status(StatusCode::UNIMPLEMENTED, "");
|
||||
if (!context->sent_initial_metadata_) {
|
||||
ops->SendInitialMetadata(context->initial_metadata_);
|
||||
ops->SendInitialMetadata(context->initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
context->sent_initial_metadata_ = true;
|
||||
}
|
||||
ops->ServerSendStatus(context->trailing_metadata_, status);
|
||||
|
|
|
|||
|
|
@ -195,6 +195,8 @@ class ServerContext {
|
|||
|
||||
void set_call(grpc_call* call);
|
||||
|
||||
uint32_t initial_metadata_flags() const { return 0; }
|
||||
|
||||
CompletionOp* completion_op_;
|
||||
bool has_notify_when_done_tag_;
|
||||
void* async_notify_when_done_tag_;
|
||||
|
|
|
|||
|
|
@ -125,7 +125,8 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
|
|||
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
|
||||
CallOpClientSendClose>
|
||||
ops;
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_);
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
// TODO(ctiller): don't assert
|
||||
GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
|
||||
ops.ClientSendClose();
|
||||
|
|
@ -190,7 +191,8 @@ class ClientWriter : public ClientWriterInterface<W> {
|
|||
finish_ops_.RecvMessage(response);
|
||||
|
||||
CallOpSet<CallOpSendInitialMetadata> ops;
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_);
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
call_.PerformOps(&ops);
|
||||
cq_.Pluck(&ops);
|
||||
}
|
||||
|
|
@ -268,7 +270,8 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
|
|||
ClientContext* context)
|
||||
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
|
||||
CallOpSet<CallOpSendInitialMetadata> ops;
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_);
|
||||
ops.SendInitialMetadata(context->send_initial_metadata_,
|
||||
context->initial_metadata_flags());
|
||||
call_.PerformOps(&ops);
|
||||
cq_.Pluck(&ops);
|
||||
}
|
||||
|
|
@ -334,7 +337,8 @@ class ServerReader GRPC_FINAL : public ReaderInterface<R> {
|
|||
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
|
||||
|
||||
CallOpSet<CallOpSendInitialMetadata> ops;
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
call_->PerformOps(&ops);
|
||||
call_->cq()->Pluck(&ops);
|
||||
|
|
@ -361,7 +365,8 @@ class ServerWriter GRPC_FINAL : public WriterInterface<W> {
|
|||
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
|
||||
|
||||
CallOpSet<CallOpSendInitialMetadata> ops;
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
call_->PerformOps(&ops);
|
||||
call_->cq()->Pluck(&ops);
|
||||
|
|
@ -374,7 +379,8 @@ class ServerWriter GRPC_FINAL : public WriterInterface<W> {
|
|||
return false;
|
||||
}
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
call_->PerformOps(&ops);
|
||||
|
|
@ -397,7 +403,8 @@ class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
|
|||
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
|
||||
|
||||
CallOpSet<CallOpSendInitialMetadata> ops;
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
call_->PerformOps(&ops);
|
||||
call_->cq()->Pluck(&ops);
|
||||
|
|
@ -417,7 +424,8 @@ class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
|
|||
return false;
|
||||
}
|
||||
if (!ctx_->sent_initial_metadata_) {
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_);
|
||||
ops.SendInitialMetadata(ctx_->initial_metadata_,
|
||||
ctx_->initial_metadata_flags());
|
||||
ctx_->sent_initial_metadata_ = true;
|
||||
}
|
||||
call_->PerformOps(&ops);
|
||||
|
|
|
|||
|
|
@ -289,6 +289,14 @@ GRPCAPI grpc_call_error grpc_server_request_call(
|
|||
grpc_completion_queue *cq_bound_to_call,
|
||||
grpc_completion_queue *cq_for_notification, void *tag_new);
|
||||
|
||||
/** How to handle payloads for a registered method */
|
||||
typedef enum {
|
||||
/** Don't try to read the payload */
|
||||
GRPC_SRM_PAYLOAD_NONE,
|
||||
/** Read the initial payload as a byte buffer */
|
||||
GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER
|
||||
} grpc_server_register_method_payload_handling;
|
||||
|
||||
/** Registers a method in the server.
|
||||
Methods to this (host, method) pair will not be reported by
|
||||
grpc_server_request_call, but instead be reported by
|
||||
|
|
@ -296,9 +304,10 @@ GRPCAPI grpc_call_error grpc_server_request_call(
|
|||
registered_method (as returned by this function).
|
||||
Must be called before grpc_server_start.
|
||||
Returns NULL on failure. */
|
||||
GRPCAPI void *grpc_server_register_method(grpc_server *server,
|
||||
const char *method, const char *host,
|
||||
uint32_t flags);
|
||||
GRPCAPI void *grpc_server_register_method(
|
||||
grpc_server *server, const char *method, const char *host,
|
||||
grpc_server_register_method_payload_handling payload_handling,
|
||||
uint32_t flags);
|
||||
|
||||
/** Request notification of a new pre-registered call. 'cq_for_notification'
|
||||
must have been registered to the server via
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ typedef struct {
|
|||
/** Secondary user agent: goes at the end of the user-agent metadata
|
||||
sent on each request */
|
||||
#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
|
||||
/** The maximum time between subsequent connection attempts, in ms */
|
||||
#define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms"
|
||||
/* The caller of the secure_channel_create functions may override the target
|
||||
name used for SSL host name checking using this channel argument which is of
|
||||
type GRPC_ARG_STRING. This *should* be used for testing only.
|
||||
|
|
@ -185,7 +187,9 @@ typedef enum grpc_call_error {
|
|||
server */
|
||||
GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE,
|
||||
/** this batch of operations leads to more operations than allowed */
|
||||
GRPC_CALL_ERROR_BATCH_TOO_BIG
|
||||
GRPC_CALL_ERROR_BATCH_TOO_BIG,
|
||||
/** payload type requested is not the type registered */
|
||||
GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH
|
||||
} grpc_call_error;
|
||||
|
||||
/* Write Flags: */
|
||||
|
|
@ -202,8 +206,12 @@ typedef enum grpc_call_error {
|
|||
/* Initial metadata flags */
|
||||
/** Signal that the call is idempotent */
|
||||
#define GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST (0x00000010u)
|
||||
/** Signal that the call should not return UNAVAILABLE before it has started */
|
||||
#define GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY (0x00000020u)
|
||||
/** Mask of all valid flags */
|
||||
#define GRPC_INITIAL_METADATA_USED_MASK GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
|
||||
#define GRPC_INITIAL_METADATA_USED_MASK \
|
||||
(GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST | \
|
||||
GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY)
|
||||
|
||||
/** A single metadata element */
|
||||
typedef struct grpc_metadata {
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@
|
|||
"src/core/lib/channel/http_client_filter.h",
|
||||
"src/core/lib/channel/http_server_filter.h",
|
||||
"src/core/lib/channel/subchannel_call_holder.h",
|
||||
"src/core/lib/client_config/client_channel_factory.h",
|
||||
"src/core/lib/client_config/client_config.h",
|
||||
"src/core/lib/client_config/connector.h",
|
||||
"src/core/lib/client_config/initial_connect_string.h",
|
||||
|
|
@ -149,7 +150,6 @@
|
|||
"src/core/lib/client_config/resolver_factory.h",
|
||||
"src/core/lib/client_config/resolver_registry.h",
|
||||
"src/core/lib/client_config/subchannel.h",
|
||||
"src/core/lib/client_config/subchannel_factory.h",
|
||||
"src/core/lib/client_config/subchannel_index.h",
|
||||
"src/core/lib/client_config/uri_parser.h",
|
||||
"src/core/lib/compression/algorithm_metadata.h",
|
||||
|
|
@ -285,6 +285,7 @@
|
|||
"src/core/lib/channel/http_client_filter.c",
|
||||
"src/core/lib/channel/http_server_filter.c",
|
||||
"src/core/lib/channel/subchannel_call_holder.c",
|
||||
"src/core/lib/client_config/client_channel_factory.c",
|
||||
"src/core/lib/client_config/client_config.c",
|
||||
"src/core/lib/client_config/connector.c",
|
||||
"src/core/lib/client_config/default_initial_connect_string.c",
|
||||
|
|
@ -296,7 +297,6 @@
|
|||
"src/core/lib/client_config/resolver_factory.c",
|
||||
"src/core/lib/client_config/resolver_registry.c",
|
||||
"src/core/lib/client_config/subchannel.c",
|
||||
"src/core/lib/client_config/subchannel_factory.c",
|
||||
"src/core/lib/client_config/subchannel_index.c",
|
||||
"src/core/lib/client_config/uri_parser.c",
|
||||
"src/core/lib/compression/compression_algorithm.c",
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@
|
|||
<file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/subchannel_call_holder.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/client_channel_factory.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/client_config.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/connector.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/initial_connect_string.h" role="src" />
|
||||
|
|
@ -210,7 +211,6 @@
|
|||
<file baseinstalldir="/" name="src/core/lib/client_config/resolver_factory.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/resolver_registry.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/subchannel.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/subchannel_factory.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/subchannel_index.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/uri_parser.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/compression/algorithm_metadata.h" role="src" />
|
||||
|
|
@ -346,6 +346,7 @@
|
|||
<file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/subchannel_call_holder.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/client_channel_factory.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/client_config.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/connector.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/default_initial_connect_string.c" role="src" />
|
||||
|
|
@ -357,7 +358,6 @@
|
|||
<file baseinstalldir="/" name="src/core/lib/client_config/resolver_factory.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/resolver_registry.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/subchannel.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/subchannel_factory.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/subchannel_index.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/client_config/uri_parser.c" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/compression/compression_algorithm.c" role="src" />
|
||||
|
|
|
|||
|
|
@ -81,6 +81,10 @@ std::string GetServerInterfaceName(const ServiceDescriptor* service) {
|
|||
return "I" + service->name();
|
||||
}
|
||||
|
||||
std::string GetServerClassName(const ServiceDescriptor* service) {
|
||||
return service->name() + "Base";
|
||||
}
|
||||
|
||||
std::string GetCSharpMethodType(MethodType method_type) {
|
||||
switch (method_type) {
|
||||
case METHODTYPE_NO_STREAMING:
|
||||
|
|
@ -108,10 +112,14 @@ std::string GetMethodFieldName(const MethodDescriptor *method) {
|
|||
return "__Method_" + method->name();
|
||||
}
|
||||
|
||||
std::string GetMethodRequestParamMaybe(const MethodDescriptor *method) {
|
||||
std::string GetMethodRequestParamMaybe(const MethodDescriptor *method,
|
||||
bool invocation_param=false) {
|
||||
if (method->client_streaming()) {
|
||||
return "";
|
||||
}
|
||||
if (invocation_param) {
|
||||
return "request, ";
|
||||
}
|
||||
return GetClassName(method->input_type()) + " request, ";
|
||||
}
|
||||
|
||||
|
|
@ -242,6 +250,8 @@ void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *se
|
|||
|
||||
void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
|
||||
out->Print("// client interface\n");
|
||||
out->Print("[System.Obsolete(\"Client side interfaced will be removed "
|
||||
"in the next release. Use client class directly.\")]\n");
|
||||
out->Print("public interface $name$\n", "name",
|
||||
GetClientInterfaceName(service));
|
||||
out->Print("{\n");
|
||||
|
|
@ -290,6 +300,8 @@ void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
|
|||
|
||||
void GenerateServerInterface(Printer* out, const ServiceDescriptor *service) {
|
||||
out->Print("// server-side interface\n");
|
||||
out->Print("[System.Obsolete(\"Service implementations should inherit"
|
||||
" from the generated abstract base class instead.\")]\n");
|
||||
out->Print("public interface $name$\n", "name",
|
||||
GetServerInterfaceName(service));
|
||||
out->Print("{\n");
|
||||
|
|
@ -309,21 +321,64 @@ void GenerateServerInterface(Printer* out, const ServiceDescriptor *service) {
|
|||
out->Print("\n");
|
||||
}
|
||||
|
||||
void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
|
||||
out->Print("// server-side abstract class\n");
|
||||
out->Print("public abstract class $name$\n", "name",
|
||||
GetServerClassName(service));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
const MethodDescriptor *method = service->method(i);
|
||||
out->Print(
|
||||
"public virtual $returntype$ $methodname$($request$$response_stream_maybe$, "
|
||||
"ServerCallContext context)\n",
|
||||
"methodname", method->name(), "returntype",
|
||||
GetMethodReturnTypeServer(method), "request",
|
||||
GetMethodRequestParamServer(method), "response_stream_maybe",
|
||||
GetMethodResponseStreamMaybe(method));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
out->Print("throw new RpcException("
|
||||
"new Status(StatusCode.Unimplemented, \"\"));\n");
|
||||
out->Outdent();
|
||||
out->Print("}\n\n");
|
||||
}
|
||||
out->Outdent();
|
||||
out->Print("}\n");
|
||||
out->Print("\n");
|
||||
}
|
||||
|
||||
void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
|
||||
out->Print("// client stub\n");
|
||||
out->Print(
|
||||
"public class $name$ : ClientBase, $interface$\n",
|
||||
"name", GetClientClassName(service), "interface",
|
||||
GetClientInterfaceName(service));
|
||||
"public class $name$ : ClientBase<$name$>, $interface$\n",
|
||||
"name", GetClientClassName(service),
|
||||
"interface", GetClientInterfaceName(service));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
|
||||
// constructors
|
||||
out->Print(
|
||||
"public $name$(Channel channel) : base(channel)\n",
|
||||
"name", GetClientClassName(service));
|
||||
out->Print("public $name$(Channel channel) : base(channel)\n",
|
||||
"name", GetClientClassName(service));
|
||||
out->Print("{\n");
|
||||
out->Print("}\n");
|
||||
out->Print("public $name$(CallInvoker callInvoker) : base(callInvoker)\n",
|
||||
"name", GetClientClassName(service));
|
||||
out->Print("{\n");
|
||||
out->Print("}\n");
|
||||
out->Print("///<summary>Protected parameterless constructor to allow creation"
|
||||
" of test doubles.</summary>\n");
|
||||
out->Print("protected $name$() : base()\n",
|
||||
"name", GetClientClassName(service));
|
||||
out->Print("{\n");
|
||||
out->Print("}\n");
|
||||
out->Print("///<summary>Protected constructor to allow creation of configured"
|
||||
" clients.</summary>\n");
|
||||
out->Print("protected $name$(ClientBaseConfiguration configuration)"
|
||||
" : base(configuration)\n",
|
||||
"name", GetClientClassName(service));
|
||||
out->Print("{\n");
|
||||
out->Print("}\n\n");
|
||||
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
const MethodDescriptor *method = service->method(i);
|
||||
|
|
@ -331,30 +386,26 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
|
|||
|
||||
if (method_type == METHODTYPE_NO_STREAMING) {
|
||||
// unary calls have an extra synchronous stub method
|
||||
out->Print(
|
||||
"public $response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
|
||||
out->Print("public virtual $response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
|
||||
"methodname", method->name(), "request",
|
||||
GetClassName(method->input_type()), "response",
|
||||
GetClassName(method->output_type()));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
out->Print("var call = CreateCall($methodfield$, new CallOptions(headers, deadline, cancellationToken));\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
out->Print("return Calls.BlockingUnaryCall(call, request);\n");
|
||||
out->Print("return $methodname$(request, new CallOptions(headers, deadline, cancellationToken));\n",
|
||||
"methodname", method->name());
|
||||
out->Outdent();
|
||||
out->Print("}\n");
|
||||
|
||||
// overload taking CallOptions as a param
|
||||
out->Print(
|
||||
"public $response$ $methodname$($request$ request, CallOptions options)\n",
|
||||
"methodname", method->name(), "request",
|
||||
GetClassName(method->input_type()), "response",
|
||||
GetClassName(method->output_type()));
|
||||
out->Print("public virtual $response$ $methodname$($request$ request, CallOptions options)\n",
|
||||
"methodname", method->name(), "request",
|
||||
GetClassName(method->input_type()), "response",
|
||||
GetClassName(method->output_type()));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
out->Print("var call = CreateCall($methodfield$, options);\n",
|
||||
out->Print("return CallInvoker.BlockingUnaryCall($methodfield$, null, options, request);\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
out->Print("return Calls.BlockingUnaryCall(call, request);\n");
|
||||
out->Outdent();
|
||||
out->Print("}\n");
|
||||
}
|
||||
|
|
@ -364,57 +415,44 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
|
|||
method_name += "Async"; // prevent name clash with synchronous method.
|
||||
}
|
||||
out->Print(
|
||||
"public $returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
|
||||
"methodname", method_name, "request_maybe",
|
||||
GetMethodRequestParamMaybe(method), "returntype",
|
||||
GetMethodReturnTypeClient(method));
|
||||
"public virtual $returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
|
||||
"methodname", method_name, "request_maybe",
|
||||
GetMethodRequestParamMaybe(method), "returntype",
|
||||
GetMethodReturnTypeClient(method));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
out->Print("var call = CreateCall($methodfield$, new CallOptions(headers, deadline, cancellationToken));\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
switch (GetMethodType(method)) {
|
||||
case METHODTYPE_NO_STREAMING:
|
||||
out->Print("return Calls.AsyncUnaryCall(call, request);\n");
|
||||
break;
|
||||
case METHODTYPE_CLIENT_STREAMING:
|
||||
out->Print("return Calls.AsyncClientStreamingCall(call);\n");
|
||||
break;
|
||||
case METHODTYPE_SERVER_STREAMING:
|
||||
out->Print(
|
||||
"return Calls.AsyncServerStreamingCall(call, request);\n");
|
||||
break;
|
||||
case METHODTYPE_BIDI_STREAMING:
|
||||
out->Print("return Calls.AsyncDuplexStreamingCall(call);\n");
|
||||
break;
|
||||
default:
|
||||
GOOGLE_LOG(FATAL)<< "Can't get here.";
|
||||
}
|
||||
|
||||
out->Print("return $methodname$($request_maybe$new CallOptions(headers, deadline, cancellationToken));\n",
|
||||
"methodname", method_name,
|
||||
"request_maybe", GetMethodRequestParamMaybe(method, true));
|
||||
out->Outdent();
|
||||
out->Print("}\n");
|
||||
|
||||
// overload taking CallOptions as a param
|
||||
out->Print(
|
||||
"public $returntype$ $methodname$($request_maybe$CallOptions options)\n",
|
||||
"public virtual $returntype$ $methodname$($request_maybe$CallOptions options)\n",
|
||||
"methodname", method_name, "request_maybe",
|
||||
GetMethodRequestParamMaybe(method), "returntype",
|
||||
GetMethodReturnTypeClient(method));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
out->Print("var call = CreateCall($methodfield$, options);\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
switch (GetMethodType(method)) {
|
||||
case METHODTYPE_NO_STREAMING:
|
||||
out->Print("return Calls.AsyncUnaryCall(call, request);\n");
|
||||
out->Print("return CallInvoker.AsyncUnaryCall($methodfield$, null, options, request);\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
break;
|
||||
case METHODTYPE_CLIENT_STREAMING:
|
||||
out->Print("return Calls.AsyncClientStreamingCall(call);\n");
|
||||
out->Print("return CallInvoker.AsyncClientStreamingCall($methodfield$, null, options);\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
break;
|
||||
case METHODTYPE_SERVER_STREAMING:
|
||||
out->Print(
|
||||
"return Calls.AsyncServerStreamingCall(call, request);\n");
|
||||
"return CallInvoker.AsyncServerStreamingCall($methodfield$, null, options, request);\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
break;
|
||||
case METHODTYPE_BIDI_STREAMING:
|
||||
out->Print("return Calls.AsyncDuplexStreamingCall(call);\n");
|
||||
out->Print("return CallInvoker.AsyncDuplexStreamingCall($methodfield$, null, options);\n",
|
||||
"methodfield", GetMethodFieldName(method));
|
||||
break;
|
||||
default:
|
||||
GOOGLE_LOG(FATAL)<< "Can't get here.";
|
||||
|
|
@ -422,17 +460,30 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
|
|||
out->Outdent();
|
||||
out->Print("}\n");
|
||||
}
|
||||
|
||||
// override NewInstance method
|
||||
out->Print("protected override $name$ NewInstance(ClientBaseConfiguration configuration)\n",
|
||||
"name", GetClientClassName(service));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
out->Print("return new $name$(configuration);\n",
|
||||
"name", GetClientClassName(service));
|
||||
out->Outdent();
|
||||
out->Print("}\n");
|
||||
|
||||
out->Outdent();
|
||||
out->Print("}\n");
|
||||
out->Print("\n");
|
||||
}
|
||||
|
||||
void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service) {
|
||||
void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service,
|
||||
bool use_server_class) {
|
||||
out->Print(
|
||||
"// creates service definition that can be registered with a server\n");
|
||||
out->Print(
|
||||
"public static ServerServiceDefinition BindService($interface$ serviceImpl)\n",
|
||||
"interface", GetServerInterfaceName(service));
|
||||
"interface", use_server_class ? GetServerClassName(service) :
|
||||
GetServerInterfaceName(service));
|
||||
out->Print("{\n");
|
||||
out->Indent();
|
||||
|
||||
|
|
@ -489,8 +540,10 @@ void GenerateService(Printer* out, const ServiceDescriptor *service) {
|
|||
GenerateServiceDescriptorProperty(out, service);
|
||||
GenerateClientInterface(out, service);
|
||||
GenerateServerInterface(out, service);
|
||||
GenerateServerClass(out, service);
|
||||
GenerateClientStub(out, service);
|
||||
GenerateBindServiceMethod(out, service);
|
||||
GenerateBindServiceMethod(out, service, false);
|
||||
GenerateBindServiceMethod(out, service, true);
|
||||
GenerateNewStubMethods(out, service);
|
||||
|
||||
out->Outdent();
|
||||
|
|
|
|||
|
|
@ -110,13 +110,15 @@ grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) {
|
|||
grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
|
||||
memset(res, 0, sizeof(*res));
|
||||
status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
|
||||
GPR_ASSERT(status == true);
|
||||
if (!status) {
|
||||
grpc_grpclb_response_destroy(res);
|
||||
return NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
|
||||
gpr_slice encoded_response) {
|
||||
grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist));
|
||||
bool status;
|
||||
decode_serverlist_arg arg;
|
||||
pb_istream_t stream =
|
||||
|
|
@ -131,15 +133,20 @@ grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
|
|||
res->server_list.servers.arg = &arg;
|
||||
arg.first_pass = 1;
|
||||
status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
|
||||
GPR_ASSERT(status == true);
|
||||
GPR_ASSERT(arg.num_servers > 0);
|
||||
if (!status) {
|
||||
grpc_grpclb_response_destroy(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arg.first_pass = 0;
|
||||
status =
|
||||
pb_decode(&stream_at_start, grpc_lb_v0_LoadBalanceResponse_fields, res);
|
||||
GPR_ASSERT(status == true);
|
||||
GPR_ASSERT(arg.servers != NULL);
|
||||
if (!status) {
|
||||
grpc_grpclb_response_destroy(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist));
|
||||
sl->num_servers = arg.num_servers;
|
||||
sl->servers = arg.servers;
|
||||
if (res->server_list.has_expiration_interval) {
|
||||
|
|
@ -150,8 +157,10 @@ grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
|
|||
}
|
||||
|
||||
void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) {
|
||||
size_t i;
|
||||
for (i = 0; i < serverlist->num_servers; i++) {
|
||||
if (serverlist == NULL) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < serverlist->num_servers; i++) {
|
||||
gpr_free(serverlist->servers[i]);
|
||||
}
|
||||
gpr_free(serverlist->servers);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
typedef struct pending_pick {
|
||||
struct pending_pick *next;
|
||||
grpc_pollset *pollset;
|
||||
uint32_t initial_metadata_flags;
|
||||
grpc_connected_subchannel **target;
|
||||
grpc_closure *on_complete;
|
||||
} pending_pick;
|
||||
|
|
@ -149,6 +150,31 @@ static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
|||
gpr_mu_unlock(&p->mu);
|
||||
}
|
||||
|
||||
static void pf_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
||||
uint32_t initial_metadata_flags_mask,
|
||||
uint32_t initial_metadata_flags_eq) {
|
||||
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
|
||||
pending_pick *pp;
|
||||
gpr_mu_lock(&p->mu);
|
||||
pp = p->pending_picks;
|
||||
p->pending_picks = NULL;
|
||||
while (pp != NULL) {
|
||||
pending_pick *next = pp->next;
|
||||
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
|
||||
initial_metadata_flags_eq) {
|
||||
grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
|
||||
pp->pollset);
|
||||
grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
|
||||
gpr_free(pp);
|
||||
} else {
|
||||
pp->next = p->pending_picks;
|
||||
p->pending_picks = pp;
|
||||
}
|
||||
pp = next;
|
||||
}
|
||||
gpr_mu_unlock(&p->mu);
|
||||
}
|
||||
|
||||
static void start_picking(grpc_exec_ctx *exec_ctx, pick_first_lb_policy *p) {
|
||||
p->started_picking = 1;
|
||||
p->checking_subchannel = 0;
|
||||
|
|
@ -171,6 +197,7 @@ static void pf_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
|
|||
|
||||
static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
||||
grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **target,
|
||||
grpc_closure *on_complete) {
|
||||
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
|
||||
|
|
@ -199,6 +226,7 @@ static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
|||
pp->next = p->pending_picks;
|
||||
pp->pollset = pollset;
|
||||
pp->target = target;
|
||||
pp->initial_metadata_flags = initial_metadata_flags;
|
||||
pp->on_complete = on_complete;
|
||||
p->pending_picks = pp;
|
||||
gpr_mu_unlock(&p->mu);
|
||||
|
|
@ -286,11 +314,14 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
&p->checking_connectivity, &p->connectivity_changed);
|
||||
break;
|
||||
case GRPC_CHANNEL_TRANSIENT_FAILURE:
|
||||
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
|
||||
GRPC_CHANNEL_TRANSIENT_FAILURE,
|
||||
"connecting_transient_failure");
|
||||
p->checking_subchannel =
|
||||
(p->checking_subchannel + 1) % p->num_subchannels;
|
||||
if (p->checking_subchannel == 0) {
|
||||
/* only trigger transient failure when we've tried all alternatives */
|
||||
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
|
||||
GRPC_CHANNEL_TRANSIENT_FAILURE,
|
||||
"connecting_transient_failure");
|
||||
}
|
||||
p->checking_connectivity = grpc_subchannel_check_connectivity(
|
||||
p->subchannels[p->checking_subchannel]);
|
||||
if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
|
||||
|
|
@ -378,14 +409,9 @@ static void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
|||
}
|
||||
|
||||
static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = {
|
||||
pf_destroy,
|
||||
pf_shutdown,
|
||||
pf_pick,
|
||||
pf_cancel_pick,
|
||||
pf_ping_one,
|
||||
pf_exit_idle,
|
||||
pf_check_connectivity,
|
||||
pf_notify_on_state_change};
|
||||
pf_destroy, pf_shutdown, pf_pick,
|
||||
pf_cancel_pick, pf_cancel_picks, pf_ping_one,
|
||||
pf_exit_idle, pf_check_connectivity, pf_notify_on_state_change};
|
||||
|
||||
static void pick_first_factory_ref(grpc_lb_policy_factory *factory) {}
|
||||
|
||||
|
|
@ -395,7 +421,7 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
|
|||
grpc_lb_policy_factory *factory,
|
||||
grpc_lb_policy_args *args) {
|
||||
GPR_ASSERT(args->addresses != NULL);
|
||||
GPR_ASSERT(args->subchannel_factory != NULL);
|
||||
GPR_ASSERT(args->client_channel_factory != NULL);
|
||||
|
||||
if (args->addresses->naddrs == 0) return NULL;
|
||||
|
||||
|
|
@ -412,8 +438,8 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
|
|||
sc_args.addr = (struct sockaddr *)(args->addresses->addrs[i].addr);
|
||||
sc_args.addr_len = (size_t)args->addresses->addrs[i].len;
|
||||
|
||||
grpc_subchannel *subchannel = grpc_subchannel_factory_create_subchannel(
|
||||
exec_ctx, args->subchannel_factory, &sc_args);
|
||||
grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
|
||||
exec_ctx, args->client_channel_factory, &sc_args);
|
||||
|
||||
if (subchannel != NULL) {
|
||||
p->subchannels[subchannel_idx++] = subchannel;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ int grpc_lb_round_robin_trace = 0;
|
|||
typedef struct pending_pick {
|
||||
struct pending_pick *next;
|
||||
grpc_pollset *pollset;
|
||||
uint32_t initial_metadata_flags;
|
||||
grpc_connected_subchannel **target;
|
||||
grpc_closure *on_complete;
|
||||
} pending_pick;
|
||||
|
|
@ -275,6 +276,32 @@ static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
|||
gpr_mu_unlock(&p->mu);
|
||||
}
|
||||
|
||||
static void rr_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
||||
uint32_t initial_metadata_flags_mask,
|
||||
uint32_t initial_metadata_flags_eq) {
|
||||
round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
|
||||
pending_pick *pp;
|
||||
gpr_mu_lock(&p->mu);
|
||||
pp = p->pending_picks;
|
||||
p->pending_picks = NULL;
|
||||
while (pp != NULL) {
|
||||
pending_pick *next = pp->next;
|
||||
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
|
||||
initial_metadata_flags_eq) {
|
||||
grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
|
||||
pp->pollset);
|
||||
*pp->target = NULL;
|
||||
grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
|
||||
gpr_free(pp);
|
||||
} else {
|
||||
pp->next = p->pending_picks;
|
||||
p->pending_picks = pp;
|
||||
}
|
||||
pp = next;
|
||||
}
|
||||
gpr_mu_unlock(&p->mu);
|
||||
}
|
||||
|
||||
static void start_picking(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p) {
|
||||
size_t i;
|
||||
p->started_picking = 1;
|
||||
|
|
@ -303,6 +330,7 @@ static void rr_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
|
|||
|
||||
static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
||||
grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **target,
|
||||
grpc_closure *on_complete) {
|
||||
round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
|
||||
|
|
@ -330,6 +358,7 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
|||
pp->pollset = pollset;
|
||||
pp->target = target;
|
||||
pp->on_complete = on_complete;
|
||||
pp->initial_metadata_flags = initial_metadata_flags;
|
||||
p->pending_picks = pp;
|
||||
gpr_mu_unlock(&p->mu);
|
||||
return 0;
|
||||
|
|
@ -485,14 +514,9 @@ static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
|
|||
}
|
||||
|
||||
static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = {
|
||||
rr_destroy,
|
||||
rr_shutdown,
|
||||
rr_pick,
|
||||
rr_cancel_pick,
|
||||
rr_ping_one,
|
||||
rr_exit_idle,
|
||||
rr_check_connectivity,
|
||||
rr_notify_on_state_change};
|
||||
rr_destroy, rr_shutdown, rr_pick,
|
||||
rr_cancel_pick, rr_cancel_picks, rr_ping_one,
|
||||
rr_exit_idle, rr_check_connectivity, rr_notify_on_state_change};
|
||||
|
||||
static void round_robin_factory_ref(grpc_lb_policy_factory *factory) {}
|
||||
|
||||
|
|
@ -502,7 +526,7 @@ static grpc_lb_policy *create_round_robin(grpc_exec_ctx *exec_ctx,
|
|||
grpc_lb_policy_factory *factory,
|
||||
grpc_lb_policy_args *args) {
|
||||
GPR_ASSERT(args->addresses != NULL);
|
||||
GPR_ASSERT(args->subchannel_factory != NULL);
|
||||
GPR_ASSERT(args->client_channel_factory != NULL);
|
||||
|
||||
round_robin_lb_policy *p = gpr_malloc(sizeof(*p));
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
|
@ -518,8 +542,8 @@ static grpc_lb_policy *create_round_robin(grpc_exec_ctx *exec_ctx,
|
|||
sc_args.addr = (struct sockaddr *)(args->addresses->addrs[i].addr);
|
||||
sc_args.addr_len = (size_t)args->addresses->addrs[i].len;
|
||||
|
||||
grpc_subchannel *subchannel = grpc_subchannel_factory_create_subchannel(
|
||||
exec_ctx, args->subchannel_factory, &sc_args);
|
||||
grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
|
||||
exec_ctx, args->client_channel_factory, &sc_args);
|
||||
|
||||
if (subchannel != NULL) {
|
||||
subchannel_data *sd = gpr_malloc(sizeof(*sd));
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ typedef struct {
|
|||
/** default port to use */
|
||||
char *default_port;
|
||||
/** subchannel factory */
|
||||
grpc_subchannel_factory *subchannel_factory;
|
||||
grpc_client_channel_factory *client_channel_factory;
|
||||
/** load balancing policy name */
|
||||
char *lb_policy_name;
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
config = grpc_client_config_create();
|
||||
memset(&lb_policy_args, 0, sizeof(lb_policy_args));
|
||||
lb_policy_args.addresses = addresses;
|
||||
lb_policy_args.subchannel_factory = r->subchannel_factory;
|
||||
lb_policy_args.client_channel_factory = r->client_channel_factory;
|
||||
lb_policy =
|
||||
grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
|
||||
if (lb_policy != NULL) {
|
||||
|
|
@ -228,7 +228,7 @@ static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
|
|||
if (r->resolved_config) {
|
||||
grpc_client_config_unref(exec_ctx, r->resolved_config);
|
||||
}
|
||||
grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
|
||||
grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
|
||||
gpr_free(r->name);
|
||||
gpr_free(r->default_port);
|
||||
gpr_free(r->lb_policy_name);
|
||||
|
|
@ -255,10 +255,10 @@ static grpc_resolver *dns_create(grpc_resolver_args *args,
|
|||
grpc_resolver_init(&r->base, &dns_resolver_vtable);
|
||||
r->name = gpr_strdup(path);
|
||||
r->default_port = gpr_strdup(default_port);
|
||||
r->subchannel_factory = args->subchannel_factory;
|
||||
r->client_channel_factory = args->client_channel_factory;
|
||||
gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER,
|
||||
BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000);
|
||||
grpc_subchannel_factory_ref(r->subchannel_factory);
|
||||
grpc_client_channel_factory_ref(r->client_channel_factory);
|
||||
r->lb_policy_name = gpr_strdup(lb_policy_name);
|
||||
return &r->base;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/host_port.h>
|
||||
#include <grpc/support/port_platform.h>
|
||||
#include <grpc/support/string_util.h>
|
||||
|
||||
#include "src/core/lib/client_config/lb_policy_registry.h"
|
||||
|
|
@ -52,7 +52,7 @@ typedef struct {
|
|||
/** refcount */
|
||||
gpr_refcount refs;
|
||||
/** subchannel factory */
|
||||
grpc_subchannel_factory *subchannel_factory;
|
||||
grpc_client_channel_factory *client_channel_factory;
|
||||
/** load balancing policy name */
|
||||
char *lb_policy_name;
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
|
|||
grpc_lb_policy_args lb_policy_args;
|
||||
memset(&lb_policy_args, 0, sizeof(lb_policy_args));
|
||||
lb_policy_args.addresses = r->addresses;
|
||||
lb_policy_args.subchannel_factory = r->subchannel_factory;
|
||||
lb_policy_args.client_channel_factory = r->client_channel_factory;
|
||||
grpc_lb_policy *lb_policy =
|
||||
grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
|
||||
grpc_client_config_set_lb_policy(cfg, lb_policy);
|
||||
|
|
@ -140,7 +140,7 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
|
|||
static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
|
||||
sockaddr_resolver *r = (sockaddr_resolver *)gr;
|
||||
gpr_mu_destroy(&r->mu);
|
||||
grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
|
||||
grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
|
||||
grpc_resolved_addresses_destroy(r->addresses);
|
||||
gpr_free(r->lb_policy_name);
|
||||
gpr_free(r);
|
||||
|
|
@ -263,22 +263,24 @@ static grpc_resolver *sockaddr_create(
|
|||
r = gpr_malloc(sizeof(sockaddr_resolver));
|
||||
memset(r, 0, sizeof(*r));
|
||||
|
||||
r->lb_policy_name = NULL;
|
||||
if (0 != strcmp(args->uri->query, "")) {
|
||||
gpr_slice query_slice;
|
||||
gpr_slice_buffer query_parts;
|
||||
r->lb_policy_name =
|
||||
gpr_strdup(grpc_uri_get_query_arg(args->uri, "lb_policy"));
|
||||
const char *lb_enabled_qpart =
|
||||
grpc_uri_get_query_arg(args->uri, "lb_enabled");
|
||||
/* anything other than "0" is interpreted as true */
|
||||
const bool lb_enabled =
|
||||
(lb_enabled_qpart != NULL && (strcmp("0", lb_enabled_qpart) != 0));
|
||||
|
||||
query_slice =
|
||||
gpr_slice_new(args->uri->query, strlen(args->uri->query), do_nothing);
|
||||
gpr_slice_buffer_init(&query_parts);
|
||||
gpr_slice_split(query_slice, "=", &query_parts);
|
||||
GPR_ASSERT(query_parts.count == 2);
|
||||
if (0 == gpr_slice_str_cmp(query_parts.slices[0], "lb_policy")) {
|
||||
r->lb_policy_name = gpr_dump_slice(query_parts.slices[1], GPR_DUMP_ASCII);
|
||||
}
|
||||
gpr_slice_buffer_destroy(&query_parts);
|
||||
gpr_slice_unref(query_slice);
|
||||
if (r->lb_policy_name != NULL && strcmp("grpclb", r->lb_policy_name) == 0 &&
|
||||
!lb_enabled) {
|
||||
/* we want grpclb but the "resolved" addresses aren't LB enabled. Bail
|
||||
* out, as this is meant mostly for tests. */
|
||||
gpr_log(GPR_ERROR,
|
||||
"Requested 'grpclb' LB policy but resolved addresses don't "
|
||||
"support load balancing.");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (r->lb_policy_name == NULL) {
|
||||
r->lb_policy_name = gpr_strdup(default_lb_policy_name);
|
||||
}
|
||||
|
|
@ -318,8 +320,8 @@ static grpc_resolver *sockaddr_create(
|
|||
gpr_ref_init(&r->refs, 1);
|
||||
gpr_mu_init(&r->mu);
|
||||
grpc_resolver_init(&r->base, &sockaddr_resolver_vtable);
|
||||
r->subchannel_factory = args->subchannel_factory;
|
||||
grpc_subchannel_factory_ref(r->subchannel_factory);
|
||||
r->client_channel_factory = args->client_channel_factory;
|
||||
grpc_client_channel_factory_ref(r->client_channel_factory);
|
||||
|
||||
return &r->base;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ typedef struct {
|
|||
/** name to resolve */
|
||||
char *name;
|
||||
/** subchannel factory */
|
||||
grpc_subchannel_factory *subchannel_factory;
|
||||
grpc_client_channel_factory *client_channel_factory;
|
||||
/** load balancing policy name */
|
||||
char *lb_policy_name;
|
||||
|
||||
|
|
@ -187,9 +187,8 @@ static void zookeeper_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
if (addresses != NULL) {
|
||||
grpc_lb_policy_args lb_policy_args;
|
||||
config = grpc_client_config_create();
|
||||
|
||||
lb_policy_args.addresses = addresses;
|
||||
lb_policy_args.subchannel_factory = r->subchannel_factory;
|
||||
lb_policy_args.client_channel_factory = r->client_channel_factory;
|
||||
lb_policy =
|
||||
grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
|
||||
|
||||
|
|
@ -424,7 +423,7 @@ static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
|
|||
if (r->resolved_config != NULL) {
|
||||
grpc_client_config_unref(exec_ctx, r->resolved_config);
|
||||
}
|
||||
grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
|
||||
grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
|
||||
gpr_free(r->name);
|
||||
gpr_free(r->lb_policy_name);
|
||||
gpr_free(r);
|
||||
|
|
@ -454,8 +453,8 @@ static grpc_resolver *zookeeper_create(grpc_resolver_args *args,
|
|||
grpc_resolver_init(&r->base, &zookeeper_resolver_vtable);
|
||||
r->name = gpr_strdup(path);
|
||||
|
||||
r->subchannel_factory = args->subchannel_factory;
|
||||
grpc_subchannel_factory_ref(r->subchannel_factory);
|
||||
r->client_channel_factory = args->client_channel_factory;
|
||||
grpc_client_channel_factory_ref(r->client_channel_factory);
|
||||
|
||||
r->lb_policy_name = gpr_strdup(lb_policy_name);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,31 +136,35 @@ static const grpc_connector_vtable connector_vtable = {
|
|||
connector_ref, connector_unref, connector_shutdown, connector_connect};
|
||||
|
||||
typedef struct {
|
||||
grpc_subchannel_factory base;
|
||||
grpc_client_channel_factory base;
|
||||
gpr_refcount refs;
|
||||
grpc_channel_args *merge_args;
|
||||
grpc_channel *master;
|
||||
} subchannel_factory;
|
||||
} client_channel_factory;
|
||||
|
||||
static void subchannel_factory_ref(grpc_subchannel_factory *scf) {
|
||||
subchannel_factory *f = (subchannel_factory *)scf;
|
||||
static void client_channel_factory_ref(
|
||||
grpc_client_channel_factory *cc_factory) {
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
gpr_ref(&f->refs);
|
||||
}
|
||||
|
||||
static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
|
||||
grpc_subchannel_factory *scf) {
|
||||
subchannel_factory *f = (subchannel_factory *)scf;
|
||||
static void client_channel_factory_unref(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
if (gpr_unref(&f->refs)) {
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
|
||||
if (f->master != NULL) {
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master,
|
||||
"client_channel_factory");
|
||||
}
|
||||
grpc_channel_args_destroy(f->merge_args);
|
||||
gpr_free(f);
|
||||
}
|
||||
}
|
||||
|
||||
static grpc_subchannel *subchannel_factory_create_subchannel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf,
|
||||
static grpc_subchannel *client_channel_factory_create_subchannel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
|
||||
grpc_subchannel_args *args) {
|
||||
subchannel_factory *f = (subchannel_factory *)scf;
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
connector *c = gpr_malloc(sizeof(*c));
|
||||
grpc_channel_args *final_args =
|
||||
grpc_channel_args_merge(args->args, f->merge_args);
|
||||
|
|
@ -175,9 +179,33 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
|
|||
return s;
|
||||
}
|
||||
|
||||
static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
|
||||
subchannel_factory_ref, subchannel_factory_unref,
|
||||
subchannel_factory_create_subchannel};
|
||||
static grpc_channel *client_channel_factory_create_channel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
|
||||
const char *target, grpc_client_channel_type type,
|
||||
grpc_channel_args *args) {
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
|
||||
grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
|
||||
GRPC_CLIENT_CHANNEL, NULL);
|
||||
grpc_channel_args_destroy(final_args);
|
||||
grpc_resolver *resolver = grpc_resolver_create(target, &f->base);
|
||||
if (!resolver) {
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
|
||||
"client_channel_factory_create_channel");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grpc_client_channel_set_resolver(
|
||||
exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
|
||||
GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
|
||||
{client_channel_factory_ref, client_channel_factory_unref,
|
||||
client_channel_factory_create_subchannel,
|
||||
client_channel_factory_create_channel};
|
||||
|
||||
/* Create a client channel:
|
||||
Asynchronously: - resolve target
|
||||
|
|
@ -186,38 +214,27 @@ static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
|
|||
grpc_channel *grpc_insecure_channel_create(const char *target,
|
||||
const grpc_channel_args *args,
|
||||
void *reserved) {
|
||||
grpc_channel *channel = NULL;
|
||||
grpc_resolver *resolver;
|
||||
subchannel_factory *f;
|
||||
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
|
||||
GRPC_API_TRACE(
|
||||
"grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
|
||||
(target, args, reserved));
|
||||
GPR_ASSERT(!reserved);
|
||||
|
||||
channel =
|
||||
grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
|
||||
|
||||
f = gpr_malloc(sizeof(*f));
|
||||
f->base.vtable = &subchannel_factory_vtable;
|
||||
client_channel_factory *f = gpr_malloc(sizeof(*f));
|
||||
memset(f, 0, sizeof(*f));
|
||||
f->base.vtable = &client_channel_factory_vtable;
|
||||
gpr_ref_init(&f->refs, 1);
|
||||
f->merge_args = grpc_channel_args_copy(args);
|
||||
f->master = channel;
|
||||
GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory");
|
||||
resolver = grpc_resolver_create(target, &f->base);
|
||||
if (!resolver) {
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, f->master, "subchannel_factory");
|
||||
grpc_subchannel_factory_unref(&exec_ctx, &f->base);
|
||||
grpc_exec_ctx_finish(&exec_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grpc_client_channel_set_resolver(
|
||||
&exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
|
||||
GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
|
||||
grpc_subchannel_factory_unref(&exec_ctx, &f->base);
|
||||
grpc_channel *channel = client_channel_factory_create_channel(
|
||||
&exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, NULL);
|
||||
if (channel != NULL) {
|
||||
f->master = channel;
|
||||
GRPC_CHANNEL_INTERNAL_REF(f->master, "grpc_insecure_channel_create");
|
||||
}
|
||||
grpc_client_channel_factory_unref(&exec_ctx, &f->base);
|
||||
|
||||
grpc_exec_ctx_finish(&exec_ctx);
|
||||
|
||||
return channel;
|
||||
return channel; /* may be NULL */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,34 +192,38 @@ static const grpc_connector_vtable connector_vtable = {
|
|||
connector_ref, connector_unref, connector_shutdown, connector_connect};
|
||||
|
||||
typedef struct {
|
||||
grpc_subchannel_factory base;
|
||||
grpc_client_channel_factory base;
|
||||
gpr_refcount refs;
|
||||
grpc_channel_args *merge_args;
|
||||
grpc_channel_security_connector *security_connector;
|
||||
grpc_channel *master;
|
||||
} subchannel_factory;
|
||||
} client_channel_factory;
|
||||
|
||||
static void subchannel_factory_ref(grpc_subchannel_factory *scf) {
|
||||
subchannel_factory *f = (subchannel_factory *)scf;
|
||||
static void client_channel_factory_ref(
|
||||
grpc_client_channel_factory *cc_factory) {
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
gpr_ref(&f->refs);
|
||||
}
|
||||
|
||||
static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
|
||||
grpc_subchannel_factory *scf) {
|
||||
subchannel_factory *f = (subchannel_factory *)scf;
|
||||
static void client_channel_factory_unref(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
if (gpr_unref(&f->refs)) {
|
||||
GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
|
||||
"subchannel_factory");
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
|
||||
"client_channel_factory");
|
||||
if (f->master != NULL) {
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master,
|
||||
"client_channel_factory");
|
||||
}
|
||||
grpc_channel_args_destroy(f->merge_args);
|
||||
gpr_free(f);
|
||||
}
|
||||
}
|
||||
|
||||
static grpc_subchannel *subchannel_factory_create_subchannel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf,
|
||||
static grpc_subchannel *client_channel_factory_create_subchannel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
|
||||
grpc_subchannel_args *args) {
|
||||
subchannel_factory *f = (subchannel_factory *)scf;
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
connector *c = gpr_malloc(sizeof(*c));
|
||||
grpc_channel_args *final_args =
|
||||
grpc_channel_args_merge(args->args, f->merge_args);
|
||||
|
|
@ -236,9 +240,37 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
|
|||
return s;
|
||||
}
|
||||
|
||||
static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
|
||||
subchannel_factory_ref, subchannel_factory_unref,
|
||||
subchannel_factory_create_subchannel};
|
||||
static grpc_channel *client_channel_factory_create_channel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
|
||||
const char *target, grpc_client_channel_type type,
|
||||
grpc_channel_args *args) {
|
||||
client_channel_factory *f = (client_channel_factory *)cc_factory;
|
||||
|
||||
grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
|
||||
grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
|
||||
GRPC_CLIENT_CHANNEL, NULL);
|
||||
grpc_channel_args_destroy(final_args);
|
||||
|
||||
grpc_resolver *resolver = grpc_resolver_create(target, &f->base);
|
||||
if (resolver != NULL) {
|
||||
grpc_client_channel_set_resolver(
|
||||
exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
|
||||
GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create");
|
||||
} else {
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
|
||||
"client_channel_factory_create_channel");
|
||||
channel = NULL;
|
||||
}
|
||||
|
||||
GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
|
||||
"client_channel_factory_create_channel");
|
||||
return channel;
|
||||
}
|
||||
|
||||
static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
|
||||
{client_channel_factory_ref, client_channel_factory_unref,
|
||||
client_channel_factory_create_subchannel,
|
||||
client_channel_factory_create_channel};
|
||||
|
||||
/* Create a secure client channel:
|
||||
Asynchronously: - resolve target
|
||||
|
|
@ -248,13 +280,11 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
|
|||
const char *target,
|
||||
const grpc_channel_args *args,
|
||||
void *reserved) {
|
||||
grpc_channel *channel;
|
||||
grpc_arg connector_arg;
|
||||
grpc_channel_args *args_copy;
|
||||
grpc_channel_args *new_args_from_connector;
|
||||
grpc_channel_security_connector *security_connector;
|
||||
grpc_resolver *resolver;
|
||||
subchannel_factory *f;
|
||||
client_channel_factory *f;
|
||||
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
|
||||
|
||||
GRPC_API_TRACE(
|
||||
|
|
@ -284,35 +314,30 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
|
|||
new_args_from_connector != NULL ? new_args_from_connector : args,
|
||||
&connector_arg, 1);
|
||||
|
||||
channel = grpc_channel_create(&exec_ctx, target, args_copy,
|
||||
GRPC_CLIENT_CHANNEL, NULL);
|
||||
|
||||
f = gpr_malloc(sizeof(*f));
|
||||
f->base.vtable = &subchannel_factory_vtable;
|
||||
memset(f, 0, sizeof(*f));
|
||||
f->base.vtable = &client_channel_factory_vtable;
|
||||
gpr_ref_init(&f->refs, 1);
|
||||
GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, "subchannel_factory");
|
||||
f->security_connector = security_connector;
|
||||
|
||||
f->merge_args = grpc_channel_args_copy(args_copy);
|
||||
f->master = channel;
|
||||
GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory");
|
||||
resolver = grpc_resolver_create(target, &f->base);
|
||||
if (resolver) {
|
||||
grpc_client_channel_set_resolver(
|
||||
&exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
|
||||
GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
|
||||
}
|
||||
grpc_subchannel_factory_unref(&exec_ctx, &f->base);
|
||||
GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create");
|
||||
grpc_channel_args_destroy(args_copy);
|
||||
if (new_args_from_connector != NULL) {
|
||||
grpc_channel_args_destroy(new_args_from_connector);
|
||||
}
|
||||
|
||||
if (!resolver) {
|
||||
GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory");
|
||||
channel = NULL;
|
||||
GRPC_SECURITY_CONNECTOR_REF(&security_connector->base,
|
||||
"grpc_secure_channel_create");
|
||||
f->security_connector = security_connector;
|
||||
|
||||
grpc_channel *channel = client_channel_factory_create_channel(
|
||||
&exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, NULL);
|
||||
if (channel != NULL) {
|
||||
f->master = channel;
|
||||
GRPC_CHANNEL_INTERNAL_REF(f->master, "grpc_secure_channel_create");
|
||||
}
|
||||
|
||||
grpc_client_channel_factory_unref(&exec_ctx, &f->base);
|
||||
grpc_exec_ctx_finish(&exec_ctx);
|
||||
|
||||
return channel;
|
||||
return channel; /* may be NULL */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,22 @@ static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand,
|
|||
grpc_lb_policy *lb_policy,
|
||||
grpc_connectivity_state current_state);
|
||||
|
||||
static void set_channel_connectivity_state_locked(grpc_exec_ctx *exec_ctx,
|
||||
channel_data *chand,
|
||||
grpc_connectivity_state state,
|
||||
const char *reason) {
|
||||
if ((state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
|
||||
state == GRPC_CHANNEL_FATAL_FAILURE) &&
|
||||
chand->lb_policy != NULL) {
|
||||
/* cancel fail-fast picks */
|
||||
grpc_lb_policy_cancel_picks(
|
||||
exec_ctx, chand->lb_policy,
|
||||
/* mask= */ GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY,
|
||||
/* check= */ 0);
|
||||
}
|
||||
grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state, reason);
|
||||
}
|
||||
|
||||
static void on_lb_policy_state_changed_locked(
|
||||
grpc_exec_ctx *exec_ctx, lb_policy_connectivity_watcher *w) {
|
||||
grpc_connectivity_state publish_state = w->state;
|
||||
|
|
@ -127,8 +143,8 @@ static void on_lb_policy_state_changed_locked(
|
|||
GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel");
|
||||
w->chand->lb_policy = NULL;
|
||||
}
|
||||
grpc_connectivity_state_set(exec_ctx, &w->chand->state_tracker, publish_state,
|
||||
"lb_changed");
|
||||
set_channel_connectivity_state_locked(exec_ctx, w->chand, publish_state,
|
||||
"lb_changed");
|
||||
if (w->state != GRPC_CHANNEL_FATAL_FAILURE) {
|
||||
watch_lb_policy(exec_ctx, w->chand, w->lb_policy, w->state);
|
||||
}
|
||||
|
|
@ -200,8 +216,8 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
}
|
||||
|
||||
if (iomgr_success && chand->resolver) {
|
||||
grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state,
|
||||
"new_lb+resolver");
|
||||
set_channel_connectivity_state_locked(exec_ctx, chand, state,
|
||||
"new_lb+resolver");
|
||||
if (lb_policy != NULL) {
|
||||
watch_lb_policy(exec_ctx, chand, lb_policy, state);
|
||||
}
|
||||
|
|
@ -216,8 +232,8 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
|
|||
GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
|
||||
chand->resolver = NULL;
|
||||
}
|
||||
grpc_connectivity_state_set(exec_ctx, &chand->state_tracker,
|
||||
GRPC_CHANNEL_FATAL_FAILURE, "resolver_gone");
|
||||
set_channel_connectivity_state_locked(
|
||||
exec_ctx, chand, GRPC_CHANNEL_FATAL_FAILURE, "resolver_gone");
|
||||
gpr_mu_unlock(&chand->mu_config);
|
||||
}
|
||||
|
||||
|
|
@ -272,8 +288,8 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
|
|||
}
|
||||
|
||||
if (op->disconnect && chand->resolver != NULL) {
|
||||
grpc_connectivity_state_set(exec_ctx, &chand->state_tracker,
|
||||
GRPC_CHANNEL_FATAL_FAILURE, "disconnect");
|
||||
set_channel_connectivity_state_locked(
|
||||
exec_ctx, chand, GRPC_CHANNEL_FATAL_FAILURE, "disconnect");
|
||||
grpc_resolver_shutdown(exec_ctx, chand->resolver);
|
||||
GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
|
||||
chand->resolver = NULL;
|
||||
|
|
@ -290,6 +306,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
|
|||
|
||||
typedef struct {
|
||||
grpc_metadata_batch *initial_metadata;
|
||||
uint32_t initial_metadata_flags;
|
||||
grpc_connected_subchannel **connected_subchannel;
|
||||
grpc_closure *on_ready;
|
||||
grpc_call_element *elem;
|
||||
|
|
@ -298,6 +315,7 @@ typedef struct {
|
|||
|
||||
static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg,
|
||||
grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **connected_subchannel,
|
||||
grpc_closure *on_ready);
|
||||
|
||||
|
|
@ -308,6 +326,7 @@ static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
|
|||
} else if (cpa->connected_subchannel == NULL) {
|
||||
/* cancelled, do nothing */
|
||||
} else if (cc_pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata,
|
||||
cpa->initial_metadata_flags,
|
||||
cpa->connected_subchannel, cpa->on_ready)) {
|
||||
grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, true, NULL);
|
||||
}
|
||||
|
|
@ -316,6 +335,7 @@ static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
|
|||
|
||||
static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
|
||||
grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **connected_subchannel,
|
||||
grpc_closure *on_ready) {
|
||||
grpc_call_element *elem = elemp;
|
||||
|
|
@ -349,7 +369,8 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
|
|||
GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel");
|
||||
gpr_mu_unlock(&chand->mu_config);
|
||||
r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollset,
|
||||
initial_metadata, connected_subchannel, on_ready);
|
||||
initial_metadata, initial_metadata_flags,
|
||||
connected_subchannel, on_ready);
|
||||
GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel");
|
||||
return r;
|
||||
}
|
||||
|
|
@ -362,6 +383,7 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
|
|||
}
|
||||
cpa = gpr_malloc(sizeof(*cpa));
|
||||
cpa->initial_metadata = initial_metadata;
|
||||
cpa->initial_metadata_flags = initial_metadata_flags;
|
||||
cpa->connected_subchannel = connected_subchannel;
|
||||
cpa->on_ready = on_ready;
|
||||
cpa->elem = elem;
|
||||
|
|
|
|||
|
|
@ -111,10 +111,12 @@ static void hc_mutate_op(grpc_call_element *elem,
|
|||
elem);
|
||||
/* Send : prefixed headers, which have to be before any application
|
||||
layer headers. */
|
||||
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
|
||||
op->send_idempotent_request
|
||||
? GRPC_MDELEM_METHOD_PUT
|
||||
: GRPC_MDELEM_METHOD_POST);
|
||||
grpc_metadata_batch_add_head(
|
||||
op->send_initial_metadata, &calld->method,
|
||||
op->send_initial_metadata_flags &
|
||||
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
|
||||
? GRPC_MDELEM_METHOD_PUT
|
||||
: GRPC_MDELEM_METHOD_POST);
|
||||
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
|
||||
channeld->static_scheme);
|
||||
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ retry:
|
|||
break;
|
||||
case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
|
||||
holder->pick_subchannel(exec_ctx, holder->pick_subchannel_arg, NULL,
|
||||
&holder->connected_subchannel, NULL);
|
||||
0, &holder->connected_subchannel, NULL);
|
||||
break;
|
||||
}
|
||||
gpr_mu_unlock(&holder->mu);
|
||||
|
|
@ -145,7 +145,8 @@ retry:
|
|||
GRPC_CALL_STACK_REF(holder->owning_call, "pick_subchannel");
|
||||
if (holder->pick_subchannel(
|
||||
exec_ctx, holder->pick_subchannel_arg, op->send_initial_metadata,
|
||||
&holder->connected_subchannel, &holder->next_step)) {
|
||||
op->send_initial_metadata_flags, &holder->connected_subchannel,
|
||||
&holder->next_step)) {
|
||||
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
|
||||
GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
called when the subchannel is available) */
|
||||
typedef int (*grpc_subchannel_call_holder_pick_subchannel)(
|
||||
grpc_exec_ctx *exec_ctx, void *arg, grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready);
|
||||
|
||||
typedef enum {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ decisions (for example, by avoiding disconnected backends).
|
|||
Configured sub-channels are fully setup to participate in the grpc data plane.
|
||||
Their behavior is specified by a set of grpc channel filters defined at their
|
||||
construction. To customize this behavior, resolvers build
|
||||
grpc_subchannel_factory objects, which use the decorator pattern to customize
|
||||
grpc_client_channel_factory objects, which use the decorator pattern to customize
|
||||
construction arguments for concrete grpc_subchannel instances.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,36 +31,27 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H
|
||||
#define GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H
|
||||
#include "src/core/lib/client_config/client_channel_factory.h"
|
||||
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/client_config/subchannel.h"
|
||||
void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) {
|
||||
factory->vtable->ref(factory);
|
||||
}
|
||||
|
||||
typedef struct grpc_subchannel_factory grpc_subchannel_factory;
|
||||
typedef struct grpc_subchannel_factory_vtable grpc_subchannel_factory_vtable;
|
||||
void grpc_client_channel_factory_unref(grpc_exec_ctx* exec_ctx,
|
||||
grpc_client_channel_factory* factory) {
|
||||
factory->vtable->unref(exec_ctx, factory);
|
||||
}
|
||||
|
||||
/** Constructor for new configured channels.
|
||||
Creating decorators around this type is encouraged to adapt behavior. */
|
||||
struct grpc_subchannel_factory {
|
||||
const grpc_subchannel_factory_vtable *vtable;
|
||||
};
|
||||
grpc_subchannel* grpc_client_channel_factory_create_subchannel(
|
||||
grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
|
||||
grpc_subchannel_args* args) {
|
||||
return factory->vtable->create_subchannel(exec_ctx, factory, args);
|
||||
}
|
||||
|
||||
struct grpc_subchannel_factory_vtable {
|
||||
void (*ref)(grpc_subchannel_factory *factory);
|
||||
void (*unref)(grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory);
|
||||
grpc_subchannel *(*create_subchannel)(grpc_exec_ctx *exec_ctx,
|
||||
grpc_subchannel_factory *factory,
|
||||
grpc_subchannel_args *args);
|
||||
};
|
||||
|
||||
void grpc_subchannel_factory_ref(grpc_subchannel_factory *factory);
|
||||
void grpc_subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
|
||||
grpc_subchannel_factory *factory);
|
||||
|
||||
/** Create a new grpc_subchannel */
|
||||
grpc_subchannel *grpc_subchannel_factory_create_subchannel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory,
|
||||
grpc_subchannel_args *args);
|
||||
|
||||
#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H */
|
||||
grpc_channel* grpc_client_channel_factory_create_channel(
|
||||
grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
|
||||
const char* target, grpc_client_channel_type type,
|
||||
grpc_channel_args* args) {
|
||||
return factory->vtable->create_client_channel(exec_ctx, factory, target, type,
|
||||
args);
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CHANNEL_FACTORY_H
|
||||
#define GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CHANNEL_FACTORY_H
|
||||
|
||||
#include <grpc/impl/codegen/grpc_types.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/client_config/subchannel.h"
|
||||
|
||||
typedef struct grpc_client_channel_factory grpc_client_channel_factory;
|
||||
typedef struct grpc_client_channel_factory_vtable
|
||||
grpc_client_channel_factory_vtable;
|
||||
|
||||
typedef enum {
|
||||
GRPC_CLIENT_CHANNEL_TYPE_REGULAR, /** for the user-level regular calls */
|
||||
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, /** for communication with a load
|
||||
balancing service */
|
||||
} grpc_client_channel_type;
|
||||
|
||||
/** Constructor for new configured channels.
|
||||
Creating decorators around this type is encouraged to adapt behavior. */
|
||||
struct grpc_client_channel_factory {
|
||||
const grpc_client_channel_factory_vtable *vtable;
|
||||
};
|
||||
|
||||
struct grpc_client_channel_factory_vtable {
|
||||
void (*ref)(grpc_client_channel_factory *factory);
|
||||
void (*unref)(grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory);
|
||||
grpc_subchannel *(*create_subchannel)(grpc_exec_ctx *exec_ctx,
|
||||
grpc_client_channel_factory *factory,
|
||||
grpc_subchannel_args *args);
|
||||
grpc_channel *(*create_client_channel)(grpc_exec_ctx *exec_ctx,
|
||||
grpc_client_channel_factory *factory,
|
||||
const char *target,
|
||||
grpc_client_channel_type type,
|
||||
grpc_channel_args *args);
|
||||
};
|
||||
|
||||
void grpc_client_channel_factory_ref(grpc_client_channel_factory *factory);
|
||||
void grpc_client_channel_factory_unref(grpc_exec_ctx *exec_ctx,
|
||||
grpc_client_channel_factory *factory);
|
||||
|
||||
/** Create a new grpc_subchannel */
|
||||
grpc_subchannel *grpc_client_channel_factory_create_subchannel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
|
||||
grpc_subchannel_args *args);
|
||||
|
||||
/** Create a new grpc_channel */
|
||||
grpc_channel *grpc_client_channel_factory_create_channel(
|
||||
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
|
||||
const char *target, grpc_client_channel_type type, grpc_channel_args *args);
|
||||
|
||||
#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CHANNEL_FACTORY_H */
|
||||
|
|
@ -101,10 +101,11 @@ void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx,
|
|||
int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
grpc_pollset *pollset,
|
||||
grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **target,
|
||||
grpc_closure *on_complete) {
|
||||
return policy->vtable->pick(exec_ctx, policy, pollset, initial_metadata,
|
||||
target, on_complete);
|
||||
initial_metadata_flags, target, on_complete);
|
||||
}
|
||||
|
||||
void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
|
|
@ -112,6 +113,14 @@ void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
|||
policy->vtable->cancel_pick(exec_ctx, policy, target);
|
||||
}
|
||||
|
||||
void grpc_lb_policy_cancel_picks(grpc_exec_ctx *exec_ctx,
|
||||
grpc_lb_policy *policy,
|
||||
uint32_t initial_metadata_flags_mask,
|
||||
uint32_t initial_metadata_flags_eq) {
|
||||
policy->vtable->cancel_picks(exec_ctx, policy, initial_metadata_flags_mask,
|
||||
initial_metadata_flags_eq);
|
||||
}
|
||||
|
||||
void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) {
|
||||
policy->vtable->exit_idle(exec_ctx, policy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,9 +60,13 @@ struct grpc_lb_policy_vtable {
|
|||
/** implement grpc_lb_policy_pick */
|
||||
int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **target, grpc_closure *on_complete);
|
||||
void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
grpc_connected_subchannel **target);
|
||||
void (*cancel_picks)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
uint32_t initial_metadata_flags_mask,
|
||||
uint32_t initial_metadata_flags_eq);
|
||||
|
||||
void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
grpc_closure *closure);
|
||||
|
|
@ -122,6 +126,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
|
|||
int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
grpc_pollset *pollset,
|
||||
grpc_metadata_batch *initial_metadata,
|
||||
uint32_t initial_metadata_flags,
|
||||
grpc_connected_subchannel **target,
|
||||
grpc_closure *on_complete);
|
||||
|
||||
|
|
@ -131,6 +136,14 @@ void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
|||
void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
|
||||
grpc_connected_subchannel **target);
|
||||
|
||||
/** Cancel all pending picks which have:
|
||||
(initial_metadata_flags & initial_metadata_flags_mask) ==
|
||||
initial_metadata_flags_eq */
|
||||
void grpc_lb_policy_cancel_picks(grpc_exec_ctx *exec_ctx,
|
||||
grpc_lb_policy *policy,
|
||||
uint32_t initial_metadata_flags_mask,
|
||||
uint32_t initial_metadata_flags_eq);
|
||||
|
||||
void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
|
||||
|
||||
void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx,
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@
|
|||
#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H
|
||||
#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H
|
||||
|
||||
#include "src/core/lib/client_config/client_channel_factory.h"
|
||||
#include "src/core/lib/client_config/lb_policy.h"
|
||||
#include "src/core/lib/client_config/subchannel_factory.h"
|
||||
#include "src/core/lib/iomgr/resolve_address.h"
|
||||
|
||||
#include "src/core/lib/iomgr/exec_ctx.h"
|
||||
|
|
@ -51,7 +51,7 @@ struct grpc_lb_policy_factory {
|
|||
|
||||
typedef struct grpc_lb_policy_args {
|
||||
grpc_resolved_addresses *addresses;
|
||||
grpc_subchannel_factory *subchannel_factory;
|
||||
grpc_client_channel_factory *client_channel_factory;
|
||||
} grpc_lb_policy_args;
|
||||
|
||||
struct grpc_lb_policy_factory_vtable {
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@
|
|||
#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_FACTORY_H
|
||||
#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_FACTORY_H
|
||||
|
||||
#include "src/core/lib/client_config/client_channel_factory.h"
|
||||
#include "src/core/lib/client_config/resolver.h"
|
||||
#include "src/core/lib/client_config/subchannel_factory.h"
|
||||
#include "src/core/lib/client_config/uri_parser.h"
|
||||
|
||||
typedef struct grpc_resolver_factory grpc_resolver_factory;
|
||||
|
|
@ -49,7 +49,7 @@ struct grpc_resolver_factory {
|
|||
|
||||
typedef struct grpc_resolver_args {
|
||||
grpc_uri *uri;
|
||||
grpc_subchannel_factory *subchannel_factory;
|
||||
grpc_client_channel_factory *client_channel_factory;
|
||||
} grpc_resolver_args;
|
||||
|
||||
struct grpc_resolver_factory_vtable {
|
||||
|
|
|
|||
|
|
@ -123,14 +123,14 @@ static grpc_resolver_factory *resolve_factory(const char *target,
|
|||
}
|
||||
|
||||
grpc_resolver *grpc_resolver_create(
|
||||
const char *target, grpc_subchannel_factory *subchannel_factory) {
|
||||
const char *target, grpc_client_channel_factory *client_channel_factory) {
|
||||
grpc_uri *uri = NULL;
|
||||
grpc_resolver_factory *factory = resolve_factory(target, &uri);
|
||||
grpc_resolver *resolver;
|
||||
grpc_resolver_args args;
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.uri = uri;
|
||||
args.subchannel_factory = subchannel_factory;
|
||||
args.client_channel_factory = client_channel_factory;
|
||||
resolver = grpc_resolver_factory_create_resolver(factory, &args);
|
||||
grpc_uri_destroy(uri);
|
||||
return resolver;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory);
|
|||
return it.
|
||||
If a resolver factory was not found, return NULL. */
|
||||
grpc_resolver *grpc_resolver_create(
|
||||
const char *target, grpc_subchannel_factory *subchannel_factory);
|
||||
const char *target, grpc_client_channel_factory *client_channel_factory);
|
||||
|
||||
/** Find a resolver factory given a name and return an (owned-by-the-caller)
|
||||
* reference to it */
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
#define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1))
|
||||
|
||||
#define GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS 20
|
||||
#define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1
|
||||
#define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 2
|
||||
#define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6
|
||||
#define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120
|
||||
#define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2
|
||||
|
|
@ -352,6 +352,25 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
|
|||
c->args->args[i].value.integer,
|
||||
c->args->args[i].value.integer);
|
||||
}
|
||||
if (0 ==
|
||||
strcmp(c->args->args[i].key, GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)) {
|
||||
if (c->args->args[i].type == GRPC_ARG_INTEGER) {
|
||||
if (c->args->args[i].value.integer >= 0) {
|
||||
gpr_backoff_init(
|
||||
&c->backoff_state, GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER,
|
||||
GRPC_SUBCHANNEL_RECONNECT_JITTER,
|
||||
GPR_MIN(c->args->args[i].value.integer,
|
||||
GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000),
|
||||
c->args->args[i].value.integer);
|
||||
} else {
|
||||
gpr_log(GPR_ERROR, GRPC_ARG_MAX_RECONNECT_BACKOFF_MS
|
||||
" : must be non-negative");
|
||||
}
|
||||
} else {
|
||||
gpr_log(GPR_ERROR,
|
||||
GRPC_ARG_MAX_RECONNECT_BACKOFF_MS " : must be an integer");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gpr_mu_init(&c->mu);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015-2016, Google Inc.
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015-2016, Google Inc.
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015-2016, Google Inc.
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -81,11 +81,11 @@ typedef enum {
|
|||
/* Status came from the application layer overriding whatever
|
||||
the wire says */
|
||||
STATUS_FROM_API_OVERRIDE = 0,
|
||||
/* Status was created by some internal channel stack operation */
|
||||
STATUS_FROM_CORE,
|
||||
/* Status came from 'the wire' - or somewhere below the surface
|
||||
layer */
|
||||
STATUS_FROM_WIRE,
|
||||
/* Status was created by some internal channel stack operation */
|
||||
STATUS_FROM_CORE,
|
||||
/* Status came from the server sending status */
|
||||
STATUS_FROM_SERVER_STATUS,
|
||||
STATUS_SOURCE_COUNT
|
||||
|
|
@ -1110,6 +1110,9 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) {
|
|||
|
||||
gpr_mu_lock(&call->mu);
|
||||
if (bctl->send_initial_metadata) {
|
||||
if (!success) {
|
||||
set_status_code(call, STATUS_FROM_CORE, GRPC_STATUS_UNAVAILABLE);
|
||||
}
|
||||
grpc_metadata_batch_destroy(
|
||||
&call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
|
||||
}
|
||||
|
|
@ -1232,8 +1235,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
|
|||
call->metadata_batch[0][0].deadline = call->send_deadline;
|
||||
stream_op.send_initial_metadata =
|
||||
&call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */];
|
||||
stream_op.send_idempotent_request =
|
||||
(op->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) != 0;
|
||||
stream_op.send_initial_metadata_flags = op->flags;
|
||||
break;
|
||||
case GRPC_OP_SEND_MESSAGE:
|
||||
if (!are_write_flags_valid(op->flags)) {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#define GRPC_CORE_LIB_SURFACE_CHANNEL_H
|
||||
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/client_config/subchannel_factory.h"
|
||||
#include "src/core/lib/client_config/client_channel_factory.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
|
||||
grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ typedef struct requested_call {
|
|||
grpc_byte_buffer **optional_payload;
|
||||
} registered;
|
||||
} data;
|
||||
grpc_closure publish;
|
||||
} requested_call;
|
||||
|
||||
typedef struct channel_registered_method {
|
||||
|
|
@ -156,15 +155,21 @@ struct call_data {
|
|||
bool recv_idempotent_request;
|
||||
grpc_metadata_array initial_metadata;
|
||||
|
||||
request_matcher *request_matcher;
|
||||
grpc_byte_buffer *payload;
|
||||
|
||||
grpc_closure got_initial_metadata;
|
||||
grpc_closure server_on_recv_initial_metadata;
|
||||
grpc_closure kill_zombie_closure;
|
||||
grpc_closure *on_done_recv_initial_metadata;
|
||||
|
||||
grpc_closure publish;
|
||||
|
||||
call_data *pending_next;
|
||||
};
|
||||
|
||||
struct request_matcher {
|
||||
grpc_server *server;
|
||||
call_data *pending_head;
|
||||
call_data *pending_tail;
|
||||
gpr_stack_lockfree *requests;
|
||||
|
|
@ -173,6 +178,7 @@ struct request_matcher {
|
|||
struct registered_method {
|
||||
char *method;
|
||||
char *host;
|
||||
grpc_server_register_method_payload_handling payload_handling;
|
||||
uint32_t flags;
|
||||
request_matcher request_matcher;
|
||||
registered_method *next;
|
||||
|
|
@ -226,8 +232,7 @@ struct grpc_server {
|
|||
#define SERVER_FROM_CALL_ELEM(elem) \
|
||||
(((channel_data *)(elem)->channel_data)->server)
|
||||
|
||||
static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
||||
call_data *calld, requested_call *rc);
|
||||
static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld, bool success);
|
||||
static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
||||
requested_call *rc);
|
||||
/* Before calling maybe_finish_shutdown, we must hold mu_global and not
|
||||
|
|
@ -303,8 +308,10 @@ static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
|
|||
* request_matcher
|
||||
*/
|
||||
|
||||
static void request_matcher_init(request_matcher *rm, size_t entries) {
|
||||
static void request_matcher_init(request_matcher *rm, size_t entries,
|
||||
grpc_server *server) {
|
||||
memset(rm, 0, sizeof(*rm));
|
||||
rm->server = server;
|
||||
rm->requests = gpr_stack_lockfree_create(entries);
|
||||
}
|
||||
|
||||
|
|
@ -417,21 +424,90 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
|
|||
&op);
|
||||
}
|
||||
|
||||
static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
||||
grpc_call_element *elem, request_matcher *rm) {
|
||||
call_data *calld = elem->call_data;
|
||||
int request_id;
|
||||
static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
|
||||
gpr_slice slice = value->slice;
|
||||
size_t len = GPR_SLICE_LENGTH(slice);
|
||||
|
||||
if (gpr_atm_acq_load(&server->shutdown_flag)) {
|
||||
if (len + 1 > *capacity) {
|
||||
*capacity = GPR_MAX(len + 1, *capacity * 2);
|
||||
*dest = gpr_realloc(*dest, *capacity);
|
||||
}
|
||||
memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
|
||||
}
|
||||
|
||||
static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
|
||||
grpc_cq_completion *c) {
|
||||
requested_call *rc = req;
|
||||
grpc_server *server = rc->server;
|
||||
|
||||
if (rc >= server->requested_calls &&
|
||||
rc < server->requested_calls + server->max_requested_calls) {
|
||||
GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
|
||||
gpr_stack_lockfree_push(server->request_freelist,
|
||||
(int)(rc - server->requested_calls));
|
||||
} else {
|
||||
gpr_free(req);
|
||||
}
|
||||
|
||||
server_unref(exec_ctx, server);
|
||||
}
|
||||
|
||||
static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
||||
call_data *calld, requested_call *rc) {
|
||||
grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
|
||||
grpc_call *call = calld->call;
|
||||
*rc->call = call;
|
||||
calld->cq_new = rc->cq_for_notification;
|
||||
GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
|
||||
switch (rc->type) {
|
||||
case BATCH_CALL:
|
||||
GPR_ASSERT(calld->host != NULL);
|
||||
GPR_ASSERT(calld->path != NULL);
|
||||
cpstr(&rc->data.batch.details->host,
|
||||
&rc->data.batch.details->host_capacity, calld->host);
|
||||
cpstr(&rc->data.batch.details->method,
|
||||
&rc->data.batch.details->method_capacity, calld->path);
|
||||
rc->data.batch.details->deadline = calld->deadline;
|
||||
rc->data.batch.details->flags =
|
||||
0 | (calld->recv_idempotent_request
|
||||
? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
|
||||
: 0);
|
||||
break;
|
||||
case REGISTERED_CALL:
|
||||
*rc->data.registered.deadline = calld->deadline;
|
||||
if (rc->data.registered.optional_payload) {
|
||||
*rc->data.registered.optional_payload = calld->payload;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
GPR_UNREACHABLE_CODE(return );
|
||||
}
|
||||
|
||||
grpc_call_element *elem =
|
||||
grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
|
||||
channel_data *chand = elem->channel_data;
|
||||
server_ref(chand->server);
|
||||
grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, true, done_request_event, rc,
|
||||
&rc->completion);
|
||||
}
|
||||
|
||||
static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
|
||||
call_data *calld = arg;
|
||||
request_matcher *rm = calld->request_matcher;
|
||||
grpc_server *server = rm->server;
|
||||
|
||||
if (!success || gpr_atm_acq_load(&server->shutdown_flag)) {
|
||||
gpr_mu_lock(&calld->mu_state);
|
||||
calld->state = ZOMBIED;
|
||||
gpr_mu_unlock(&calld->mu_state);
|
||||
grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
|
||||
grpc_closure_init(
|
||||
&calld->kill_zombie_closure, kill_zombie,
|
||||
grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
|
||||
grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
request_id = gpr_stack_lockfree_pop(rm->requests);
|
||||
int request_id = gpr_stack_lockfree_pop(rm->requests);
|
||||
if (request_id == -1) {
|
||||
gpr_mu_lock(&server->mu_call);
|
||||
gpr_mu_lock(&calld->mu_state);
|
||||
|
|
@ -449,7 +525,41 @@ static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
|||
gpr_mu_lock(&calld->mu_state);
|
||||
calld->state = ACTIVATED;
|
||||
gpr_mu_unlock(&calld->mu_state);
|
||||
begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
|
||||
publish_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
|
||||
}
|
||||
}
|
||||
|
||||
static void finish_start_new_rpc(
|
||||
grpc_exec_ctx *exec_ctx, grpc_server *server, grpc_call_element *elem,
|
||||
request_matcher *rm,
|
||||
grpc_server_register_method_payload_handling payload_handling) {
|
||||
call_data *calld = elem->call_data;
|
||||
|
||||
if (gpr_atm_acq_load(&server->shutdown_flag)) {
|
||||
gpr_mu_lock(&calld->mu_state);
|
||||
calld->state = ZOMBIED;
|
||||
gpr_mu_unlock(&calld->mu_state);
|
||||
grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
|
||||
grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
calld->request_matcher = rm;
|
||||
|
||||
switch (payload_handling) {
|
||||
case GRPC_SRM_PAYLOAD_NONE:
|
||||
publish_new_rpc(exec_ctx, calld, true);
|
||||
break;
|
||||
case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: {
|
||||
grpc_op op;
|
||||
memset(&op, 0, sizeof(op));
|
||||
op.op = GRPC_OP_RECV_MESSAGE;
|
||||
op.data.recv_message = &calld->payload;
|
||||
grpc_closure_init(&calld->publish, publish_new_rpc, calld);
|
||||
grpc_call_start_batch_and_execute(exec_ctx, calld->call, &op, 1,
|
||||
&calld->publish);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -475,7 +585,8 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
|
|||
!calld->recv_idempotent_request)
|
||||
continue;
|
||||
finish_start_new_rpc(exec_ctx, server, elem,
|
||||
&rm->server_registered_method->request_matcher);
|
||||
&rm->server_registered_method->request_matcher,
|
||||
rm->server_registered_method->payload_handling);
|
||||
return;
|
||||
}
|
||||
/* check for a wildcard method definition (no host set) */
|
||||
|
|
@ -490,12 +601,14 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
|
|||
!calld->recv_idempotent_request)
|
||||
continue;
|
||||
finish_start_new_rpc(exec_ctx, server, elem,
|
||||
&rm->server_registered_method->request_matcher);
|
||||
&rm->server_registered_method->request_matcher,
|
||||
rm->server_registered_method->payload_handling);
|
||||
return;
|
||||
}
|
||||
}
|
||||
finish_start_new_rpc(exec_ctx, server, elem,
|
||||
&server->unregistered_request_matcher);
|
||||
&server->unregistered_request_matcher,
|
||||
GRPC_SRM_PAYLOAD_NONE);
|
||||
}
|
||||
|
||||
static int num_listeners(grpc_server *server) {
|
||||
|
|
@ -824,7 +937,7 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
|
|||
gpr_stack_lockfree_push(server->request_freelist, (int)i);
|
||||
}
|
||||
request_matcher_init(&server->unregistered_request_matcher,
|
||||
server->max_requested_calls);
|
||||
server->max_requested_calls, server);
|
||||
server->requested_calls = gpr_malloc(server->max_requested_calls *
|
||||
sizeof(*server->requested_calls));
|
||||
|
||||
|
|
@ -840,8 +953,10 @@ static int streq(const char *a, const char *b) {
|
|||
return 0 == strcmp(a, b);
|
||||
}
|
||||
|
||||
void *grpc_server_register_method(grpc_server *server, const char *method,
|
||||
const char *host, uint32_t flags) {
|
||||
void *grpc_server_register_method(
|
||||
grpc_server *server, const char *method, const char *host,
|
||||
grpc_server_register_method_payload_handling payload_handling,
|
||||
uint32_t flags) {
|
||||
registered_method *m;
|
||||
GRPC_API_TRACE(
|
||||
"grpc_server_register_method(server=%p, method=%s, host=%s, "
|
||||
|
|
@ -866,10 +981,12 @@ void *grpc_server_register_method(grpc_server *server, const char *method,
|
|||
}
|
||||
m = gpr_malloc(sizeof(registered_method));
|
||||
memset(m, 0, sizeof(*m));
|
||||
request_matcher_init(&m->request_matcher, server->max_requested_calls);
|
||||
request_matcher_init(&m->request_matcher, server->max_requested_calls,
|
||||
server);
|
||||
m->method = gpr_strdup(method);
|
||||
m->host = gpr_strdup(host);
|
||||
m->next = server->registered_methods;
|
||||
m->payload_handling = payload_handling;
|
||||
m->flags = flags;
|
||||
server->registered_methods = m;
|
||||
return m;
|
||||
|
|
@ -1143,8 +1260,8 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
|
|||
GPR_ASSERT(calld->state == PENDING);
|
||||
calld->state = ACTIVATED;
|
||||
gpr_mu_unlock(&calld->mu_state);
|
||||
begin_call(exec_ctx, server, calld,
|
||||
&server->requested_calls[request_id]);
|
||||
publish_call(exec_ctx, server, calld,
|
||||
&server->requested_calls[request_id]);
|
||||
}
|
||||
gpr_mu_lock(&server->mu_call);
|
||||
}
|
||||
|
|
@ -1209,6 +1326,12 @@ grpc_call_error grpc_server_request_registered_call(
|
|||
error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
|
||||
goto done;
|
||||
}
|
||||
if ((optional_payload == NULL) !=
|
||||
(rm->payload_handling == GRPC_SRM_PAYLOAD_NONE)) {
|
||||
gpr_free(rc);
|
||||
error = GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH;
|
||||
goto done;
|
||||
}
|
||||
grpc_cq_begin_op(cq_for_notification, tag);
|
||||
rc->type = REGISTERED_CALL;
|
||||
rc->server = server;
|
||||
|
|
@ -1226,86 +1349,6 @@ done:
|
|||
return error;
|
||||
}
|
||||
|
||||
static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
|
||||
void *user_data, bool success);
|
||||
|
||||
static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
|
||||
gpr_slice slice = value->slice;
|
||||
size_t len = GPR_SLICE_LENGTH(slice);
|
||||
|
||||
if (len + 1 > *capacity) {
|
||||
*capacity = GPR_MAX(len + 1, *capacity * 2);
|
||||
*dest = gpr_realloc(*dest, *capacity);
|
||||
}
|
||||
memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
|
||||
}
|
||||
|
||||
static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
||||
call_data *calld, requested_call *rc) {
|
||||
grpc_op ops[1];
|
||||
grpc_op *op = ops;
|
||||
|
||||
memset(ops, 0, sizeof(ops));
|
||||
|
||||
/* called once initial metadata has been read by the call, but BEFORE
|
||||
the ioreq to fetch it out of the call has been executed.
|
||||
This means metadata related fields can be relied on in calld, but to
|
||||
fill in the metadata array passed by the client, we need to perform
|
||||
an ioreq op, that should complete immediately. */
|
||||
|
||||
grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
|
||||
grpc_closure_init(&rc->publish, publish_registered_or_batch, rc);
|
||||
*rc->call = calld->call;
|
||||
calld->cq_new = rc->cq_for_notification;
|
||||
GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
|
||||
switch (rc->type) {
|
||||
case BATCH_CALL:
|
||||
GPR_ASSERT(calld->host != NULL);
|
||||
GPR_ASSERT(calld->path != NULL);
|
||||
cpstr(&rc->data.batch.details->host,
|
||||
&rc->data.batch.details->host_capacity, calld->host);
|
||||
cpstr(&rc->data.batch.details->method,
|
||||
&rc->data.batch.details->method_capacity, calld->path);
|
||||
rc->data.batch.details->deadline = calld->deadline;
|
||||
rc->data.batch.details->flags =
|
||||
0 | (calld->recv_idempotent_request
|
||||
? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
|
||||
: 0);
|
||||
break;
|
||||
case REGISTERED_CALL:
|
||||
*rc->data.registered.deadline = calld->deadline;
|
||||
if (rc->data.registered.optional_payload) {
|
||||
op->op = GRPC_OP_RECV_MESSAGE;
|
||||
op->data.recv_message = rc->data.registered.optional_payload;
|
||||
op++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
GPR_UNREACHABLE_CODE(return );
|
||||
}
|
||||
|
||||
GRPC_CALL_INTERNAL_REF(calld->call, "server");
|
||||
grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops,
|
||||
(size_t)(op - ops), &rc->publish);
|
||||
}
|
||||
|
||||
static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
|
||||
grpc_cq_completion *c) {
|
||||
requested_call *rc = req;
|
||||
grpc_server *server = rc->server;
|
||||
|
||||
if (rc >= server->requested_calls &&
|
||||
rc < server->requested_calls + server->max_requested_calls) {
|
||||
GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
|
||||
gpr_stack_lockfree_push(server->request_freelist,
|
||||
(int)(rc - server->requested_calls));
|
||||
} else {
|
||||
gpr_free(req);
|
||||
}
|
||||
|
||||
server_unref(exec_ctx, server);
|
||||
}
|
||||
|
||||
static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
||||
requested_call *rc) {
|
||||
*rc->call = NULL;
|
||||
|
|
@ -1316,20 +1359,6 @@ static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
|
|||
done_request_event, rc, &rc->completion);
|
||||
}
|
||||
|
||||
static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
|
||||
bool success) {
|
||||
requested_call *rc = prc;
|
||||
grpc_call *call = *rc->call;
|
||||
grpc_call_element *elem =
|
||||
grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
|
||||
call_data *calld = elem->call_data;
|
||||
channel_data *chand = elem->channel_data;
|
||||
server_ref(chand->server);
|
||||
grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
|
||||
rc, &rc->completion);
|
||||
GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
|
||||
}
|
||||
|
||||
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
|
||||
return server->channel_args;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,9 +101,9 @@ typedef struct grpc_transport_stream_op {
|
|||
/** Send initial metadata to the peer, from the provided metadata batch.
|
||||
idempotent_request MUST be set if this is non-null */
|
||||
grpc_metadata_batch *send_initial_metadata;
|
||||
/** Iff send_initial_metadata != NULL, flags if this is an idempotent request
|
||||
or not */
|
||||
bool send_idempotent_request;
|
||||
/** Iff send_initial_metadata != NULL, flags associated with
|
||||
send_initial_metadata: a bitfield of GRPC_INITIAL_METADATA_xxx */
|
||||
uint32_t send_initial_metadata_flags;
|
||||
|
||||
/** Send trailing metadata to the peer, from the provided metadata batch. */
|
||||
grpc_metadata_batch *send_trailing_metadata;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ static ClientContext::GlobalCallbacks* g_client_callbacks =
|
|||
|
||||
ClientContext::ClientContext()
|
||||
: initial_metadata_received_(false),
|
||||
fail_fast_(true),
|
||||
idempotent_(false),
|
||||
call_(nullptr),
|
||||
call_canceled_(false),
|
||||
deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)),
|
||||
|
|
|
|||
|
|
@ -321,6 +321,19 @@ void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) {
|
|||
g_callbacks.reset(callbacks);
|
||||
}
|
||||
|
||||
static grpc_server_register_method_payload_handling PayloadHandlingForMethod(
|
||||
RpcServiceMethod* method) {
|
||||
switch (method->method_type()) {
|
||||
case RpcMethod::NORMAL_RPC:
|
||||
case RpcMethod::SERVER_STREAMING:
|
||||
return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER;
|
||||
case RpcMethod::CLIENT_STREAMING:
|
||||
case RpcMethod::BIDI_STREAMING:
|
||||
return GRPC_SRM_PAYLOAD_NONE;
|
||||
}
|
||||
GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;);
|
||||
}
|
||||
|
||||
bool Server::RegisterService(const grpc::string* host, Service* service) {
|
||||
bool has_async_methods = service->has_async_methods();
|
||||
if (has_async_methods) {
|
||||
|
|
@ -334,8 +347,9 @@ bool Server::RegisterService(const grpc::string* host, Service* service) {
|
|||
continue;
|
||||
}
|
||||
RpcServiceMethod* method = it->get();
|
||||
void* tag = grpc_server_register_method(server_, method->name(),
|
||||
host ? host->c_str() : nullptr, 0);
|
||||
void* tag = grpc_server_register_method(
|
||||
server_, method->name(), host ? host->c_str() : nullptr,
|
||||
PayloadHandlingForMethod(method), 0);
|
||||
if (tag == nullptr) {
|
||||
gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
|
||||
method->name());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core.Internal;
|
||||
|
||||
namespace Grpc.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstraction of client-side RPC invocation.
|
||||
/// </summary>
|
||||
/// <seealso cref="Calls"/>
|
||||
public abstract class CallInvoker
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes a simple remote call in a blocking fashion.
|
||||
/// </summary>
|
||||
public abstract TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
where TRequest : class
|
||||
where TResponse : class;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a simple remote call asynchronously.
|
||||
/// </summary>
|
||||
public abstract AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
where TRequest : class
|
||||
where TResponse : class;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a server streaming call asynchronously.
|
||||
/// In server streaming scenario, client sends on request and server responds with a stream of responses.
|
||||
/// </summary>
|
||||
public abstract AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
where TRequest : class
|
||||
where TResponse : class;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a client streaming call asynchronously.
|
||||
/// In client streaming scenario, client sends a stream of requests and server responds with a single response.
|
||||
/// </summary>
|
||||
public abstract AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
where TRequest : class
|
||||
where TResponse : class;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a duplex streaming call asynchronously.
|
||||
/// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses.
|
||||
/// The response stream is completely independent and both side can be sending messages at the same time.
|
||||
/// </summary>
|
||||
public abstract AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
where TRequest : class
|
||||
where TResponse : class;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -31,93 +31,156 @@
|
|||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core.Internal;
|
||||
using Grpc.Core.Utils;
|
||||
|
||||
namespace Grpc.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Interceptor for call headers.
|
||||
/// Generic base class for client-side stubs.
|
||||
/// </summary>
|
||||
/// <remarks>Header interceptor is no longer to recommented way to perform authentication.
|
||||
/// For header (initial metadata) based auth such as OAuth2 or JWT access token, use <see cref="MetadataCredentials"/>.
|
||||
/// </remarks>
|
||||
public delegate void HeaderInterceptor(IMethod method, Metadata metadata);
|
||||
public abstract class ClientBase<T> : ClientBase
|
||||
where T : ClientBase<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ClientBase</c> class that
|
||||
/// throws <c>NotImplementedException</c> upon invocation of any RPC.
|
||||
/// This constructor is only provided to allow creation of test doubles
|
||||
/// for client classes (e.g. mocking requires a parameterless constructor).
|
||||
/// </summary>
|
||||
protected ClientBase() : base()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ClientBase</c> class.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration.</param>
|
||||
protected ClientBase(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ClientBase</c> class.
|
||||
/// </summary>
|
||||
/// <param name="channel">The channel to use for remote call invocation.</param>
|
||||
public ClientBase(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ClientBase</c> class.
|
||||
/// </summary>
|
||||
/// <param name="callInvoker">The <c>CallInvoker</c> for remote call invocation.</param>
|
||||
public ClientBase(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new client that sets host field for calls explicitly.
|
||||
/// gRPC supports multiple "hosts" being served by a single server.
|
||||
/// By default (if a client was not created by calling this method),
|
||||
/// host <c>null</c> with the meaning "use default host" is used.
|
||||
/// </summary>
|
||||
public T WithHost(string host)
|
||||
{
|
||||
var newConfiguration = this.Configuration.WithHost(host);
|
||||
return NewInstance(newConfiguration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of client from given <c>ClientBaseConfiguration</c>.
|
||||
/// </summary>
|
||||
protected abstract T NewInstance(ClientBaseConfiguration configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for client-side stubs.
|
||||
/// </summary>
|
||||
public abstract class ClientBase
|
||||
{
|
||||
readonly Channel channel;
|
||||
readonly ClientBaseConfiguration configuration;
|
||||
readonly CallInvoker callInvoker;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ClientBase</c> class that
|
||||
/// throws <c>NotImplementedException</c> upon invocation of any RPC.
|
||||
/// This constructor is only provided to allow creation of test doubles
|
||||
/// for client classes (e.g. mocking requires a parameterless constructor).
|
||||
/// </summary>
|
||||
protected ClientBase() : this(new UnimplementedCallInvoker())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ClientBase</c> class.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration.</param>
|
||||
protected ClientBase(ClientBaseConfiguration configuration)
|
||||
{
|
||||
this.configuration = GrpcPreconditions.CheckNotNull(configuration, "configuration");
|
||||
this.callInvoker = configuration.CreateDecoratedCallInvoker();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <c>ClientBase</c> class.
|
||||
/// </summary>
|
||||
/// <param name="channel">The channel to use for remote call invocation.</param>
|
||||
public ClientBase(Channel channel)
|
||||
public ClientBase(Channel channel) : this(new DefaultCallInvoker(channel))
|
||||
{
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can be used to register a custom header interceptor.
|
||||
/// The interceptor is invoked each time a new call on this client is started.
|
||||
/// It is not recommented to use header interceptor to add auth headers to RPC calls.
|
||||
/// Initializes a new instance of <c>ClientBase</c> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="HeaderInterceptor"/>
|
||||
public HeaderInterceptor HeaderInterceptor
|
||||
/// <param name="callInvoker">The <c>CallInvoker</c> for remote call invocation.</param>
|
||||
public ClientBase(CallInvoker callInvoker) : this(new ClientBaseConfiguration(callInvoker, null))
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gRPC supports multiple "hosts" being served by a single server.
|
||||
/// This property can be used to set the target host explicitly.
|
||||
/// By default, this will be set to <c>null</c> with the meaning
|
||||
/// "use default host".
|
||||
/// Gets the call invoker.
|
||||
/// </summary>
|
||||
public string Host
|
||||
protected CallInvoker CallInvoker
|
||||
{
|
||||
get;
|
||||
set;
|
||||
get { return this.callInvoker; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Channel associated with this client.
|
||||
/// Gets the configuration.
|
||||
/// </summary>
|
||||
public Channel Channel
|
||||
internal ClientBaseConfiguration Configuration
|
||||
{
|
||||
get
|
||||
get { return this.configuration; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents configuration of ClientBase. The class itself is visible to
|
||||
/// subclasses, but contents are marked as internal to make the instances opaque.
|
||||
/// The verbose name of this class was chosen to make name clash in generated code
|
||||
/// less likely.
|
||||
/// </summary>
|
||||
protected internal class ClientBaseConfiguration
|
||||
{
|
||||
readonly CallInvoker undecoratedCallInvoker;
|
||||
readonly string host;
|
||||
|
||||
internal ClientBaseConfiguration(CallInvoker undecoratedCallInvoker, string host)
|
||||
{
|
||||
return this.channel;
|
||||
this.undecoratedCallInvoker = GrpcPreconditions.CheckNotNull(undecoratedCallInvoker);
|
||||
this.host = host;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new call to given method.
|
||||
/// </summary>
|
||||
/// <param name="method">The method to invoke.</param>
|
||||
/// <param name="options">The call options.</param>
|
||||
/// <typeparam name="TRequest">Request message type.</typeparam>
|
||||
/// <typeparam name="TResponse">Response message type.</typeparam>
|
||||
/// <returns>The call invocation details.</returns>
|
||||
protected CallInvocationDetails<TRequest, TResponse> CreateCall<TRequest, TResponse>(Method<TRequest, TResponse> method, CallOptions options)
|
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{
|
||||
var interceptor = HeaderInterceptor;
|
||||
if (interceptor != null)
|
||||
internal CallInvoker CreateDecoratedCallInvoker()
|
||||
{
|
||||
if (options.Headers == null)
|
||||
{
|
||||
options = options.WithHeaders(new Metadata());
|
||||
}
|
||||
interceptor(method, options.Headers);
|
||||
return new InterceptingCallInvoker(undecoratedCallInvoker, hostInterceptor: (h) => host);
|
||||
}
|
||||
|
||||
internal ClientBaseConfiguration WithHost(string host)
|
||||
{
|
||||
GrpcPreconditions.CheckNotNull(host, "host");
|
||||
return new ClientBaseConfiguration(this.undecoratedCallInvoker, host);
|
||||
}
|
||||
return new CallInvocationDetails<TRequest, TResponse>(channel, method, Host, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core.Internal;
|
||||
using Grpc.Core.Utils;
|
||||
|
||||
namespace Grpc.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes client RPCs using <see cref="Calls"/>.
|
||||
/// </summary>
|
||||
public class DefaultCallInvoker : CallInvoker
|
||||
{
|
||||
readonly Channel channel;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Grpc.Core.DefaultCallInvoker"/> class.
|
||||
/// </summary>
|
||||
/// <param name="channel">Channel to use.</param>
|
||||
public DefaultCallInvoker(Channel channel)
|
||||
{
|
||||
this.channel = GrpcPreconditions.CheckNotNull(channel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a simple remote call in a blocking fashion.
|
||||
/// </summary>
|
||||
public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
var call = CreateCall(method, host, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a simple remote call asynchronously.
|
||||
/// </summary>
|
||||
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
var call = CreateCall(method, host, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a server streaming call asynchronously.
|
||||
/// In server streaming scenario, client sends on request and server responds with a stream of responses.
|
||||
/// </summary>
|
||||
public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
var call = CreateCall(method, host, options);
|
||||
return Calls.AsyncServerStreamingCall(call, request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a client streaming call asynchronously.
|
||||
/// In client streaming scenario, client sends a stream of requests and server responds with a single response.
|
||||
/// </summary>
|
||||
public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(method, host, options);
|
||||
return Calls.AsyncClientStreamingCall(call);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a duplex streaming call asynchronously.
|
||||
/// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses.
|
||||
/// The response stream is completely independent and both side can be sending messages at the same time.
|
||||
/// </summary>
|
||||
public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(method, host, options);
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
}
|
||||
|
||||
protected virtual CallInvocationDetails<TRequest, TResponse> CreateCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{
|
||||
return new CallInvocationDetails<TRequest, TResponse>(channel, method, host, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -129,6 +129,10 @@
|
|||
<Compile Include="Profiling\Profilers.cs" />
|
||||
<Compile Include="Internal\DefaultSslRootsOverride.cs" />
|
||||
<Compile Include="Utils\GrpcPreconditions.cs" />
|
||||
<Compile Include="CallInvoker.cs" />
|
||||
<Compile Include="DefaultCallInvoker.cs" />
|
||||
<Compile Include="Internal\UnimplementedCallInvoker.cs" />
|
||||
<Compile Include="Internal\InterceptingCallInvoker.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Grpc.Core.nuspec" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Utils;
|
||||
|
||||
namespace Grpc.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Decorates an underlying <c>CallInvoker</c> to intercept call invocations.
|
||||
/// </summary>
|
||||
internal class InterceptingCallInvoker : CallInvoker
|
||||
{
|
||||
readonly CallInvoker callInvoker;
|
||||
readonly Func<string, string> hostInterceptor;
|
||||
readonly Func<CallOptions, CallOptions> callOptionsInterceptor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Grpc.Core.InterceptingCallInvoker"/> class.
|
||||
/// </summary>
|
||||
public InterceptingCallInvoker(CallInvoker callInvoker,
|
||||
Func<string, string> hostInterceptor = null,
|
||||
Func<CallOptions, CallOptions> callOptionsInterceptor = null)
|
||||
{
|
||||
this.callInvoker = GrpcPreconditions.CheckNotNull(callInvoker);
|
||||
this.hostInterceptor = hostInterceptor;
|
||||
this.callOptionsInterceptor = callOptionsInterceptor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intercepts a unary call.
|
||||
/// </summary>
|
||||
public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
host = InterceptHost(host);
|
||||
options = InterceptCallOptions(options);
|
||||
return callInvoker.BlockingUnaryCall(method, host, options, request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a simple remote call asynchronously.
|
||||
/// </summary>
|
||||
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
host = InterceptHost(host);
|
||||
options = InterceptCallOptions(options);
|
||||
return callInvoker.AsyncUnaryCall(method, host, options, request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a server streaming call asynchronously.
|
||||
/// In server streaming scenario, client sends on request and server responds with a stream of responses.
|
||||
/// </summary>
|
||||
public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
host = InterceptHost(host);
|
||||
options = InterceptCallOptions(options);
|
||||
return callInvoker.AsyncServerStreamingCall(method, host, options, request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a client streaming call asynchronously.
|
||||
/// In client streaming scenario, client sends a stream of requests and server responds with a single response.
|
||||
/// </summary>
|
||||
public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
{
|
||||
host = InterceptHost(host);
|
||||
options = InterceptCallOptions(options);
|
||||
return callInvoker.AsyncClientStreamingCall(method, host, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a duplex streaming call asynchronously.
|
||||
/// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses.
|
||||
/// The response stream is completely independent and both side can be sending messages at the same time.
|
||||
/// </summary>
|
||||
public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
{
|
||||
host = InterceptHost(host);
|
||||
options = InterceptCallOptions(options);
|
||||
return callInvoker.AsyncDuplexStreamingCall(method, host, options);
|
||||
}
|
||||
|
||||
private string InterceptHost(string host)
|
||||
{
|
||||
if (hostInterceptor == null)
|
||||
{
|
||||
return host;
|
||||
}
|
||||
return hostInterceptor(host);
|
||||
}
|
||||
|
||||
private CallOptions InterceptCallOptions(CallOptions options)
|
||||
{
|
||||
if (callOptionsInterceptor == null)
|
||||
{
|
||||
return options;
|
||||
}
|
||||
return callOptionsInterceptor(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Utils;
|
||||
|
||||
namespace Grpc.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Call invoker that throws <c>NotImplementedException</c> for all requests.
|
||||
/// </summary>
|
||||
internal class UnimplementedCallInvoker : CallInvoker
|
||||
{
|
||||
public UnimplementedCallInvoker()
|
||||
{
|
||||
}
|
||||
|
||||
public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#region Copyright notice and license
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -40,7 +40,7 @@ namespace Math
|
|||
public static void Main(string[] args)
|
||||
{
|
||||
var channel = new Channel("127.0.0.1", 23456, ChannelCredentials.Insecure);
|
||||
Math.IMathClient client = new Math.MathClient(channel);
|
||||
Math.MathClient client = new Math.MathClient(channel);
|
||||
MathExamples.DivExample(client);
|
||||
|
||||
MathExamples.DivAsyncExample(client).Wait();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#region Copyright notice and license
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -38,19 +38,19 @@ namespace Math
|
|||
{
|
||||
public static class MathExamples
|
||||
{
|
||||
public static void DivExample(Math.IMathClient client)
|
||||
public static void DivExample(Math.MathClient client)
|
||||
{
|
||||
DivReply result = client.Div(new DivArgs { Dividend = 10, Divisor = 3 });
|
||||
Console.WriteLine("Div Result: " + result);
|
||||
}
|
||||
|
||||
public static async Task DivAsyncExample(Math.IMathClient client)
|
||||
public static async Task DivAsyncExample(Math.MathClient client)
|
||||
{
|
||||
DivReply result = await client.DivAsync(new DivArgs { Dividend = 4, Divisor = 5 });
|
||||
Console.WriteLine("DivAsync Result: " + result);
|
||||
}
|
||||
|
||||
public static async Task FibExample(Math.IMathClient client)
|
||||
public static async Task FibExample(Math.MathClient client)
|
||||
{
|
||||
using (var call = client.Fib(new FibArgs { Limit = 5 }))
|
||||
{
|
||||
|
|
@ -59,7 +59,7 @@ namespace Math
|
|||
}
|
||||
}
|
||||
|
||||
public static async Task SumExample(Math.IMathClient client)
|
||||
public static async Task SumExample(Math.MathClient client)
|
||||
{
|
||||
var numbers = new List<Num>
|
||||
{
|
||||
|
|
@ -75,7 +75,7 @@ namespace Math
|
|||
}
|
||||
}
|
||||
|
||||
public static async Task DivManyExample(Math.IMathClient client)
|
||||
public static async Task DivManyExample(Math.MathClient client)
|
||||
{
|
||||
var divArgsList = new List<DivArgs>
|
||||
{
|
||||
|
|
@ -90,7 +90,7 @@ namespace Math
|
|||
}
|
||||
}
|
||||
|
||||
public static async Task DependendRequestsExample(Math.IMathClient client)
|
||||
public static async Task DependendRequestsExample(Math.MathClient client)
|
||||
{
|
||||
var numbers = new List<Num>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ namespace Math {
|
|||
}
|
||||
|
||||
// client interface
|
||||
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
|
||||
public interface IMathClient
|
||||
{
|
||||
global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
@ -67,6 +68,7 @@ namespace Math {
|
|||
}
|
||||
|
||||
// server-side interface
|
||||
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
|
||||
public interface IMath
|
||||
{
|
||||
Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context);
|
||||
|
|
@ -75,61 +77,92 @@ namespace Math {
|
|||
Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context);
|
||||
}
|
||||
|
||||
// server-side abstract class
|
||||
public abstract class MathBase
|
||||
{
|
||||
public virtual Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// client stub
|
||||
public class MathClient : ClientBase, IMathClient
|
||||
public class MathClient : ClientBase<MathClient>, IMathClient
|
||||
{
|
||||
public MathClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
public global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public MathClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
|
||||
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected MathClient() : base()
|
||||
{
|
||||
var call = CreateCall(__Method_Div, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
///<summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
protected MathClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
|
||||
|
||||
public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_Div, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return Div(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_DivMany, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
|
||||
public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_DivMany, options);
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_Fib, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncServerStreamingCall(call, request);
|
||||
return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request);
|
||||
}
|
||||
public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
|
||||
public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_Fib, options);
|
||||
return Calls.AsyncServerStreamingCall(call, request);
|
||||
return DivMany(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_Sum, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncClientStreamingCall(call);
|
||||
return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
|
||||
}
|
||||
public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
|
||||
public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_Sum, options);
|
||||
return Calls.AsyncClientStreamingCall(call);
|
||||
return Fib(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request);
|
||||
}
|
||||
public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return Sum(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options);
|
||||
}
|
||||
protected override MathClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new MathClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,6 +176,16 @@ namespace Math {
|
|||
.AddMethod(__Method_Sum, serviceImpl.Sum).Build();
|
||||
}
|
||||
|
||||
// creates service definition that can be registered with a server
|
||||
public static ServerServiceDefinition BindService(MathBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder(__ServiceName)
|
||||
.AddMethod(__Method_Div, serviceImpl.Div)
|
||||
.AddMethod(__Method_DivMany, serviceImpl.DivMany)
|
||||
.AddMethod(__Method_Fib, serviceImpl.Fib)
|
||||
.AddMethod(__Method_Sum, serviceImpl.Sum).Build();
|
||||
}
|
||||
|
||||
// creates a new client
|
||||
public static MathClient NewClient(Channel channel)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -43,14 +43,14 @@ namespace Math
|
|||
/// <summary>
|
||||
/// Implementation of MathService server
|
||||
/// </summary>
|
||||
public class MathServiceImpl : Math.IMath
|
||||
public class MathServiceImpl : Math.MathBase
|
||||
{
|
||||
public Task<DivReply> Div(DivArgs request, ServerCallContext context)
|
||||
public override Task<DivReply> Div(DivArgs request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(DivInternal(request));
|
||||
}
|
||||
|
||||
public async Task Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context)
|
||||
public override async Task Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context)
|
||||
{
|
||||
if (request.Limit <= 0)
|
||||
{
|
||||
|
|
@ -72,7 +72,7 @@ namespace Math
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
|
||||
public override async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
|
||||
{
|
||||
long sum = 0;
|
||||
await requestStream.ForEachAsync(async num =>
|
||||
|
|
@ -82,7 +82,7 @@ namespace Math
|
|||
return new Num { Num_ = sum };
|
||||
}
|
||||
|
||||
public async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
|
||||
public override async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
|
||||
{
|
||||
await requestStream.ForEachAsync(async divArgs => await responseStream.WriteAsync(DivInternal(divArgs)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace Grpc.HealthCheck.Tests
|
|||
const string Host = "localhost";
|
||||
Server server;
|
||||
Channel channel;
|
||||
Grpc.Health.V1.Health.IHealthClient client;
|
||||
Grpc.Health.V1.Health.HealthClient client;
|
||||
Grpc.HealthCheck.HealthServiceImpl serviceImpl;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace Grpc.Health.V1 {
|
|||
}
|
||||
|
||||
// client interface
|
||||
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
|
||||
public interface IHealthClient
|
||||
{
|
||||
global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
@ -38,36 +39,59 @@ namespace Grpc.Health.V1 {
|
|||
}
|
||||
|
||||
// server-side interface
|
||||
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
|
||||
public interface IHealth
|
||||
{
|
||||
Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context);
|
||||
}
|
||||
|
||||
// server-side abstract class
|
||||
public abstract class HealthBase
|
||||
{
|
||||
public virtual Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// client stub
|
||||
public class HealthClient : ClientBase, IHealthClient
|
||||
public class HealthClient : ClientBase<HealthClient>, IHealthClient
|
||||
{
|
||||
public HealthClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public HealthClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
|
||||
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected HealthClient() : base()
|
||||
{
|
||||
var call = CreateCall(__Method_Check, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
///<summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
protected HealthClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
|
||||
|
||||
public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_Check, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return Check(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request);
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return CheckAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request);
|
||||
}
|
||||
protected override HealthClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new HealthClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,6 +102,13 @@ namespace Grpc.Health.V1 {
|
|||
.AddMethod(__Method_Check, serviceImpl.Check).Build();
|
||||
}
|
||||
|
||||
// creates service definition that can be registered with a server
|
||||
public static ServerServiceDefinition BindService(HealthBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder(__ServiceName)
|
||||
.AddMethod(__Method_Check, serviceImpl.Check).Build();
|
||||
}
|
||||
|
||||
// creates a new client
|
||||
public static HealthClient NewClient(Channel channel)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace Grpc.HealthCheck
|
|||
/// server.AddServiceDefinition(Grpc.Health.V1.Health.BindService(serviceImpl));
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public class HealthServiceImpl : Grpc.Health.V1.Health.IHealth
|
||||
public class HealthServiceImpl : Grpc.Health.V1.Health.HealthBase
|
||||
{
|
||||
private readonly object myLock = new object();
|
||||
private readonly Dictionary<string, HealthCheckResponse.Types.ServingStatus> statusMap =
|
||||
|
|
@ -99,7 +99,7 @@ namespace Grpc.HealthCheck
|
|||
/// <param name="request">The check request.</param>
|
||||
/// <param name="context">The call context.</param>
|
||||
/// <returns>The asynchronous response.</returns>
|
||||
public Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
|
||||
public override Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
|
||||
{
|
||||
lock (myLock)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -44,19 +44,19 @@ namespace Grpc.Testing
|
|||
/// <summary>
|
||||
/// Implementation of BenchmarkService server
|
||||
/// </summary>
|
||||
public class BenchmarkServiceImpl : BenchmarkService.IBenchmarkService
|
||||
public class BenchmarkServiceImpl : BenchmarkService.BenchmarkServiceBase
|
||||
{
|
||||
public BenchmarkServiceImpl()
|
||||
{
|
||||
}
|
||||
|
||||
public Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
|
||||
public override Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
|
||||
{
|
||||
var response = new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) };
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
|
||||
public async Task StreamingCall(IAsyncStreamReader<SimpleRequest> requestStream, IServerStreamWriter<SimpleResponse> responseStream, ServerCallContext context)
|
||||
public override async Task StreamingCall(IAsyncStreamReader<SimpleRequest> requestStream, IServerStreamWriter<SimpleResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
await requestStream.ForEachAsync(async request =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,15 +61,7 @@ namespace Grpc.IntegrationTesting
|
|||
public static IClientRunner CreateStarted(ClientConfig config)
|
||||
{
|
||||
Logger.Debug("ClientConfig: {0}", config);
|
||||
string target = config.ServerTargets.Single();
|
||||
GrpcPreconditions.CheckArgument(config.LoadParams.LoadCase == LoadParams.LoadOneofCase.ClosedLoop,
|
||||
"Only closed loop scenario supported for C#");
|
||||
GrpcPreconditions.CheckArgument(config.ClientChannels == 1, "ClientConfig.ClientChannels needs to be 1");
|
||||
|
||||
if (config.OutstandingRpcsPerChannel != 0)
|
||||
{
|
||||
Logger.Warning("ClientConfig.OutstandingRpcsPerChannel is not supported for C#. Ignoring the value");
|
||||
}
|
||||
if (config.AsyncClientThreads != 0)
|
||||
{
|
||||
Logger.Warning("ClientConfig.AsyncClientThreads is not supported for C#. Ignoring the value");
|
||||
|
|
@ -83,22 +75,40 @@ namespace Grpc.IntegrationTesting
|
|||
Logger.Warning("ClientConfig.CoreList is not supported for C#. Ignoring the value");
|
||||
}
|
||||
|
||||
var credentials = config.SecurityParams != null ? TestCredentials.CreateSslCredentials() : ChannelCredentials.Insecure;
|
||||
var channels = CreateChannels(config.ClientChannels, config.ServerTargets, config.SecurityParams);
|
||||
|
||||
return new ClientRunnerImpl(channels,
|
||||
config.ClientType,
|
||||
config.RpcType,
|
||||
config.OutstandingRpcsPerChannel,
|
||||
config.LoadParams,
|
||||
config.PayloadConfig,
|
||||
config.HistogramParams);
|
||||
}
|
||||
|
||||
private static List<Channel> CreateChannels(int clientChannels, IEnumerable<string> serverTargets, SecurityParams securityParams)
|
||||
{
|
||||
GrpcPreconditions.CheckArgument(clientChannels > 0, "clientChannels needs to be at least 1.");
|
||||
GrpcPreconditions.CheckArgument(serverTargets.Count() > 0, "at least one serverTarget needs to be specified.");
|
||||
|
||||
var credentials = securityParams != null ? TestCredentials.CreateSslCredentials() : ChannelCredentials.Insecure;
|
||||
List<ChannelOption> channelOptions = null;
|
||||
if (config.SecurityParams != null && config.SecurityParams.ServerHostOverride != "")
|
||||
if (securityParams != null && securityParams.ServerHostOverride != "")
|
||||
{
|
||||
channelOptions = new List<ChannelOption>
|
||||
{
|
||||
new ChannelOption(ChannelOptions.SslTargetNameOverride, config.SecurityParams.ServerHostOverride)
|
||||
new ChannelOption(ChannelOptions.SslTargetNameOverride, securityParams.ServerHostOverride)
|
||||
};
|
||||
}
|
||||
var channel = new Channel(target, credentials, channelOptions);
|
||||
|
||||
return new ClientRunnerImpl(channel,
|
||||
config.ClientType,
|
||||
config.RpcType,
|
||||
config.PayloadConfig,
|
||||
config.HistogramParams);
|
||||
var result = new List<Channel>();
|
||||
for (int i = 0; i < clientChannels; i++)
|
||||
{
|
||||
var target = serverTargets.ElementAt(i % serverTargets.Count());
|
||||
var channel = new Channel(target, credentials, channelOptions);
|
||||
result.Add(channel);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,30 +116,35 @@ namespace Grpc.IntegrationTesting
|
|||
{
|
||||
const double SecondsToNanos = 1e9;
|
||||
|
||||
readonly Channel channel;
|
||||
readonly List<Channel> channels;
|
||||
readonly ClientType clientType;
|
||||
readonly RpcType rpcType;
|
||||
readonly PayloadConfig payloadConfig;
|
||||
readonly Histogram histogram;
|
||||
|
||||
readonly BenchmarkService.IBenchmarkServiceClient client;
|
||||
readonly Task runnerTask;
|
||||
readonly CancellationTokenSource stoppedCts;
|
||||
readonly List<Task> runnerTasks;
|
||||
readonly CancellationTokenSource stoppedCts = new CancellationTokenSource();
|
||||
readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
|
||||
|
||||
public ClientRunnerImpl(Channel channel, ClientType clientType, RpcType rpcType, PayloadConfig payloadConfig, HistogramParams histogramParams)
|
||||
public ClientRunnerImpl(List<Channel> channels, ClientType clientType, RpcType rpcType, int outstandingRpcsPerChannel, LoadParams loadParams, PayloadConfig payloadConfig, HistogramParams histogramParams)
|
||||
{
|
||||
this.channel = GrpcPreconditions.CheckNotNull(channel);
|
||||
GrpcPreconditions.CheckArgument(outstandingRpcsPerChannel > 0, "outstandingRpcsPerChannel");
|
||||
this.channels = new List<Channel>(channels);
|
||||
this.clientType = clientType;
|
||||
this.rpcType = rpcType;
|
||||
this.payloadConfig = payloadConfig;
|
||||
this.histogram = new Histogram(histogramParams.Resolution, histogramParams.MaxPossible);
|
||||
|
||||
this.stoppedCts = new CancellationTokenSource();
|
||||
this.client = BenchmarkService.NewClient(channel);
|
||||
|
||||
var threadBody = GetThreadBody();
|
||||
this.runnerTask = Task.Factory.StartNew(threadBody, TaskCreationOptions.LongRunning);
|
||||
this.runnerTasks = new List<Task>();
|
||||
foreach (var channel in this.channels)
|
||||
{
|
||||
for (int i = 0; i < outstandingRpcsPerChannel; i++)
|
||||
{
|
||||
var timer = CreateTimer(loadParams, 1.0 / this.channels.Count / outstandingRpcsPerChannel);
|
||||
var threadBody = GetThreadBody(channel, timer);
|
||||
this.runnerTasks.Add(Task.Factory.StartNew(threadBody, TaskCreationOptions.LongRunning));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ClientStats GetStats(bool reset)
|
||||
|
|
@ -150,12 +165,19 @@ namespace Grpc.IntegrationTesting
|
|||
public async Task StopAsync()
|
||||
{
|
||||
stoppedCts.Cancel();
|
||||
await runnerTask;
|
||||
await channel.ShutdownAsync();
|
||||
foreach (var runnerTask in runnerTasks)
|
||||
{
|
||||
await runnerTask;
|
||||
}
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
await channel.ShutdownAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void RunClosedLoopUnary()
|
||||
private void RunUnary(Channel channel, IInterarrivalTimer timer)
|
||||
{
|
||||
var client = BenchmarkService.NewClient(channel);
|
||||
var request = CreateSimpleRequest();
|
||||
var stopwatch = new Stopwatch();
|
||||
|
||||
|
|
@ -167,11 +189,14 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
// spec requires data point in nanoseconds.
|
||||
histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos);
|
||||
|
||||
timer.WaitForNext();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunClosedLoopUnaryAsync()
|
||||
private async Task RunUnaryAsync(Channel channel, IInterarrivalTimer timer)
|
||||
{
|
||||
var client = BenchmarkService.NewClient(channel);
|
||||
var request = CreateSimpleRequest();
|
||||
var stopwatch = new Stopwatch();
|
||||
|
||||
|
|
@ -183,11 +208,14 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
// spec requires data point in nanoseconds.
|
||||
histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos);
|
||||
|
||||
await timer.WaitForNextAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunClosedLoopStreamingAsync()
|
||||
private async Task RunStreamingPingPongAsync(Channel channel, IInterarrivalTimer timer)
|
||||
{
|
||||
var client = BenchmarkService.NewClient(channel);
|
||||
var request = CreateSimpleRequest();
|
||||
var stopwatch = new Stopwatch();
|
||||
|
||||
|
|
@ -202,6 +230,8 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
// spec requires data point in nanoseconds.
|
||||
histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos);
|
||||
|
||||
await timer.WaitForNextAsync();
|
||||
}
|
||||
|
||||
// finish the streaming call
|
||||
|
|
@ -210,7 +240,7 @@ namespace Grpc.IntegrationTesting
|
|||
}
|
||||
}
|
||||
|
||||
private async Task RunGenericClosedLoopStreamingAsync()
|
||||
private async Task RunGenericStreamingAsync(Channel channel, IInterarrivalTimer timer)
|
||||
{
|
||||
var request = CreateByteBufferRequest();
|
||||
var stopwatch = new Stopwatch();
|
||||
|
|
@ -228,6 +258,8 @@ namespace Grpc.IntegrationTesting
|
|||
|
||||
// spec requires data point in nanoseconds.
|
||||
histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos);
|
||||
|
||||
await timer.WaitForNextAsync();
|
||||
}
|
||||
|
||||
// finish the streaming call
|
||||
|
|
@ -236,7 +268,7 @@ namespace Grpc.IntegrationTesting
|
|||
}
|
||||
}
|
||||
|
||||
private Action GetThreadBody()
|
||||
private Action GetThreadBody(Channel channel, IInterarrivalTimer timer)
|
||||
{
|
||||
if (payloadConfig.PayloadCase == PayloadConfig.PayloadOneofCase.BytebufParams)
|
||||
{
|
||||
|
|
@ -244,7 +276,7 @@ namespace Grpc.IntegrationTesting
|
|||
GrpcPreconditions.CheckArgument(rpcType == RpcType.STREAMING, "Generic client only supports streaming calls");
|
||||
return () =>
|
||||
{
|
||||
RunGenericClosedLoopStreamingAsync().Wait();
|
||||
RunGenericStreamingAsync(channel, timer).Wait();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +284,7 @@ namespace Grpc.IntegrationTesting
|
|||
if (clientType == ClientType.SYNC_CLIENT)
|
||||
{
|
||||
GrpcPreconditions.CheckArgument(rpcType == RpcType.UNARY, "Sync client can only be used for Unary calls in C#");
|
||||
return RunClosedLoopUnary;
|
||||
return () => RunUnary(channel, timer);
|
||||
}
|
||||
else if (clientType == ClientType.ASYNC_CLIENT)
|
||||
{
|
||||
|
|
@ -261,12 +293,12 @@ namespace Grpc.IntegrationTesting
|
|||
case RpcType.UNARY:
|
||||
return () =>
|
||||
{
|
||||
RunClosedLoopUnaryAsync().Wait();
|
||||
RunUnaryAsync(channel, timer).Wait();
|
||||
};
|
||||
case RpcType.STREAMING:
|
||||
return () =>
|
||||
{
|
||||
RunClosedLoopStreamingAsync().Wait();
|
||||
RunStreamingPingPongAsync(channel, timer).Wait();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -292,5 +324,18 @@ namespace Grpc.IntegrationTesting
|
|||
{
|
||||
return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
|
||||
}
|
||||
|
||||
private static IInterarrivalTimer CreateTimer(LoadParams loadParams, double loadMultiplier)
|
||||
{
|
||||
switch (loadParams.LoadCase)
|
||||
{
|
||||
case LoadParams.LoadOneofCase.ClosedLoop:
|
||||
return new ClosedLoopInterarrivalTimer();
|
||||
case LoadParams.LoadOneofCase.Poisson:
|
||||
return new PoissonInterarrivalTimer(loadParams.Poisson.OfferedLoad * loadMultiplier);
|
||||
default:
|
||||
throw new ArgumentException("Unknown load type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Utils;
|
||||
using Grpc.Testing;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Grpc.IntegrationTesting
|
||||
{
|
||||
public class GeneratedClientTest
|
||||
{
|
||||
TestService.TestServiceClient unimplementedClient = new UnimplementedTestServiceClient();
|
||||
|
||||
[Test]
|
||||
public void ExpandedParamOverloadCanBeMocked()
|
||||
{
|
||||
var expected = new SimpleResponse();
|
||||
|
||||
var mockClient = new Mock<TestService.TestServiceClient>();
|
||||
// mocking is relatively clumsy because one needs to specify value for all the optional params.
|
||||
mockClient.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), null, null, CancellationToken.None)).Returns(expected);
|
||||
|
||||
Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CallOptionsOverloadCanBeMocked()
|
||||
{
|
||||
var expected = new SimpleResponse();
|
||||
|
||||
var mockClient = new Mock<TestService.TestServiceClient>();
|
||||
mockClient.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), It.IsAny<CallOptions>())).Returns(expected);
|
||||
|
||||
Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest(), new CallOptions()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultMethodStubThrows_UnaryCall()
|
||||
{
|
||||
Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.UnaryCall(new SimpleRequest()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultMethodStubThrows_ClientStreaming()
|
||||
{
|
||||
Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.StreamingInputCall());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultMethodStubThrows_ServerStreaming()
|
||||
{
|
||||
Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.StreamingOutputCall(new StreamingOutputCallRequest()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultMethodStubThrows_DuplexStreaming()
|
||||
{
|
||||
Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.FullDuplexCall());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subclass of the generated client that doesn't override any method stubs.
|
||||
/// </summary>
|
||||
private class UnimplementedTestServiceClient : TestService.TestServiceClient
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Utils;
|
||||
using Grpc.Testing;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Grpc.IntegrationTesting
|
||||
{
|
||||
public class GeneratedServiceBaseTest
|
||||
{
|
||||
const string Host = "localhost";
|
||||
Server server;
|
||||
Channel channel;
|
||||
TestService.TestServiceClient client;
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
server = new Server
|
||||
{
|
||||
Services = { TestService.BindService(new UnimplementedTestServiceImpl()) },
|
||||
Ports = { { Host, ServerPort.PickUnused, SslServerCredentials.Insecure } }
|
||||
};
|
||||
server.Start();
|
||||
channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
|
||||
client = TestService.NewClient(channel);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
channel.ShutdownAsync().Wait();
|
||||
server.ShutdownAsync().Wait();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UnimplementedByDefault_Unary()
|
||||
{
|
||||
var ex = Assert.Throws<RpcException>(() => client.UnaryCall(new SimpleRequest { }));
|
||||
Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UnimplementedByDefault_ClientStreaming()
|
||||
{
|
||||
var call = client.StreamingInputCall();
|
||||
|
||||
var ex = Assert.Throws<RpcException>(async () => await call);
|
||||
Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UnimplementedByDefault_ServerStreamingCall()
|
||||
{
|
||||
var call = client.StreamingOutputCall(new StreamingOutputCallRequest());
|
||||
|
||||
var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
|
||||
Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UnimplementedByDefault_DuplexStreamingCall()
|
||||
{
|
||||
var call = client.FullDuplexCall();
|
||||
|
||||
var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
|
||||
Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of TestService that doesn't override any methods.
|
||||
/// </summary>
|
||||
private class UnimplementedTestServiceImpl : TestService.TestServiceBase
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +84,6 @@
|
|||
<Compile Include="..\Grpc.Core\Version.cs">
|
||||
<Link>Version.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="HeaderInterceptorTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Empty.cs" />
|
||||
<Compile Include="Messages.cs" />
|
||||
|
|
@ -114,6 +113,9 @@
|
|||
<Compile Include="QpsWorker.cs" />
|
||||
<Compile Include="WallClockStopwatch.cs" />
|
||||
<Compile Include="GenericService.cs" />
|
||||
<Compile Include="GeneratedServiceBaseTest.cs" />
|
||||
<Compile Include="GeneratedClientTest.cs" />
|
||||
<Compile Include="InterarrivalTimers.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Google.Protobuf;
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Utils;
|
||||
using Grpc.Testing;
|
||||
|
||||
namespace Grpc.IntegrationTesting
|
||||
{
|
||||
public interface IInterarrivalTimer
|
||||
{
|
||||
void WaitForNext();
|
||||
|
||||
Task WaitForNextAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interarrival timer that doesn't wait at all.
|
||||
/// </summary>
|
||||
public class ClosedLoopInterarrivalTimer : IInterarrivalTimer
|
||||
{
|
||||
public ClosedLoopInterarrivalTimer()
|
||||
{
|
||||
}
|
||||
|
||||
public void WaitForNext()
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
public Task WaitForNextAsync()
|
||||
{
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interarrival timer that generates Poisson process load.
|
||||
/// </summary>
|
||||
public class PoissonInterarrivalTimer : IInterarrivalTimer
|
||||
{
|
||||
readonly ExponentialDistribution exponentialDistribution;
|
||||
DateTime? lastEventTime;
|
||||
|
||||
public PoissonInterarrivalTimer(double offeredLoad)
|
||||
{
|
||||
this.exponentialDistribution = new ExponentialDistribution(new Random(), offeredLoad);
|
||||
this.lastEventTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public void WaitForNext()
|
||||
{
|
||||
var waitDuration = GetNextWaitDuration();
|
||||
int millisTimeout = (int) Math.Round(waitDuration.TotalMilliseconds);
|
||||
if (millisTimeout > 0)
|
||||
{
|
||||
// TODO(jtattermusch): probably only works well for a relatively low interarrival rate
|
||||
Thread.Sleep(millisTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task WaitForNextAsync()
|
||||
{
|
||||
var waitDuration = GetNextWaitDuration();
|
||||
int millisTimeout = (int) Math.Round(waitDuration.TotalMilliseconds);
|
||||
if (millisTimeout > 0)
|
||||
{
|
||||
// TODO(jtattermusch): probably only works well for a relatively low interarrival rate
|
||||
await Task.Delay(millisTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
private TimeSpan GetNextWaitDuration()
|
||||
{
|
||||
if (!lastEventTime.HasValue)
|
||||
{
|
||||
this.lastEventTime = DateTime.Now;
|
||||
}
|
||||
|
||||
var origLastEventTime = this.lastEventTime.Value;
|
||||
this.lastEventTime = origLastEventTime + TimeSpan.FromSeconds(exponentialDistribution.Next());
|
||||
return this.lastEventTime.Value - origLastEventTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exp generator.
|
||||
/// </summary>
|
||||
private class ExponentialDistribution
|
||||
{
|
||||
readonly Random random;
|
||||
readonly double lambda;
|
||||
readonly double lambdaReciprocal;
|
||||
|
||||
public ExponentialDistribution(Random random, double lambda)
|
||||
{
|
||||
this.random = random;
|
||||
this.lambda = lambda;
|
||||
this.lambdaReciprocal = 1.0 / lambda;
|
||||
}
|
||||
|
||||
public double Next()
|
||||
{
|
||||
double uniform = random.NextDouble();
|
||||
// Use 1.0-uni above to avoid NaN if uni is 0
|
||||
return lambdaReciprocal * (-Math.Log(1.0 - uniform));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -217,7 +217,7 @@ namespace Grpc.IntegrationTesting
|
|||
}
|
||||
}
|
||||
|
||||
public static void RunEmptyUnary(TestService.ITestServiceClient client)
|
||||
public static void RunEmptyUnary(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running empty_unary");
|
||||
var response = client.EmptyCall(new Empty());
|
||||
|
|
@ -225,7 +225,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunLargeUnary(TestService.ITestServiceClient client)
|
||||
public static void RunLargeUnary(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running large_unary");
|
||||
var request = new SimpleRequest
|
||||
|
|
@ -241,7 +241,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunClientStreamingAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunClientStreamingAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running client_streaming");
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunServerStreamingAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunServerStreamingAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running server_streaming");
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunPingPongAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunPingPongAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running ping_pong");
|
||||
|
||||
|
|
@ -338,7 +338,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunEmptyStreamAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunEmptyStreamAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running empty_stream");
|
||||
using (var call = client.FullDuplexCall())
|
||||
|
|
@ -434,7 +434,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunCancelAfterBeginAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running cancel_after_begin");
|
||||
|
||||
|
|
@ -451,7 +451,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunCancelAfterFirstResponseAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunCancelAfterFirstResponseAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running cancel_after_first_response");
|
||||
|
||||
|
|
@ -477,7 +477,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunTimeoutOnSleepingServerAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunTimeoutOnSleepingServerAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running timeout_on_sleeping_server");
|
||||
|
||||
|
|
@ -499,7 +499,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunCustomMetadataAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunCustomMetadataAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running custom_metadata");
|
||||
{
|
||||
|
|
@ -546,7 +546,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static async Task RunStatusCodeAndMessageAsync(TestService.ITestServiceClient client)
|
||||
public static async Task RunStatusCodeAndMessageAsync(TestService.TestServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running status_code_and_message");
|
||||
var echoStatus = new EchoStatus
|
||||
|
|
@ -580,7 +580,7 @@ namespace Grpc.IntegrationTesting
|
|||
Console.WriteLine("Passed!");
|
||||
}
|
||||
|
||||
public static void RunUnimplementedMethod(UnimplementedService.IUnimplementedServiceClient client)
|
||||
public static void RunUnimplementedMethod(UnimplementedService.UnimplementedServiceClient client)
|
||||
{
|
||||
Console.WriteLine("running unimplemented_method");
|
||||
var e = Assert.Throws<RpcException>(() => client.UnimplementedCall(new Empty()));
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace Grpc.IntegrationTesting
|
|||
const string Host = "localhost";
|
||||
Server server;
|
||||
Channel channel;
|
||||
TestService.ITestServiceClient client;
|
||||
TestService.TestServiceClient client;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void Init()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -50,15 +50,15 @@ namespace Grpc.IntegrationTesting
|
|||
const string Host = "localhost";
|
||||
Server server;
|
||||
Channel channel;
|
||||
TestService.ITestServiceClient client;
|
||||
TestService.TestServiceClient client;
|
||||
List<ChannelOption> options;
|
||||
Mock<TestService.ITestService> serviceMock;
|
||||
Mock<TestService.TestServiceBase> serviceMock;
|
||||
AsyncAuthInterceptor asyncAuthInterceptor;
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
serviceMock = new Mock<TestService.ITestService>();
|
||||
serviceMock = new Mock<TestService.TestServiceBase>();
|
||||
serviceMock.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), It.IsAny<ServerCallContext>()))
|
||||
.Returns(new Func<SimpleRequest, ServerCallContext, Task<SimpleResponse>>(UnaryCallHandler));
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// client interface
|
||||
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
|
||||
public interface IBenchmarkServiceClient
|
||||
{
|
||||
global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
@ -47,47 +48,73 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// server-side interface
|
||||
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
|
||||
public interface IBenchmarkService
|
||||
{
|
||||
Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
|
||||
Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context);
|
||||
}
|
||||
|
||||
// server-side abstract class
|
||||
public abstract class BenchmarkServiceBase
|
||||
{
|
||||
public virtual Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// client stub
|
||||
public class BenchmarkServiceClient : ClientBase, IBenchmarkServiceClient
|
||||
public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>, IBenchmarkServiceClient
|
||||
{
|
||||
public BenchmarkServiceClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public BenchmarkServiceClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected BenchmarkServiceClient() : base()
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
///<summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
protected BenchmarkServiceClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
|
||||
public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_StreamingCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_StreamingCall, options);
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
|
||||
}
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return StreamingCall(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
|
||||
}
|
||||
protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new BenchmarkServiceClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,6 +126,14 @@ namespace Grpc.Testing {
|
|||
.AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
|
||||
}
|
||||
|
||||
// creates service definition that can be registered with a server
|
||||
public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder(__ServiceName)
|
||||
.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
|
||||
.AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
|
||||
}
|
||||
|
||||
// creates a new client
|
||||
public static BenchmarkServiceClient NewClient(Channel channel)
|
||||
{
|
||||
|
|
@ -153,6 +188,7 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// client interface
|
||||
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
|
||||
public interface IWorkerServiceClient
|
||||
{
|
||||
AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
@ -170,6 +206,7 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// server-side interface
|
||||
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
|
||||
public interface IWorkerService
|
||||
{
|
||||
Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context);
|
||||
|
|
@ -178,71 +215,100 @@ namespace Grpc.Testing {
|
|||
Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context);
|
||||
}
|
||||
|
||||
// server-side abstract class
|
||||
public abstract class WorkerServiceBase
|
||||
{
|
||||
public virtual Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// client stub
|
||||
public class WorkerServiceClient : ClientBase, IWorkerServiceClient
|
||||
public class WorkerServiceClient : ClientBase<WorkerServiceClient>, IWorkerServiceClient
|
||||
{
|
||||
public WorkerServiceClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public WorkerServiceClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
var call = CreateCall(__Method_RunServer, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
|
||||
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected WorkerServiceClient() : base()
|
||||
{
|
||||
var call = CreateCall(__Method_RunServer, options);
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
///<summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
protected WorkerServiceClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
var call = CreateCall(__Method_RunClient, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
|
||||
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_RunClient, options);
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return RunServer(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return CallInvoker.AsyncDuplexStreamingCall(__Method_RunServer, null, options);
|
||||
}
|
||||
public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_CoreCount, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return RunClient(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return CallInvoker.AsyncDuplexStreamingCall(__Method_RunClient, null, options);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
|
||||
public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_CoreCount, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return CoreCount(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return CallInvoker.BlockingUnaryCall(__Method_CoreCount, null, options, request);
|
||||
}
|
||||
public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_QuitWorker, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return CoreCountAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return CallInvoker.AsyncUnaryCall(__Method_CoreCount, null, options, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
|
||||
public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_QuitWorker, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return QuitWorker(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.BlockingUnaryCall(__Method_QuitWorker, null, options, request);
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return QuitWorkerAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
|
||||
}
|
||||
protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new WorkerServiceClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +322,16 @@ namespace Grpc.Testing {
|
|||
.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
|
||||
}
|
||||
|
||||
// creates service definition that can be registered with a server
|
||||
public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder(__ServiceName)
|
||||
.AddMethod(__Method_RunServer, serviceImpl.RunServer)
|
||||
.AddMethod(__Method_RunClient, serviceImpl.RunClient)
|
||||
.AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
|
||||
.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
|
||||
}
|
||||
|
||||
// creates a new client
|
||||
public static WorkerServiceClient NewClient(Channel channel)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -53,7 +53,7 @@ namespace Grpc.IntegrationTesting
|
|||
const string Host = "localhost";
|
||||
Server server;
|
||||
Channel channel;
|
||||
TestService.ITestServiceClient client;
|
||||
TestService.TestServiceClient client;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void Init()
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// client interface
|
||||
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
|
||||
public interface ITestServiceClient
|
||||
{
|
||||
global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
@ -90,6 +91,7 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// server-side interface
|
||||
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
|
||||
public interface ITestService
|
||||
{
|
||||
Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context);
|
||||
|
|
@ -100,91 +102,126 @@ namespace Grpc.Testing {
|
|||
Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
|
||||
}
|
||||
|
||||
// server-side abstract class
|
||||
public abstract class TestServiceBase
|
||||
{
|
||||
public virtual Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// client stub
|
||||
public class TestServiceClient : ClientBase, ITestServiceClient
|
||||
public class TestServiceClient : ClientBase<TestServiceClient>, ITestServiceClient
|
||||
{
|
||||
public TestServiceClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public TestServiceClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected TestServiceClient() : base()
|
||||
{
|
||||
var call = CreateCall(__Method_EmptyCall, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
///<summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
protected TestServiceClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
|
||||
public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_EmptyCall, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return EmptyCall(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return CallInvoker.BlockingUnaryCall(__Method_EmptyCall, null, options, request);
|
||||
}
|
||||
public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return EmptyCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return CallInvoker.AsyncUnaryCall(__Method_EmptyCall, null, options, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_UnaryCall, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return UnaryCall(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_StreamingOutputCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncServerStreamingCall(call, request);
|
||||
return CallInvoker.BlockingUnaryCall(__Method_UnaryCall, null, options, request);
|
||||
}
|
||||
public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_StreamingOutputCall, options);
|
||||
return Calls.AsyncServerStreamingCall(call, request);
|
||||
return UnaryCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_StreamingInputCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncClientStreamingCall(call);
|
||||
return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
|
||||
}
|
||||
public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
|
||||
public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_StreamingInputCall, options);
|
||||
return Calls.AsyncClientStreamingCall(call);
|
||||
return StreamingOutputCall(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_FullDuplexCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return CallInvoker.AsyncServerStreamingCall(__Method_StreamingOutputCall, null, options, request);
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
|
||||
public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_FullDuplexCall, options);
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return StreamingInputCall(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_HalfDuplexCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return CallInvoker.AsyncClientStreamingCall(__Method_StreamingInputCall, null, options);
|
||||
}
|
||||
public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_HalfDuplexCall, options);
|
||||
return Calls.AsyncDuplexStreamingCall(call);
|
||||
return FullDuplexCall(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncDuplexStreamingCall(__Method_FullDuplexCall, null, options);
|
||||
}
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return HalfDuplexCall(new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
|
||||
}
|
||||
protected override TestServiceClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new TestServiceClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,6 +237,18 @@ namespace Grpc.Testing {
|
|||
.AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall).Build();
|
||||
}
|
||||
|
||||
// creates service definition that can be registered with a server
|
||||
public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder(__ServiceName)
|
||||
.AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
|
||||
.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
|
||||
.AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall)
|
||||
.AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall)
|
||||
.AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall)
|
||||
.AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall).Build();
|
||||
}
|
||||
|
||||
// creates a new client
|
||||
public static TestServiceClient NewClient(Channel channel)
|
||||
{
|
||||
|
|
@ -227,6 +276,7 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// client interface
|
||||
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
|
||||
public interface IUnimplementedServiceClient
|
||||
{
|
||||
global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
@ -236,36 +286,59 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// server-side interface
|
||||
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
|
||||
public interface IUnimplementedService
|
||||
{
|
||||
Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context);
|
||||
}
|
||||
|
||||
// server-side abstract class
|
||||
public abstract class UnimplementedServiceBase
|
||||
{
|
||||
public virtual Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// client stub
|
||||
public class UnimplementedServiceClient : ClientBase, IUnimplementedServiceClient
|
||||
public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>, IUnimplementedServiceClient
|
||||
{
|
||||
public UnimplementedServiceClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
public global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public UnimplementedServiceClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
var call = CreateCall(__Method_UnimplementedCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected UnimplementedServiceClient() : base()
|
||||
{
|
||||
var call = CreateCall(__Method_UnimplementedCall, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
///<summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
protected UnimplementedServiceClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
var call = CreateCall(__Method_UnimplementedCall, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
|
||||
public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_UnimplementedCall, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return UnimplementedCall(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.BlockingUnaryCall(__Method_UnimplementedCall, null, options, request);
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return UnimplementedCallAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
|
||||
}
|
||||
protected override UnimplementedServiceClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new UnimplementedServiceClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -276,6 +349,13 @@ namespace Grpc.Testing {
|
|||
.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
|
||||
}
|
||||
|
||||
// creates service definition that can be registered with a server
|
||||
public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder(__ServiceName)
|
||||
.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
|
||||
}
|
||||
|
||||
// creates a new client
|
||||
public static UnimplementedServiceClient NewClient(Channel channel)
|
||||
{
|
||||
|
|
@ -311,6 +391,7 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// client interface
|
||||
[System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
|
||||
public interface IReconnectServiceClient
|
||||
{
|
||||
global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
@ -324,57 +405,81 @@ namespace Grpc.Testing {
|
|||
}
|
||||
|
||||
// server-side interface
|
||||
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
|
||||
public interface IReconnectService
|
||||
{
|
||||
Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.Empty request, ServerCallContext context);
|
||||
Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context);
|
||||
}
|
||||
|
||||
// server-side abstract class
|
||||
public abstract class ReconnectServiceBase
|
||||
{
|
||||
public virtual Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.Empty request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
public virtual Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// client stub
|
||||
public class ReconnectServiceClient : ClientBase, IReconnectServiceClient
|
||||
public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>, IReconnectServiceClient
|
||||
{
|
||||
public ReconnectServiceClient(Channel channel) : base(channel)
|
||||
{
|
||||
}
|
||||
public global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public ReconnectServiceClient(CallInvoker callInvoker) : base(callInvoker)
|
||||
{
|
||||
var call = CreateCall(__Method_Start, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
///<summary>Protected parameterless constructor to allow creation of test doubles.</summary>
|
||||
protected ReconnectServiceClient() : base()
|
||||
{
|
||||
var call = CreateCall(__Method_Start, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
///<summary>Protected constructor to allow creation of configured clients.</summary>
|
||||
protected ReconnectServiceClient(ClientBaseConfiguration configuration) : base(configuration)
|
||||
{
|
||||
var call = CreateCall(__Method_Start, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
|
||||
public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_Start, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return Start(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_Stop, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return CallInvoker.BlockingUnaryCall(__Method_Start, null, options, request);
|
||||
}
|
||||
public global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_Stop, options);
|
||||
return Calls.BlockingUnaryCall(call, request);
|
||||
return StartAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
var call = CreateCall(__Method_Stop, new CallOptions(headers, deadline, cancellationToken));
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return CallInvoker.AsyncUnaryCall(__Method_Start, null, options, request);
|
||||
}
|
||||
public AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var call = CreateCall(__Method_Stop, options);
|
||||
return Calls.AsyncUnaryCall(call, request);
|
||||
return Stop(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.BlockingUnaryCall(__Method_Stop, null, options, request);
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return StopAsync(request, new CallOptions(headers, deadline, cancellationToken));
|
||||
}
|
||||
public virtual AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options)
|
||||
{
|
||||
return CallInvoker.AsyncUnaryCall(__Method_Stop, null, options, request);
|
||||
}
|
||||
protected override ReconnectServiceClient NewInstance(ClientBaseConfiguration configuration)
|
||||
{
|
||||
return new ReconnectServiceClient(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,6 +491,14 @@ namespace Grpc.Testing {
|
|||
.AddMethod(__Method_Stop, serviceImpl.Stop).Build();
|
||||
}
|
||||
|
||||
// creates service definition that can be registered with a server
|
||||
public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
|
||||
{
|
||||
return ServerServiceDefinition.CreateBuilder(__ServiceName)
|
||||
.AddMethod(__Method_Start, serviceImpl.Start)
|
||||
.AddMethod(__Method_Stop, serviceImpl.Stop).Build();
|
||||
}
|
||||
|
||||
// creates a new client
|
||||
public static ReconnectServiceClient NewClient(Channel channel)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -45,14 +45,14 @@ namespace Grpc.Testing
|
|||
/// <summary>
|
||||
/// Implementation of TestService server
|
||||
/// </summary>
|
||||
public class TestServiceImpl : TestService.ITestService
|
||||
public class TestServiceImpl : TestService.TestServiceBase
|
||||
{
|
||||
public Task<Empty> EmptyCall(Empty request, ServerCallContext context)
|
||||
public override Task<Empty> EmptyCall(Empty request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
public async Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
|
||||
public override async Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context);
|
||||
EnsureEchoStatus(request.ResponseStatus, context);
|
||||
|
|
@ -61,7 +61,7 @@ namespace Grpc.Testing
|
|||
return response;
|
||||
}
|
||||
|
||||
public async Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
public override async Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context);
|
||||
EnsureEchoStatus(request.ResponseStatus, context);
|
||||
|
|
@ -73,7 +73,7 @@ namespace Grpc.Testing
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
|
||||
public override async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context);
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ namespace Grpc.Testing
|
|||
return new StreamingInputCallResponse { AggregatedPayloadSize = sum };
|
||||
}
|
||||
|
||||
public async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
public override async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
await EnsureEchoMetadataAsync(context);
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ namespace Grpc.Testing
|
|||
});
|
||||
}
|
||||
|
||||
public async Task HalfDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
public override async Task HalfDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace Grpc.Testing
|
|||
/// <summary>
|
||||
/// Implementation of WorkerService server
|
||||
/// </summary>
|
||||
public class WorkerServiceImpl : WorkerService.IWorkerService
|
||||
public class WorkerServiceImpl : WorkerService.WorkerServiceBase
|
||||
{
|
||||
readonly Action stopRequestHandler;
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ namespace Grpc.Testing
|
|||
this.stopRequestHandler = GrpcPreconditions.CheckNotNull(stopRequestHandler);
|
||||
}
|
||||
|
||||
public async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context)
|
||||
public override async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context)
|
||||
{
|
||||
GrpcPreconditions.CheckState(await requestStream.MoveNext());
|
||||
var serverConfig = requestStream.Current.Setup;
|
||||
|
|
@ -78,7 +78,7 @@ namespace Grpc.Testing
|
|||
await runner.StopAsync();
|
||||
}
|
||||
|
||||
public async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context)
|
||||
public override async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context)
|
||||
{
|
||||
GrpcPreconditions.CheckState(await requestStream.MoveNext());
|
||||
var clientConfig = requestStream.Current.Setup;
|
||||
|
|
@ -100,12 +100,12 @@ namespace Grpc.Testing
|
|||
await runner.StopAsync();
|
||||
}
|
||||
|
||||
public Task<CoreResponse> CoreCount(CoreRequest request, ServerCallContext context)
|
||||
public override Task<CoreResponse> CoreCount(CoreRequest request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(new CoreResponse { Cores = Environment.ProcessorCount });
|
||||
}
|
||||
|
||||
public Task<Void> QuitWorker(Void request, ServerCallContext context)
|
||||
public override Task<Void> QuitWorker(Void request, ServerCallContext context)
|
||||
{
|
||||
stopRequestHandler();
|
||||
return Task.FromResult(new Void());
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Native extension needed by gRPC C# library. This is not the package you are looking for, it is only meant to be used as a dependency.</description>
|
||||
<releaseNotes>Release of gRPC C core $version$ libraries.</releaseNotes>
|
||||
<copyright>Copyright 2015-2016</copyright>
|
||||
<copyright>Copyright 2015</copyright>
|
||||
<title>gRPC C# Native Extension</title>
|
||||
<summary>Native library required by gRPC C#</summary>
|
||||
<tags>gRPC native</tags>
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@
|
|||
"Math.Tests.MathClientServerTest",
|
||||
"Grpc.HealthCheck.Tests.HealthClientServerTest",
|
||||
"Grpc.HealthCheck.Tests.HealthServiceImplTest",
|
||||
"Grpc.IntegrationTesting.HeaderInterceptorTest",
|
||||
"Grpc.IntegrationTesting.HistogramTest",
|
||||
"Grpc.IntegrationTesting.GeneratedClientTest",
|
||||
"Grpc.IntegrationTesting.GeneratedServiceBaseTest",
|
||||
"Grpc.IntegrationTesting.InteropClientServerTest",
|
||||
"Grpc.IntegrationTesting.MetadataCredentialsTest",
|
||||
"Grpc.IntegrationTesting.RunnerClientServerTest",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -158,6 +158,12 @@ message StreamingOutputCallResponse {
|
|||
Payload payload = 1;
|
||||
}
|
||||
|
||||
// For reconnect interop test only.
|
||||
// Client tells server what reconnection parameters it used.
|
||||
message ReconnectParams {
|
||||
int32 max_reconnect_backoff_ms = 1;
|
||||
}
|
||||
|
||||
// For reconnect interop test only.
|
||||
// Server tells client whether its reconnects are following the spec and the
|
||||
// reconnect backoffs it saw.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -42,7 +42,7 @@ message GaugeResponse {
|
|||
string name = 1;
|
||||
oneof value {
|
||||
int64 long_value = 2;
|
||||
double double_vale = 3;
|
||||
double double_value = 3;
|
||||
string string_value = 4;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
// Copyright 2015, Google Inc.
|
||||
// Copyright 2015-2016, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -80,6 +80,6 @@ service UnimplementedService {
|
|||
|
||||
// A service used to control reconnect server.
|
||||
service ReconnectService {
|
||||
rpc Start(grpc.testing.Empty) returns (grpc.testing.Empty);
|
||||
rpc Start(grpc.testing.ReconnectParams) returns (grpc.testing.Empty);
|
||||
rpc Stop(grpc.testing.Empty) returns (grpc.testing.ReconnectInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ extern grpc_call_destroy_type grpc_call_destroy_import;
|
|||
typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
|
||||
extern grpc_server_request_call_type grpc_server_request_call_import;
|
||||
#define grpc_server_request_call grpc_server_request_call_import
|
||||
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, uint32_t flags);
|
||||
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, grpc_server_register_method_payload_handling payload_handling, uint32_t flags);
|
||||
extern grpc_server_register_method_type grpc_server_register_method_import;
|
||||
#define grpc_server_register_method grpc_server_register_method_import
|
||||
typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015-2016, Google Inc.
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ CORE_SOURCE_FILES = [
|
|||
'src/core/lib/channel/http_client_filter.c',
|
||||
'src/core/lib/channel/http_server_filter.c',
|
||||
'src/core/lib/channel/subchannel_call_holder.c',
|
||||
'src/core/lib/client_config/client_channel_factory.c',
|
||||
'src/core/lib/client_config/client_config.c',
|
||||
'src/core/lib/client_config/connector.c',
|
||||
'src/core/lib/client_config/default_initial_connect_string.c',
|
||||
|
|
@ -134,7 +135,6 @@ CORE_SOURCE_FILES = [
|
|||
'src/core/lib/client_config/resolver_factory.c',
|
||||
'src/core/lib/client_config/resolver_registry.c',
|
||||
'src/core/lib/client_config/subchannel.c',
|
||||
'src/core/lib/client_config/subchannel_factory.c',
|
||||
'src/core/lib/client_config/subchannel_index.c',
|
||||
'src/core/lib/client_config/uri_parser.c',
|
||||
'src/core/lib/compression/compression_algorithm.c',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015-2016, Google Inc.
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015-2016, Google Inc.
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015-2016, Google Inc.
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015-2016, Google Inc.
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
|
|||
md_ary->metadata[md_ary->count].value_length = value_len;
|
||||
md_ary->count += 1;
|
||||
}
|
||||
} else {
|
||||
} else if (TYPE(val) == T_STRING) {
|
||||
value_str = RSTRING_PTR(val);
|
||||
value_len = RSTRING_LEN(val);
|
||||
if (!grpc_is_binary_header(key_str, key_len) &&
|
||||
|
|
@ -373,6 +373,10 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
|
|||
md_ary->metadata[md_ary->count].value = value_str;
|
||||
md_ary->metadata[md_ary->count].value_length = value_len;
|
||||
md_ary->count += 1;
|
||||
} else {
|
||||
rb_raise(rb_eArgError,
|
||||
"Header values must be of type string or array");
|
||||
return ST_STOP;
|
||||
}
|
||||
|
||||
return ST_CONTINUE;
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ extern grpc_call_destroy_type grpc_call_destroy_import;
|
|||
typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
|
||||
extern grpc_server_request_call_type grpc_server_request_call_import;
|
||||
#define grpc_server_request_call grpc_server_request_call_import
|
||||
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, uint32_t flags);
|
||||
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, grpc_server_register_method_payload_handling payload_handling, uint32_t flags);
|
||||
extern grpc_server_register_method_type grpc_server_register_method_import;
|
||||
#define grpc_server_register_method grpc_server_register_method_import
|
||||
typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ module GRPC
|
|||
loop_handle_server_calls
|
||||
end
|
||||
|
||||
# Sends UNAVAILABLE if there are too many unprocessed jobs
|
||||
# Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs
|
||||
def available?(an_rpc)
|
||||
jobs_count, max = @pool.jobs_waiting, @max_waiting_requests
|
||||
GRPC.logger.info("waiting: #{jobs_count}, max: #{max}")
|
||||
|
|
@ -411,7 +411,7 @@ module GRPC
|
|||
GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}")
|
||||
noop = proc { |x| x }
|
||||
c = ActiveCall.new(an_rpc.call, @cq, noop, noop, an_rpc.deadline)
|
||||
c.send_status(StatusCodes::UNAVAILABLE, '')
|
||||
c.send_status(StatusCodes::RESOURCE_EXHAUSTED, '')
|
||||
nil
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -193,44 +193,45 @@ describe 'ClientStub' do
|
|||
describe '#client_streamer' do
|
||||
shared_examples 'client streaming' do
|
||||
before(:each) do
|
||||
server_port = create_test_server
|
||||
host = "localhost:#{server_port}"
|
||||
@stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
|
||||
@options = { k1: 'v1', k2: 'v2' }
|
||||
@sent_msgs = Array.new(3) { |i| 'msg_' + (i + 1).to_s }
|
||||
@resp = 'a_reply'
|
||||
end
|
||||
|
||||
it 'should send requests to/receive a reply from a server' do
|
||||
server_port = create_test_server
|
||||
host = "localhost:#{server_port}"
|
||||
th = run_client_streamer(@sent_msgs, @resp, @pass)
|
||||
stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
|
||||
expect(get_response(stub)).to eq(@resp)
|
||||
expect(get_response(@stub)).to eq(@resp)
|
||||
th.join
|
||||
end
|
||||
|
||||
it 'should send metadata to the server ok' do
|
||||
server_port = create_test_server
|
||||
host = "localhost:#{server_port}"
|
||||
th = run_client_streamer(@sent_msgs, @resp, @pass,
|
||||
k1: 'v1', k2: 'v2')
|
||||
stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
|
||||
expect(get_response(stub)).to eq(@resp)
|
||||
th = run_client_streamer(@sent_msgs, @resp, @pass, @options)
|
||||
expect(get_response(@stub)).to eq(@resp)
|
||||
th.join
|
||||
end
|
||||
|
||||
it 'should raise an error if the status is not ok' do
|
||||
server_port = create_test_server
|
||||
host = "localhost:#{server_port}"
|
||||
th = run_client_streamer(@sent_msgs, @resp, @fail)
|
||||
stub = GRPC::ClientStub.new(host, @cq, :this_channel_is_insecure)
|
||||
blk = proc { get_response(stub) }
|
||||
blk = proc { get_response(@stub) }
|
||||
expect(&blk).to raise_error(GRPC::BadStatus)
|
||||
th.join
|
||||
end
|
||||
|
||||
it 'should raise ArgumentError if metadata contains invalid values' do
|
||||
@options.merge!(k3: 3)
|
||||
expect do
|
||||
get_response(@stub)
|
||||
end.to raise_error(ArgumentError,
|
||||
/Header values must be of type string or array/)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'without a call operation' do
|
||||
def get_response(stub)
|
||||
stub.client_streamer(@method, @sent_msgs, noop, noop,
|
||||
k1: 'v1', k2: 'v2')
|
||||
stub.client_streamer(@method, @sent_msgs, noop, noop, @options)
|
||||
end
|
||||
|
||||
it_behaves_like 'client streaming'
|
||||
|
|
@ -239,7 +240,7 @@ describe 'ClientStub' do
|
|||
describe 'via a call operation' do
|
||||
def get_response(stub)
|
||||
op = stub.client_streamer(@method, @sent_msgs, noop, noop,
|
||||
return_op: true, k1: 'v1', k2: 'v2')
|
||||
@options.merge(return_op: true))
|
||||
expect(op).to be_a(GRPC::ActiveCall::Operation)
|
||||
op.execute
|
||||
end
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ describe GRPC::RpcServer do
|
|||
threads.each(&:join)
|
||||
end
|
||||
|
||||
it 'should return UNAVAILABLE on too many jobs', server: true do
|
||||
it 'should return RESOURCE_EXHAUSTED on too many jobs', server: true do
|
||||
opts = {
|
||||
a_channel_arg: 'an_arg',
|
||||
server_override: @server,
|
||||
|
|
@ -449,7 +449,8 @@ describe GRPC::RpcServer do
|
|||
begin
|
||||
stub.an_rpc(req)
|
||||
rescue GRPC::BadStatus => e
|
||||
one_failed_as_unavailable = e.code == StatusCodes::UNAVAILABLE
|
||||
one_failed_as_unavailable =
|
||||
e.code == StatusCodes::RESOURCE_EXHAUSTED
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator,
|
|||
grpc_server_register_completion_queue(a.server, a.cq, NULL);
|
||||
a.registered_method =
|
||||
grpc_server_register_method(a.server, GRPC_BAD_CLIENT_REGISTERED_METHOD,
|
||||
GRPC_BAD_CLIENT_REGISTERED_HOST, 0);
|
||||
GRPC_BAD_CLIENT_REGISTERED_HOST,
|
||||
GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0);
|
||||
grpc_server_start(a.server);
|
||||
transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0);
|
||||
server_setup_transport(&a, transport);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ BAD_CLIENT_TESTS = {
|
|||
'connection_prefix': default_test_options._replace(cpu_cost=0.2),
|
||||
'headers': default_test_options._replace(cpu_cost=0.2),
|
||||
'initial_settings_frame': default_test_options._replace(cpu_cost=0.2),
|
||||
'head_of_line_blocking': default_test_options,
|
||||
'server_registered_method': default_test_options,
|
||||
'simple_request': default_test_options,
|
||||
'window_overflow': default_test_options,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "test/core/bad_client/bad_client.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <grpc/support/alloc.h>
|
||||
|
||||
#include "src/core/lib/surface/server.h"
|
||||
#include "test/core/end2end/cq_verifier.h"
|
||||
|
||||
static const char prefix[] =
|
||||
"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
|
||||
// settings frame
|
||||
"\x00\x00\x00\x04\x00\x00\x00\x00\x00"
|
||||
// stream 1 headers: generated from server_registered_method.headers in this
|
||||
// directory
|
||||
"\x00\x00\xd0\x01\x04\x00\x00\x00\x01"
|
||||
"\x10\x05:path\x0f/registered/bar"
|
||||
"\x10\x07:scheme\x04http"
|
||||
"\x10\x07:method\x04POST"
|
||||
"\x10\x0a:authority\x09localhost"
|
||||
"\x10\x0c"
|
||||
"content-type\x10"
|
||||
"application/grpc"
|
||||
"\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"
|
||||
"\x10\x02te\x08trailers"
|
||||
"\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
|
||||
// data frame for stream 1: advertise a 10000 byte payload (that we won't
|
||||
// fulfill)
|
||||
"\x00\x00\x05\x00\x00\x00\x00\x00\x01"
|
||||
"\x01\x00\x00\x27\x10"
|
||||
// stream 3 headers: generated from server_registered_method.headers in this
|
||||
// directory
|
||||
"\x00\x00\xd0\x01\x04\x00\x00\x00\x03"
|
||||
"\x10\x05:path\x0f/registered/bar"
|
||||
"\x10\x07:scheme\x04http"
|
||||
"\x10\x07:method\x04POST"
|
||||
"\x10\x0a:authority\x09localhost"
|
||||
"\x10\x0c"
|
||||
"content-type\x10"
|
||||
"application/grpc"
|
||||
"\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"
|
||||
"\x10\x02te\x08trailers"
|
||||
"\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
|
||||
// data frame for stream 3: advertise a 10000 byte payload (that we will
|
||||
// fulfill)
|
||||
"\x00\x00\x05\x00\x00\x00\x00\x00\x03"
|
||||
"\x01\x00\x00\x27\x10"
|
||||
"";
|
||||
|
||||
static void *tag(intptr_t t) { return (void *)t; }
|
||||
|
||||
static void verifier(grpc_server *server, grpc_completion_queue *cq,
|
||||
void *registered_method) {
|
||||
grpc_call_error error;
|
||||
grpc_call *s;
|
||||
cq_verifier *cqv = cq_verifier_create(cq);
|
||||
grpc_metadata_array request_metadata_recv;
|
||||
gpr_timespec deadline;
|
||||
grpc_byte_buffer *payload = NULL;
|
||||
|
||||
grpc_metadata_array_init(&request_metadata_recv);
|
||||
|
||||
error = grpc_server_request_registered_call(server, registered_method, &s,
|
||||
&deadline, &request_metadata_recv,
|
||||
&payload, cq, cq, tag(101));
|
||||
GPR_ASSERT(GRPC_CALL_OK == error);
|
||||
cq_expect_completion(cqv, tag(101), 1);
|
||||
cq_verify(cqv);
|
||||
|
||||
GPR_ASSERT(payload != NULL);
|
||||
|
||||
grpc_metadata_array_destroy(&request_metadata_recv);
|
||||
grpc_call_destroy(s);
|
||||
grpc_byte_buffer_destroy(payload);
|
||||
cq_verifier_destroy(cqv);
|
||||
}
|
||||
|
||||
char *g_buffer;
|
||||
size_t g_cap = 0;
|
||||
size_t g_count = 0;
|
||||
|
||||
static void addbuf(const void *data, size_t len) {
|
||||
if (g_count + len > g_cap) {
|
||||
g_cap = GPR_MAX(g_count + len, g_cap * 2);
|
||||
g_buffer = gpr_realloc(g_buffer, g_cap);
|
||||
}
|
||||
memcpy(g_buffer + g_count, data, len);
|
||||
g_count += len;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i;
|
||||
grpc_test_init(argc, argv);
|
||||
|
||||
#define NUM_FRAMES 10
|
||||
#define FRAME_SIZE 1000
|
||||
|
||||
addbuf(prefix, sizeof(prefix) - 1);
|
||||
for (i = 0; i < NUM_FRAMES; i++) {
|
||||
uint8_t hdr[9] = {(uint8_t)(FRAME_SIZE >> 16),
|
||||
(uint8_t)(FRAME_SIZE >> 8),
|
||||
(uint8_t)FRAME_SIZE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
3};
|
||||
uint8_t msg[FRAME_SIZE];
|
||||
memset(msg, 'a', sizeof(msg));
|
||||
addbuf(hdr, sizeof(hdr));
|
||||
addbuf(msg, FRAME_SIZE);
|
||||
}
|
||||
grpc_run_bad_client_test(verifier, g_buffer, g_count, 0);
|
||||
gpr_free(g_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ static void run_test(const char *target, size_t nops) {
|
|||
op = ops;
|
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
||||
op->data.send_initial_metadata.count = 0;
|
||||
op->flags = 0;
|
||||
op->flags = GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY;
|
||||
op->reserved = NULL;
|
||||
op++;
|
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue