Merge branch 'master' into remove_node
diff --git a/BUILD b/BUILD
index 99411f9..f2848fd 100644
--- a/BUILD
+++ b/BUILD
@@ -409,41 +409,7 @@
grpc_cc_library(
name = "census",
srcs = [
- "src/core/ext/census/base_resources.cc",
- "src/core/ext/census/context.cc",
- "src/core/ext/census/gen/census.pb.c",
- "src/core/ext/census/gen/trace_context.pb.c",
"src/core/ext/census/grpc_context.cc",
- "src/core/ext/census/grpc_filter.cc",
- "src/core/ext/census/grpc_plugin.cc",
- "src/core/ext/census/initialize.cc",
- "src/core/ext/census/intrusive_hash_map.cc",
- "src/core/ext/census/mlog.cc",
- "src/core/ext/census/operation.cc",
- "src/core/ext/census/placeholders.cc",
- "src/core/ext/census/resource.cc",
- "src/core/ext/census/trace_context.cc",
- "src/core/ext/census/tracing.cc",
- ],
- hdrs = [
- "src/core/ext/census/aggregation.h",
- "src/core/ext/census/base_resources.h",
- "src/core/ext/census/census_interface.h",
- "src/core/ext/census/census_rpc_stats.h",
- "src/core/ext/census/gen/census.pb.h",
- "src/core/ext/census/gen/trace_context.pb.h",
- "src/core/ext/census/grpc_filter.h",
- "src/core/ext/census/intrusive_hash_map.h",
- "src/core/ext/census/intrusive_hash_map_internal.h",
- "src/core/ext/census/mlog.h",
- "src/core/ext/census/resource.h",
- "src/core/ext/census/rpc_metric_id.h",
- "src/core/ext/census/trace_context.h",
- "src/core/ext/census/trace_label.h",
- "src/core/ext/census/trace_propagation.h",
- "src/core/ext/census/trace_status.h",
- "src/core/ext/census/trace_string.h",
- "src/core/ext/census/tracing.h",
],
external_deps = [
"nanopb",
@@ -872,6 +838,7 @@
grpc_cc_library(
name = "grpc_client_channel",
srcs = [
+ "src/core/ext/filters/client_channel/backup_poller.cc",
"src/core/ext/filters/client_channel/channel_connectivity.cc",
"src/core/ext/filters/client_channel/client_channel.cc",
"src/core/ext/filters/client_channel/client_channel_factory.cc",
@@ -894,6 +861,7 @@
"src/core/ext/filters/client_channel/uri_parser.cc",
],
hdrs = [
+ "src/core/ext/filters/client_channel/backup_poller.h",
"src/core/ext/filters/client_channel/client_channel.h",
"src/core/ext/filters/client_channel/client_channel_factory.h",
"src/core/ext/filters/client_channel/connector.h",
@@ -1075,6 +1043,21 @@
)
grpc_cc_library(
+ name = "grpc_lb_subchannel_list",
+ srcs = [
+ "src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc",
+ ],
+ hdrs = [
+ "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h",
+ ],
+ language = "c++",
+ deps = [
+ "grpc_base",
+ "grpc_client_channel",
+ ],
+)
+
+grpc_cc_library(
name = "grpc_lb_policy_pick_first",
srcs = [
"src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc",
@@ -1083,6 +1066,7 @@
deps = [
"grpc_base",
"grpc_client_channel",
+ "grpc_lb_subchannel_list",
],
)
@@ -1095,6 +1079,7 @@
deps = [
"grpc_base",
"grpc_client_channel",
+ "grpc_lb_subchannel_list",
],
)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3ac6c9b..c20c97d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -384,10 +384,6 @@
add_dependencies(buildtests_c bin_decoder_test)
add_dependencies(buildtests_c bin_encoder_test)
add_dependencies(buildtests_c byte_stream_test)
-add_dependencies(buildtests_c census_context_test)
-add_dependencies(buildtests_c census_intrusive_hash_map_test)
-add_dependencies(buildtests_c census_resource_test)
-add_dependencies(buildtests_c census_trace_context_test)
add_dependencies(buildtests_c channel_create_test)
add_dependencies(buildtests_c chttp2_hpack_encoder_test)
add_dependencies(buildtests_c chttp2_stream_map_test)
@@ -492,7 +488,6 @@
endif()
add_dependencies(buildtests_c message_compress_test)
add_dependencies(buildtests_c minimal_stack_is_minimal_test)
-add_dependencies(buildtests_c mlog_test)
add_dependencies(buildtests_c multiple_server_queues_test)
add_dependencies(buildtests_c murmur_hash_test)
add_dependencies(buildtests_c no_server_test)
@@ -1153,6 +1148,7 @@
src/core/tsi/transport_security_adapter.cc
src/core/ext/transport/chttp2/server/chttp2_server.cc
src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
+ src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
src/core/ext/filters/client_channel/client_channel.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -1192,6 +1188,7 @@
third_party/nanopb/pb_encode.c
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+ src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@@ -1201,21 +1198,7 @@
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
- src/core/ext/census/base_resources.cc
- src/core/ext/census/context.cc
- src/core/ext/census/gen/census.pb.c
- src/core/ext/census/gen/trace_context.pb.c
src/core/ext/census/grpc_context.cc
- src/core/ext/census/grpc_filter.cc
- src/core/ext/census/grpc_plugin.cc
- src/core/ext/census/initialize.cc
- src/core/ext/census/intrusive_hash_map.cc
- src/core/ext/census/mlog.cc
- src/core/ext/census/operation.cc
- src/core/ext/census/placeholders.cc
- src/core/ext/census/resource.cc
- src/core/ext/census/trace_context.cc
- src/core/ext/census/tracing.cc
src/core/ext/filters/max_age/max_age_filter.cc
src/core/ext/filters/message_size/message_size_filter.cc
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc
@@ -1477,6 +1460,7 @@
src/core/ext/filters/http/http_filters_plugin.cc
src/core/ext/filters/http/message_compress/message_compress_filter.cc
src/core/ext/filters/http/server/http_server_filter.cc
+ src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
src/core/ext/filters/client_channel/client_channel.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -1767,6 +1751,7 @@
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
src/core/lib/debug/trace.cc
+ src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
src/core/ext/filters/client_channel/client_channel.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -2032,6 +2017,7 @@
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
src/core/lib/debug/trace.cc
+ src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
src/core/ext/filters/client_channel/client_channel.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -2316,6 +2302,7 @@
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
src/core/ext/transport/chttp2/client/chttp2_connector.cc
+ src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
src/core/ext/filters/client_channel/client_channel.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -2358,22 +2345,9 @@
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+ src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
- src/core/ext/census/base_resources.cc
- src/core/ext/census/context.cc
- src/core/ext/census/gen/census.pb.c
- src/core/ext/census/gen/trace_context.pb.c
src/core/ext/census/grpc_context.cc
- src/core/ext/census/grpc_filter.cc
- src/core/ext/census/grpc_plugin.cc
- src/core/ext/census/initialize.cc
- src/core/ext/census/intrusive_hash_map.cc
- src/core/ext/census/mlog.cc
- src/core/ext/census/operation.cc
- src/core/ext/census/placeholders.cc
- src/core/ext/census/resource.cc
- src/core/ext/census/trace_context.cc
- src/core/ext/census/tracing.cc
src/core/ext/filters/max_age/max_age_filter.cc
src/core/ext/filters/message_size/message_size_filter.cc
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc
@@ -3051,6 +3025,7 @@
src/core/ext/filters/http/http_filters_plugin.cc
src/core/ext/filters/http/message_compress/message_compress_filter.cc
src/core/ext/filters/http/server/http_server_filter.cc
+ src/core/ext/filters/client_channel/backup_poller.cc
src/core/ext/filters/client_channel/channel_connectivity.cc
src/core/ext/filters/client_channel/client_channel.cc
src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -3075,21 +3050,7 @@
src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
src/core/ext/transport/chttp2/server/chttp2_server.cc
- src/core/ext/census/base_resources.cc
- src/core/ext/census/context.cc
- src/core/ext/census/gen/census.pb.c
- src/core/ext/census/gen/trace_context.pb.c
src/core/ext/census/grpc_context.cc
- src/core/ext/census/grpc_filter.cc
- src/core/ext/census/grpc_plugin.cc
- src/core/ext/census/initialize.cc
- src/core/ext/census/intrusive_hash_map.cc
- src/core/ext/census/mlog.cc
- src/core/ext/census/operation.cc
- src/core/ext/census/placeholders.cc
- src/core/ext/census/resource.cc
- src/core/ext/census/trace_context.cc
- src/core/ext/census/tracing.cc
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
@@ -5391,126 +5352,6 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
-add_executable(census_context_test
- test/core/census/context_test.c
-)
-
-
-target_include_directories(census_context_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${BORINGSSL_ROOT_DIR}/include
- PRIVATE ${PROTOBUF_ROOT_DIR}/src
- PRIVATE ${BENCHMARK_ROOT_DIR}/include
- PRIVATE ${ZLIB_ROOT_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
- PRIVATE ${CARES_INCLUDE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp
-)
-
-target_link_libraries(census_context_test
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
- grpc
- gpr_test_util
- gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
-add_executable(census_intrusive_hash_map_test
- test/core/census/intrusive_hash_map_test.c
-)
-
-
-target_include_directories(census_intrusive_hash_map_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${BORINGSSL_ROOT_DIR}/include
- PRIVATE ${PROTOBUF_ROOT_DIR}/src
- PRIVATE ${BENCHMARK_ROOT_DIR}/include
- PRIVATE ${ZLIB_ROOT_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
- PRIVATE ${CARES_INCLUDE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp
-)
-
-target_link_libraries(census_intrusive_hash_map_test
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
- grpc
- gpr_test_util
- gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
-add_executable(census_resource_test
- test/core/census/resource_test.c
-)
-
-
-target_include_directories(census_resource_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${BORINGSSL_ROOT_DIR}/include
- PRIVATE ${PROTOBUF_ROOT_DIR}/src
- PRIVATE ${BENCHMARK_ROOT_DIR}/include
- PRIVATE ${ZLIB_ROOT_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
- PRIVATE ${CARES_INCLUDE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp
-)
-
-target_link_libraries(census_resource_test
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
- grpc
- gpr_test_util
- gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
-add_executable(census_trace_context_test
- test/core/census/trace_context_test.c
-)
-
-
-target_include_directories(census_trace_context_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${BORINGSSL_ROOT_DIR}/include
- PRIVATE ${PROTOBUF_ROOT_DIR}/src
- PRIVATE ${BENCHMARK_ROOT_DIR}/include
- PRIVATE ${ZLIB_ROOT_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
- PRIVATE ${CARES_INCLUDE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp
-)
-
-target_link_libraries(census_trace_context_test
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
- grpc
- gpr_test_util
- gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
add_executable(channel_create_test
test/core/surface/channel_create_test.c
)
@@ -8029,36 +7870,6 @@
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
-add_executable(mlog_test
- test/core/census/mlog_test.c
-)
-
-
-target_include_directories(mlog_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${BORINGSSL_ROOT_DIR}/include
- PRIVATE ${PROTOBUF_ROOT_DIR}/src
- PRIVATE ${BENCHMARK_ROOT_DIR}/include
- PRIVATE ${ZLIB_ROOT_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
- PRIVATE ${CARES_INCLUDE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp
-)
-
-target_link_libraries(mlog_test
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
- grpc
- gpr_test_util
- gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
add_executable(multiple_server_queues_test
test/core/end2end/multiple_server_queues_test.c
)
diff --git a/Makefile b/Makefile
index 325c912..ff26247 100644
--- a/Makefile
+++ b/Makefile
@@ -955,10 +955,6 @@
bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test
bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test
byte_stream_test: $(BINDIR)/$(CONFIG)/byte_stream_test
-census_context_test: $(BINDIR)/$(CONFIG)/census_context_test
-census_intrusive_hash_map_test: $(BINDIR)/$(CONFIG)/census_intrusive_hash_map_test
-census_resource_test: $(BINDIR)/$(CONFIG)/census_resource_test
-census_trace_context_test: $(BINDIR)/$(CONFIG)/census_trace_context_test
channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test
check_epollexclusive: $(BINDIR)/$(CONFIG)/check_epollexclusive
chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test
@@ -1048,7 +1044,6 @@
memory_profile_test: $(BINDIR)/$(CONFIG)/memory_profile_test
message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_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
@@ -1357,10 +1352,6 @@
$(BINDIR)/$(CONFIG)/bin_decoder_test \
$(BINDIR)/$(CONFIG)/bin_encoder_test \
$(BINDIR)/$(CONFIG)/byte_stream_test \
- $(BINDIR)/$(CONFIG)/census_context_test \
- $(BINDIR)/$(CONFIG)/census_intrusive_hash_map_test \
- $(BINDIR)/$(CONFIG)/census_resource_test \
- $(BINDIR)/$(CONFIG)/census_trace_context_test \
$(BINDIR)/$(CONFIG)/channel_create_test \
$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \
$(BINDIR)/$(CONFIG)/chttp2_stream_map_test \
@@ -1437,7 +1428,6 @@
$(BINDIR)/$(CONFIG)/memory_profile_test \
$(BINDIR)/$(CONFIG)/message_compress_test \
$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \
- $(BINDIR)/$(CONFIG)/mlog_test \
$(BINDIR)/$(CONFIG)/multiple_server_queues_test \
$(BINDIR)/$(CONFIG)/murmur_hash_test \
$(BINDIR)/$(CONFIG)/no_server_test \
@@ -1780,14 +1770,6 @@
$(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 )
$(E) "[RUN] Testing byte_stream_test"
$(Q) $(BINDIR)/$(CONFIG)/byte_stream_test || ( echo test byte_stream_test failed ; exit 1 )
- $(E) "[RUN] Testing census_context_test"
- $(Q) $(BINDIR)/$(CONFIG)/census_context_test || ( echo test census_context_test failed ; exit 1 )
- $(E) "[RUN] Testing census_intrusive_hash_map_test"
- $(Q) $(BINDIR)/$(CONFIG)/census_intrusive_hash_map_test || ( echo test census_intrusive_hash_map_test failed ; exit 1 )
- $(E) "[RUN] Testing census_resource_test"
- $(Q) $(BINDIR)/$(CONFIG)/census_resource_test || ( echo test census_resource_test failed ; exit 1 )
- $(E) "[RUN] Testing census_trace_context_test"
- $(Q) $(BINDIR)/$(CONFIG)/census_trace_context_test || ( echo test census_trace_context_test failed ; exit 1 )
$(E) "[RUN] Testing channel_create_test"
$(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 )
$(E) "[RUN] Testing chttp2_hpack_encoder_test"
@@ -2033,8 +2015,6 @@
flaky_test_c: buildtests_c
- $(E) "[RUN] Testing mlog_test"
- $(Q) $(BINDIR)/$(CONFIG)/mlog_test || ( echo test mlog_test failed ; exit 1 )
test_cxx: buildtests_cxx
@@ -3153,6 +3133,7 @@
src/core/tsi/transport_security_adapter.cc \
src/core/ext/transport/chttp2/server/chttp2_server.cc \
src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
@@ -3192,6 +3173,7 @@
third_party/nanopb/pb_encode.c \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
+ src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
@@ -3201,21 +3183,7 @@
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
- src/core/ext/census/base_resources.cc \
- src/core/ext/census/context.cc \
- src/core/ext/census/gen/census.pb.c \
- src/core/ext/census/gen/trace_context.pb.c \
src/core/ext/census/grpc_context.cc \
- src/core/ext/census/grpc_filter.cc \
- src/core/ext/census/grpc_plugin.cc \
- src/core/ext/census/initialize.cc \
- src/core/ext/census/intrusive_hash_map.cc \
- src/core/ext/census/mlog.cc \
- src/core/ext/census/operation.cc \
- src/core/ext/census/placeholders.cc \
- src/core/ext/census/resource.cc \
- src/core/ext/census/trace_context.cc \
- src/core/ext/census/tracing.cc \
src/core/ext/filters/max_age/max_age_filter.cc \
src/core/ext/filters/message_size/message_size_filter.cc \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
@@ -3476,6 +3444,7 @@
src/core/ext/filters/http/http_filters_plugin.cc \
src/core/ext/filters/http/message_compress/message_compress_filter.cc \
src/core/ext/filters/http/server/http_server_filter.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
@@ -3764,6 +3733,7 @@
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
src/core/lib/debug/trace.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
@@ -4019,6 +3989,7 @@
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
src/core/lib/debug/trace.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
@@ -4280,6 +4251,7 @@
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
@@ -4322,22 +4294,9 @@
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
+ src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
- src/core/ext/census/base_resources.cc \
- src/core/ext/census/context.cc \
- src/core/ext/census/gen/census.pb.c \
- src/core/ext/census/gen/trace_context.pb.c \
src/core/ext/census/grpc_context.cc \
- src/core/ext/census/grpc_filter.cc \
- src/core/ext/census/grpc_plugin.cc \
- src/core/ext/census/initialize.cc \
- src/core/ext/census/intrusive_hash_map.cc \
- src/core/ext/census/mlog.cc \
- src/core/ext/census/operation.cc \
- src/core/ext/census/placeholders.cc \
- src/core/ext/census/resource.cc \
- src/core/ext/census/trace_context.cc \
- src/core/ext/census/tracing.cc \
src/core/ext/filters/max_age/max_age_filter.cc \
src/core/ext/filters/message_size/message_size_filter.cc \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
@@ -4993,6 +4952,7 @@
src/core/ext/filters/http/http_filters_plugin.cc \
src/core/ext/filters/http/message_compress/message_compress_filter.cc \
src/core/ext/filters/http/server/http_server_filter.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
@@ -5017,21 +4977,7 @@
src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \
src/core/ext/transport/chttp2/server/chttp2_server.cc \
- src/core/ext/census/base_resources.cc \
- src/core/ext/census/context.cc \
- src/core/ext/census/gen/census.pb.c \
- src/core/ext/census/gen/trace_context.pb.c \
src/core/ext/census/grpc_context.cc \
- src/core/ext/census/grpc_filter.cc \
- src/core/ext/census/grpc_plugin.cc \
- src/core/ext/census/initialize.cc \
- src/core/ext/census/intrusive_hash_map.cc \
- src/core/ext/census/mlog.cc \
- src/core/ext/census/operation.cc \
- src/core/ext/census/placeholders.cc \
- src/core/ext/census/resource.cc \
- src/core/ext/census/trace_context.cc \
- src/core/ext/census/tracing.cc \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
@@ -8298,6 +8244,7 @@
third_party/benchmark/src/commandlineflags.cc \
third_party/benchmark/src/complexity.cc \
third_party/benchmark/src/console_reporter.cc \
+ third_party/benchmark/src/counter.cc \
third_party/benchmark/src/csv_reporter.cc \
third_party/benchmark/src/json_reporter.cc \
third_party/benchmark/src/reporter.cc \
@@ -9072,134 +9019,6 @@
endif
-CENSUS_CONTEXT_TEST_SRC = \
- test/core/census/context_test.c \
-
-CENSUS_CONTEXT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_CONTEXT_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/census_context_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/census_context_test: $(CENSUS_CONTEXT_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) $(LD) $(LDFLAGS) $(CENSUS_CONTEXT_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) -o $(BINDIR)/$(CONFIG)/census_context_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/census/context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_census_context_test: $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_INTRUSIVE_HASH_MAP_TEST_SRC = \
- test/core/census/intrusive_hash_map_test.c \
-
-CENSUS_INTRUSIVE_HASH_MAP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_INTRUSIVE_HASH_MAP_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/census_intrusive_hash_map_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/census_intrusive_hash_map_test: $(CENSUS_INTRUSIVE_HASH_MAP_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) $(LD) $(LDFLAGS) $(CENSUS_INTRUSIVE_HASH_MAP_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) -o $(BINDIR)/$(CONFIG)/census_intrusive_hash_map_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/census/intrusive_hash_map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_census_intrusive_hash_map_test: $(CENSUS_INTRUSIVE_HASH_MAP_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_INTRUSIVE_HASH_MAP_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_RESOURCE_TEST_SRC = \
- test/core/census/resource_test.c \
-
-CENSUS_RESOURCE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_RESOURCE_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/census_resource_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/census_resource_test: $(CENSUS_RESOURCE_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) $(LD) $(LDFLAGS) $(CENSUS_RESOURCE_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) -o $(BINDIR)/$(CONFIG)/census_resource_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/census/resource_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_census_resource_test: $(CENSUS_RESOURCE_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_RESOURCE_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_TRACE_CONTEXT_TEST_SRC = \
- test/core/census/trace_context_test.c \
-
-CENSUS_TRACE_CONTEXT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_TRACE_CONTEXT_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/census_trace_context_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/census_trace_context_test: $(CENSUS_TRACE_CONTEXT_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) $(LD) $(LDFLAGS) $(CENSUS_TRACE_CONTEXT_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) -o $(BINDIR)/$(CONFIG)/census_trace_context_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/census/trace_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_census_trace_context_test: $(CENSUS_TRACE_CONTEXT_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_TRACE_CONTEXT_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
CHANNEL_CREATE_TEST_SRC = \
test/core/surface/channel_create_test.c \
@@ -12051,38 +11870,6 @@
endif
-MLOG_TEST_SRC = \
- test/core/census/mlog_test.c \
-
-MLOG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MLOG_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/mlog_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/mlog_test: $(MLOG_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) $(LD) $(LDFLAGS) $(MLOG_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) -o $(BINDIR)/$(CONFIG)/mlog_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/census/mlog_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_mlog_test: $(MLOG_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(MLOG_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
MULTIPLE_SERVER_QUEUES_TEST_SRC = \
test/core/end2end/multiple_server_queues_test.c \
diff --git a/build.yaml b/build.yaml
index 2bcf11d..5dcc1c7 100644
--- a/build.yaml
+++ b/build.yaml
@@ -19,42 +19,8 @@
- name: census
public_headers:
- include/grpc/census.h
- headers:
- - src/core/ext/census/aggregation.h
- - src/core/ext/census/base_resources.h
- - src/core/ext/census/census_interface.h
- - src/core/ext/census/census_rpc_stats.h
- - src/core/ext/census/gen/census.pb.h
- - src/core/ext/census/gen/trace_context.pb.h
- - src/core/ext/census/grpc_filter.h
- - src/core/ext/census/intrusive_hash_map.h
- - src/core/ext/census/intrusive_hash_map_internal.h
- - src/core/ext/census/mlog.h
- - src/core/ext/census/resource.h
- - src/core/ext/census/rpc_metric_id.h
- - src/core/ext/census/trace_context.h
- - src/core/ext/census/trace_label.h
- - src/core/ext/census/trace_propagation.h
- - src/core/ext/census/trace_status.h
- - src/core/ext/census/trace_string.h
- - src/core/ext/census/tracing.h
src:
- - src/core/ext/census/base_resources.cc
- - src/core/ext/census/context.cc
- - src/core/ext/census/gen/census.pb.c
- - src/core/ext/census/gen/trace_context.pb.c
- src/core/ext/census/grpc_context.cc
- - src/core/ext/census/grpc_filter.cc
- - src/core/ext/census/grpc_plugin.cc
- - src/core/ext/census/initialize.cc
- - src/core/ext/census/intrusive_hash_map.cc
- - src/core/ext/census/mlog.cc
- - src/core/ext/census/operation.cc
- - src/core/ext/census/placeholders.cc
- - src/core/ext/census/resource.cc
- - src/core/ext/census/trace_context.cc
- - src/core/ext/census/tracing.cc
- plugin: census_grpc_plugin
uses:
- grpc_base
- nanopb
@@ -463,6 +429,7 @@
- grpc_trace_headers
- name: grpc_client_channel
headers:
+ - src/core/ext/filters/client_channel/backup_poller.h
- src/core/ext/filters/client_channel/client_channel.h
- src/core/ext/filters/client_channel/client_channel_factory.h
- src/core/ext/filters/client_channel/connector.h
@@ -482,6 +449,7 @@
- src/core/ext/filters/client_channel/subchannel_index.h
- src/core/ext/filters/client_channel/uri_parser.h
src:
+ - src/core/ext/filters/client_channel/backup_poller.cc
- src/core/ext/filters/client_channel/channel_connectivity.cc
- src/core/ext/filters/client_channel/client_channel.cc
- src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -590,6 +558,7 @@
uses:
- grpc_base
- grpc_client_channel
+ - grpc_lb_subchannel_list
- name: grpc_lb_policy_round_robin
src:
- src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -597,6 +566,15 @@
uses:
- grpc_base
- grpc_client_channel
+ - grpc_lb_subchannel_list
+- name: grpc_lb_subchannel_list
+ headers:
+ - src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
+ src:
+ - src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
+ uses:
+ - grpc_base
+ - grpc_client_channel
- name: grpc_max_age_filter
headers:
- src/core/ext/filters/max_age/max_age_filter.h
@@ -1834,50 +1812,6 @@
- gpr_test_util
- gpr
uses_polling: false
-- name: census_context_test
- build: test
- language: c
- src:
- - test/core/census/context_test.c
- deps:
- - grpc_test_util
- - grpc
- - gpr_test_util
- - gpr
- uses_polling: false
-- name: census_intrusive_hash_map_test
- build: test
- language: c
- src:
- - test/core/census/intrusive_hash_map_test.c
- deps:
- - grpc_test_util
- - grpc
- - gpr_test_util
- - gpr
- uses_polling: false
-- name: census_resource_test
- build: test
- language: c
- src:
- - test/core/census/resource_test.c
- deps:
- - grpc_test_util
- - grpc
- - gpr_test_util
- - gpr
- uses_polling: false
-- name: census_trace_context_test
- build: test
- language: c
- src:
- - test/core/census/trace_context_test.c
- deps:
- - grpc_test_util
- - grpc
- - gpr_test_util
- - gpr
- uses_polling: false
- name: channel_create_test
build: test
language: c
@@ -2886,18 +2820,6 @@
- gpr_test_util
- gpr
uses_polling: false
-- name: mlog_test
- flaky: true
- build: test
- language: c
- src:
- - test/core/census/mlog_test.c
- deps:
- - grpc_test_util
- - grpc
- - gpr_test_util
- - gpr
- uses_polling: false
- name: multiple_server_queues_test
build: test
language: c
@@ -3794,6 +3716,8 @@
- --benchmark_min_time=0
benchmark: true
defaults: benchmark
+ exclude_configs:
+ - tsan
excluded_poll_engines:
- poll
- poll-cv
@@ -3955,10 +3879,6 @@
- grpc
- gpr_test_util
- gpr
- excluded_poll_engines:
- - poll
- - poll-cv
- - epollex
- name: codegen_test_full
gtest: true
build: test
@@ -4247,9 +4167,6 @@
- grpc
- gpr_test_util
- gpr
- excluded_poll_engines:
- - poll
- - poll-cv
- name: grpclb_test
gtest: false
build: test
@@ -4264,10 +4181,6 @@
- grpc
- gpr_test_util
- gpr
- excluded_poll_engines:
- - poll
- - poll-cv
- - epollex
- name: h2_ssl_cert_test
gtest: true
build: test
@@ -4838,7 +4751,6 @@
- grpc_unsecure
- gpr_test_util
- gpr
- timeout_seconds: 1200
- name: transport_pid_controller_test
build: test
language: c++
diff --git a/config.m4 b/config.m4
index 5d92a2a..5cb46cf 100644
--- a/config.m4
+++ b/config.m4
@@ -278,6 +278,7 @@
src/core/tsi/transport_security_adapter.cc \
src/core/ext/transport/chttp2/server/chttp2_server.cc \
src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc \
+ src/core/ext/filters/client_channel/backup_poller.cc \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel_factory.cc \
@@ -317,6 +318,7 @@
third_party/nanopb/pb_encode.c \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
+ src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
@@ -326,21 +328,7 @@
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/load_reporting/server_load_reporting_filter.cc \
src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc \
- src/core/ext/census/base_resources.cc \
- src/core/ext/census/context.cc \
- src/core/ext/census/gen/census.pb.c \
- src/core/ext/census/gen/trace_context.pb.c \
src/core/ext/census/grpc_context.cc \
- src/core/ext/census/grpc_filter.cc \
- src/core/ext/census/grpc_plugin.cc \
- src/core/ext/census/initialize.cc \
- src/core/ext/census/intrusive_hash_map.cc \
- src/core/ext/census/mlog.cc \
- src/core/ext/census/operation.cc \
- src/core/ext/census/placeholders.cc \
- src/core/ext/census/resource.cc \
- src/core/ext/census/trace_context.cc \
- src/core/ext/census/tracing.cc \
src/core/ext/filters/max_age/max_age_filter.cc \
src/core/ext/filters/message_size/message_size_filter.cc \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
@@ -658,8 +646,8 @@
PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census)
- PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census/gen)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first)
diff --git a/config.w32 b/config.w32
index 67b5e2f..0fc5066 100644
--- a/config.w32
+++ b/config.w32
@@ -255,6 +255,7 @@
"src\\core\\tsi\\transport_security_adapter.cc " +
"src\\core\\ext\\transport\\chttp2\\server\\chttp2_server.cc " +
"src\\core\\ext\\transport\\chttp2\\client\\secure\\secure_channel_create.cc " +
+ "src\\core\\ext\\filters\\client_channel\\backup_poller.cc " +
"src\\core\\ext\\filters\\client_channel\\channel_connectivity.cc " +
"src\\core\\ext\\filters\\client_channel\\client_channel.cc " +
"src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " +
@@ -294,6 +295,7 @@
"third_party\\nanopb\\pb_encode.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first\\pick_first.cc " +
+ "src\\core\\ext\\filters\\client_channel\\lb_policy\\subchannel_list.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " +
@@ -303,21 +305,7 @@
"src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " +
"src\\core\\ext\\filters\\load_reporting\\server_load_reporting_filter.cc " +
"src\\core\\ext\\filters\\load_reporting\\server_load_reporting_plugin.cc " +
- "src\\core\\ext\\census\\base_resources.cc " +
- "src\\core\\ext\\census\\context.cc " +
- "src\\core\\ext\\census\\gen\\census.pb.c " +
- "src\\core\\ext\\census\\gen\\trace_context.pb.c " +
"src\\core\\ext\\census\\grpc_context.cc " +
- "src\\core\\ext\\census\\grpc_filter.cc " +
- "src\\core\\ext\\census\\grpc_plugin.cc " +
- "src\\core\\ext\\census\\initialize.cc " +
- "src\\core\\ext\\census\\intrusive_hash_map.cc " +
- "src\\core\\ext\\census\\mlog.cc " +
- "src\\core\\ext\\census\\operation.cc " +
- "src\\core\\ext\\census\\placeholders.cc " +
- "src\\core\\ext\\census\\resource.cc " +
- "src\\core\\ext\\census\\trace_context.cc " +
- "src\\core\\ext\\census\\tracing.cc " +
"src\\core\\ext\\filters\\max_age\\max_age_filter.cc " +
"src\\core\\ext\\filters\\message_size\\message_size_filter.cc " +
"src\\core\\ext\\filters\\workarounds\\workaround_cronet_compression_filter.cc " +
@@ -661,7 +649,6 @@
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census");
- FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census\\gen");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy");
diff --git a/doc/environment_variables.md b/doc/environment_variables.md
index c5fb266..40af758 100644
--- a/doc/environment_variables.md
+++ b/doc/environment_variables.md
@@ -120,10 +120,10 @@
perform name resolution
- ares - a DNS resolver based around the c-ares library
-* GRPC_DISABLE_CHANNEL_CONNECTIVITY_WATCHER
- The channel connectivity watcher uses one extra thread to check the channel
- state every 500 ms on the client side. It can help reconnect disconnected
- client channels (mostly due to idleness), so that the next RPC on this channel
- won't fail. Set to 1 to turn off this watcher and save a thread. Please note
- this is a temporary work-around, it will be removed in the future once we have
- support for automatically reestablishing failed connections.
+* GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS
+ Default: 5000
+ Declares the interval between two backup polls on client channels. These polls
+ are run in the timer thread so that gRPC can process connection failures while
+ there is no active polling thread. They help reconnect disconnected client
+ channels (mostly due to idleness), so that the next RPC on this channel won't
+ fail. Set to 0 to turn off the backup polls.
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 0e3b50c..b2313a5 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -299,6 +299,7 @@
'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
+ 'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/connector.h',
@@ -448,28 +449,11 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
+ 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
- 'src/core/ext/census/aggregation.h',
- 'src/core/ext/census/base_resources.h',
- 'src/core/ext/census/census_interface.h',
- 'src/core/ext/census/census_rpc_stats.h',
- 'src/core/ext/census/gen/census.pb.h',
- 'src/core/ext/census/gen/trace_context.pb.h',
- 'src/core/ext/census/grpc_filter.h',
- 'src/core/ext/census/intrusive_hash_map.h',
- 'src/core/ext/census/intrusive_hash_map_internal.h',
- 'src/core/ext/census/mlog.h',
- 'src/core/ext/census/resource.h',
- 'src/core/ext/census/rpc_metric_id.h',
- 'src/core/ext/census/trace_context.h',
- 'src/core/ext/census/trace_label.h',
- 'src/core/ext/census/trace_propagation.h',
- 'src/core/ext/census/trace_status.h',
- 'src/core/ext/census/trace_string.h',
- 'src/core/ext/census/tracing.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
@@ -668,6 +652,7 @@
'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
+ 'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
@@ -704,6 +689,7 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
@@ -713,21 +699,7 @@
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc',
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc',
- 'src/core/ext/census/base_resources.cc',
- 'src/core/ext/census/context.cc',
- 'src/core/ext/census/gen/census.pb.c',
- 'src/core/ext/census/gen/trace_context.pb.c',
'src/core/ext/census/grpc_context.cc',
- 'src/core/ext/census/grpc_filter.cc',
- 'src/core/ext/census/grpc_plugin.cc',
- 'src/core/ext/census/initialize.cc',
- 'src/core/ext/census/intrusive_hash_map.cc',
- 'src/core/ext/census/mlog.cc',
- 'src/core/ext/census/operation.cc',
- 'src/core/ext/census/placeholders.cc',
- 'src/core/ext/census/resource.cc',
- 'src/core/ext/census/trace_context.cc',
- 'src/core/ext/census/tracing.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
@@ -802,6 +774,7 @@
'src/core/tsi/transport_security_adapter.h',
'src/core/tsi/transport_security_interface.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
+ 'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/connector.h',
@@ -951,28 +924,11 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
+ 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
- 'src/core/ext/census/aggregation.h',
- 'src/core/ext/census/base_resources.h',
- 'src/core/ext/census/census_interface.h',
- 'src/core/ext/census/census_rpc_stats.h',
- 'src/core/ext/census/gen/census.pb.h',
- 'src/core/ext/census/gen/trace_context.pb.h',
- 'src/core/ext/census/grpc_filter.h',
- 'src/core/ext/census/intrusive_hash_map.h',
- 'src/core/ext/census/intrusive_hash_map_internal.h',
- 'src/core/ext/census/mlog.h',
- 'src/core/ext/census/resource.h',
- 'src/core/ext/census/rpc_metric_id.h',
- 'src/core/ext/census/trace_context.h',
- 'src/core/ext/census/trace_label.h',
- 'src/core/ext/census/trace_propagation.h',
- 'src/core/ext/census/trace_status.h',
- 'src/core/ext/census/trace_string.h',
- 'src/core/ext/census/tracing.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
diff --git a/grpc.def b/grpc.def
index e4281f3..710be52 100644
--- a/grpc.def
+++ b/grpc.def
@@ -1,32 +1,4 @@
EXPORTS
- census_initialize
- census_shutdown
- census_supported
- census_enabled
- census_context_create
- census_context_destroy
- census_context_get_status
- census_context_initialize_iterator
- census_context_next_tag
- census_context_get_tag
- census_context_encode
- census_context_decode
- census_trace_mask
- census_set_trace_mask
- census_start_rpc_op_timestamp
- census_start_client_rpc_op
- census_set_rpc_client_peer
- census_start_server_rpc_op
- census_start_op
- census_end_op
- census_trace_print
- census_trace_scan_start
- census_get_trace_record
- census_trace_scan_end
- census_define_resource
- census_delete_resource
- census_resource_id
- census_record_values
grpc_compression_algorithm_parse
grpc_compression_algorithm_name
grpc_stream_compression_algorithm_name
@@ -132,8 +104,14 @@
grpc_metadata_credentials_create_from_plugin
grpc_secure_channel_create
grpc_server_credentials_release
+ grpc_ssl_server_certificate_config_create
+ grpc_ssl_server_certificate_config_destroy
grpc_ssl_server_credentials_create
grpc_ssl_server_credentials_create_ex
+ grpc_ssl_server_credentials_create_options_using_config
+ grpc_ssl_server_credentials_create_options_using_config_fetcher
+ grpc_ssl_server_credentials_options_destroy
+ grpc_ssl_server_credentials_create_with_options
grpc_server_add_secure_http2_port
grpc_call_set_credentials
grpc_server_credentials_set_auth_metadata_processor
diff --git a/grpc.gemspec b/grpc.gemspec
index 4567058..2fe2536 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -28,7 +28,7 @@
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.1'
- s.add_dependency 'googleauth', '~> 0.5.1'
+ s.add_dependency 'googleauth', '>= 0.5.1', '< 0.7'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0'
s.add_development_dependency 'bundler', '~> 1.9'
@@ -230,6 +230,7 @@
s.files += %w( src/core/tsi/transport_security_adapter.h )
s.files += %w( src/core/tsi/transport_security_interface.h )
s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h )
+ s.files += %w( src/core/ext/filters/client_channel/backup_poller.h )
s.files += %w( src/core/ext/filters/client_channel/client_channel.h )
s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h )
s.files += %w( src/core/ext/filters/client_channel/connector.h )
@@ -383,28 +384,11 @@
s.files += %w( third_party/nanopb/pb_decode.h )
s.files += %w( third_party/nanopb/pb_encode.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h )
+ s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_filter.h )
s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_plugin.h )
- s.files += %w( src/core/ext/census/aggregation.h )
- s.files += %w( src/core/ext/census/base_resources.h )
- s.files += %w( src/core/ext/census/census_interface.h )
- s.files += %w( src/core/ext/census/census_rpc_stats.h )
- s.files += %w( src/core/ext/census/gen/census.pb.h )
- s.files += %w( src/core/ext/census/gen/trace_context.pb.h )
- s.files += %w( src/core/ext/census/grpc_filter.h )
- s.files += %w( src/core/ext/census/intrusive_hash_map.h )
- s.files += %w( src/core/ext/census/intrusive_hash_map_internal.h )
- s.files += %w( src/core/ext/census/mlog.h )
- s.files += %w( src/core/ext/census/resource.h )
- s.files += %w( src/core/ext/census/rpc_metric_id.h )
- s.files += %w( src/core/ext/census/trace_context.h )
- s.files += %w( src/core/ext/census/trace_label.h )
- s.files += %w( src/core/ext/census/trace_propagation.h )
- s.files += %w( src/core/ext/census/trace_status.h )
- s.files += %w( src/core/ext/census/trace_string.h )
- s.files += %w( src/core/ext/census/tracing.h )
s.files += %w( src/core/ext/filters/max_age/max_age_filter.h )
s.files += %w( src/core/ext/filters/message_size/message_size_filter.h )
s.files += %w( src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h )
@@ -603,6 +587,7 @@
s.files += %w( src/core/tsi/transport_security_adapter.cc )
s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.cc )
s.files += %w( src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc )
+ s.files += %w( src/core/ext/filters/client_channel/backup_poller.cc )
s.files += %w( src/core/ext/filters/client_channel/channel_connectivity.cc )
s.files += %w( src/core/ext/filters/client_channel/client_channel.cc )
s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc )
@@ -642,6 +627,7 @@
s.files += %w( third_party/nanopb/pb_encode.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc )
+ s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc )
@@ -651,21 +637,7 @@
s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc )
s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_filter.cc )
s.files += %w( src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc )
- s.files += %w( src/core/ext/census/base_resources.cc )
- s.files += %w( src/core/ext/census/context.cc )
- s.files += %w( src/core/ext/census/gen/census.pb.c )
- s.files += %w( src/core/ext/census/gen/trace_context.pb.c )
s.files += %w( src/core/ext/census/grpc_context.cc )
- s.files += %w( src/core/ext/census/grpc_filter.cc )
- s.files += %w( src/core/ext/census/grpc_plugin.cc )
- s.files += %w( src/core/ext/census/initialize.cc )
- s.files += %w( src/core/ext/census/intrusive_hash_map.cc )
- s.files += %w( src/core/ext/census/mlog.cc )
- s.files += %w( src/core/ext/census/operation.cc )
- s.files += %w( src/core/ext/census/placeholders.cc )
- s.files += %w( src/core/ext/census/resource.cc )
- s.files += %w( src/core/ext/census/trace_context.cc )
- s.files += %w( src/core/ext/census/tracing.cc )
s.files += %w( src/core/ext/filters/max_age/max_age_filter.cc )
s.files += %w( src/core/ext/filters/message_size/message_size_filter.cc )
s.files += %w( src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 487d529..32b6dc2 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -419,6 +419,7 @@
'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
+ 'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
@@ -458,6 +459,7 @@
'third_party/nanopb/pb_encode.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
@@ -467,21 +469,7 @@
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc',
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc',
- 'src/core/ext/census/base_resources.cc',
- 'src/core/ext/census/context.cc',
- 'src/core/ext/census/gen/census.pb.c',
- 'src/core/ext/census/gen/trace_context.pb.c',
'src/core/ext/census/grpc_context.cc',
- 'src/core/ext/census/grpc_filter.cc',
- 'src/core/ext/census/grpc_plugin.cc',
- 'src/core/ext/census/initialize.cc',
- 'src/core/ext/census/intrusive_hash_map.cc',
- 'src/core/ext/census/mlog.cc',
- 'src/core/ext/census/operation.cc',
- 'src/core/ext/census/placeholders.cc',
- 'src/core/ext/census/resource.cc',
- 'src/core/ext/census/trace_context.cc',
- 'src/core/ext/census/tracing.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
@@ -661,6 +649,7 @@
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
'src/core/lib/debug/trace.cc',
+ 'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
@@ -868,6 +857,7 @@
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
'src/core/lib/debug/trace.cc',
+ 'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
@@ -1093,6 +1083,7 @@
'src/core/ext/transport/chttp2/client/insecure/channel_create.cc',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
+ 'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
@@ -1135,22 +1126,9 @@
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
- 'src/core/ext/census/base_resources.cc',
- 'src/core/ext/census/context.cc',
- 'src/core/ext/census/gen/census.pb.c',
- 'src/core/ext/census/gen/trace_context.pb.c',
'src/core/ext/census/grpc_context.cc',
- 'src/core/ext/census/grpc_filter.cc',
- 'src/core/ext/census/grpc_plugin.cc',
- 'src/core/ext/census/initialize.cc',
- 'src/core/ext/census/intrusive_hash_map.cc',
- 'src/core/ext/census/mlog.cc',
- 'src/core/ext/census/operation.cc',
- 'src/core/ext/census/placeholders.cc',
- 'src/core/ext/census/resource.cc',
- 'src/core/ext/census/trace_context.cc',
- 'src/core/ext/census/tracing.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
@@ -2316,6 +2294,7 @@
'third_party/benchmark/src/commandlineflags.cc',
'third_party/benchmark/src/complexity.cc',
'third_party/benchmark/src/console_reporter.cc',
+ 'third_party/benchmark/src/counter.cc',
'third_party/benchmark/src/csv_reporter.cc',
'third_party/benchmark/src/json_reporter.cc',
'third_party/benchmark/src/reporter.cc',
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index 2d88d86..b43425e 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -92,7 +92,7 @@
}
private:
- class AlarmEntry : public CompletionQueueTag {
+ class AlarmEntry : public internal::CompletionQueueTag {
public:
AlarmEntry(void* tag) : tag_(tag) {}
void Set(void* tag) { tag_ = tag; }
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index c50091d..e9fb5a5 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -32,7 +32,7 @@
namespace grpc {
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ChannelInterface,
- public CallHook,
+ public internal::CallHook,
public std::enable_shared_from_this<Channel>,
private GrpcLibraryCodegen {
public:
@@ -51,18 +51,16 @@
private:
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
+ friend class internal::BlockingUnaryCallImpl;
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel);
Channel(const grpc::string& host, grpc_channel* c_channel);
- Call CreateCall(const RpcMethod& method, ClientContext* context,
- CompletionQueue* cq) override;
- void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) override;
+ internal::Call CreateCall(const internal::RpcMethod& method,
+ ClientContext* context,
+ CompletionQueue* cq) override;
+ void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h
index e60572f..4476033 100644
--- a/include/grpc++/impl/codegen/async_stream.h
+++ b/include/grpc++/impl/codegen/async_stream.h
@@ -30,6 +30,7 @@
class CompletionQueue;
+namespace internal {
/// Common interface for all client side asynchronous streaming.
class ClientAsyncStreamingInterface {
public:
@@ -151,15 +152,16 @@
}
};
-template <class R>
-class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
- public AsyncReaderInterface<R> {};
+} // namespace internal
-/// Async client-side API for doing server-streaming RPCs,
-/// where the incoming message stream coming from the server has
-/// messages of type \a R.
template <class R>
-class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
+class ClientAsyncReaderInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncReaderInterface<R> {};
+
+namespace internal {
+template <class R>
+class ClientAsyncReaderFactory {
public:
/// Create a stream object.
/// Write the first request out if \a start is set.
@@ -169,16 +171,25 @@
/// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
template <class W>
- static ClientAsyncReader* Create(ChannelInterface* channel,
- CompletionQueue* cq, const RpcMethod& method,
- ClientContext* context, const W& request,
- bool start, void* tag) {
- Call call = channel->CreateCall(method, context, cq);
+ static ClientAsyncReader<R>* Create(ChannelInterface* channel,
+ CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncReader)))
- ClientAsyncReader(call, context, request, start, tag);
+ call.call(), sizeof(ClientAsyncReader<R>)))
+ ClientAsyncReader<R>(call, context, request, start, tag);
}
+};
+} // namespace internal
+/// Async client-side API for doing server-streaming RPCs,
+/// where the incoming message stream coming from the server has
+/// messages of type \a R.
+template <class R>
+class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
+ public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncReader));
@@ -233,9 +244,10 @@
}
private:
+ friend class internal::ClientAsyncReaderFactory<R>;
template <class W>
- ClientAsyncReader(Call call, ClientContext* context, const W& request,
- bool start, void* tag)
+ ClientAsyncReader(::grpc::internal::Call call, ClientContext* context,
+ const W& request, bool start, void* tag)
: context_(context), call_(call), started_(start) {
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
@@ -255,19 +267,27 @@
}
ClientContext* context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
init_ops_;
- CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
};
/// Common interface for client side asynchronous writing.
template <class W>
-class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
- public AsyncWriterInterface<W> {
+class ClientAsyncWriterInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W> {
public:
/// Signal the client is done with the writes (half-close the client stream).
/// Thread-safe with respect to \a AsyncReaderInterface::Read
@@ -276,11 +296,9 @@
virtual void WritesDone(void* tag) = 0;
};
-/// Async API on the client side for doing client-streaming RPCs,
-/// where the outgoing message stream going to the server contains
-/// messages of type \a W.
+namespace internal {
template <class W>
-class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
+class ClientAsyncWriterFactory {
public:
/// Create a stream object.
/// Start the RPC if \a start is set
@@ -294,16 +312,25 @@
/// message from the server upon a successful call to the \a Finish
/// method of this instance.
template <class R>
- static ClientAsyncWriter* Create(ChannelInterface* channel,
- CompletionQueue* cq, const RpcMethod& method,
- ClientContext* context, R* response,
- bool start, void* tag) {
- Call call = channel->CreateCall(method, context, cq);
+ static ClientAsyncWriter<W>* Create(ChannelInterface* channel,
+ CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncWriter)))
- ClientAsyncWriter(call, context, response, start, tag);
+ call.call(), sizeof(ClientAsyncWriter<W>)))
+ ClientAsyncWriter<W>(call, context, response, start, tag);
}
+};
+} // namespace internal
+/// Async API on the client side for doing client-streaming RPCs,
+/// where the outgoing message stream going to the server contains
+/// messages of type \a W.
+template <class W>
+class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
+ public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncWriter));
@@ -376,9 +403,10 @@
}
private:
+ friend class internal::ClientAsyncWriterFactory<W>;
template <class R>
- ClientAsyncWriter(Call call, ClientContext* context, R* response, bool start,
- void* tag)
+ ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context,
+ R* response, bool start, void* tag)
: context_(context), call_(call), started_(start) {
finish_ops_.RecvMessage(response);
finish_ops_.AllowNoMessage();
@@ -401,13 +429,17 @@
}
ClientContext* context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
- CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
write_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
- CallOpClientRecvStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpGenericRecvMessage,
+ ::grpc::internal::CallOpClientRecvStatus>
finish_ops_;
};
@@ -415,9 +447,10 @@
/// where the client-to-server message stream has messages of type \a W,
/// and the server-to-client message stream has messages of type \a R.
template <class W, class R>
-class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
- public AsyncWriterInterface<W>,
- public AsyncReaderInterface<R> {
+class ClientAsyncReaderWriterInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W>,
+ public internal::AsyncReaderInterface<R> {
public:
/// Signal the client is done with the writes (half-close the client stream).
/// Thread-safe with respect to \a AsyncReaderInterface::Read
@@ -426,6 +459,30 @@
virtual void WritesDone(void* tag) = 0;
};
+namespace internal {
+template <class W, class R>
+class ClientAsyncReaderWriterFactory {
+ public:
+ /// Create a stream object.
+ /// Start the RPC request if \a start is set.
+ /// \a tag will be notified on \a cq when the call has been started (i.e.
+ /// intitial metadata sent). If \a start is not set, \a tag must be
+ /// nullptr and the actual call must be initiated by StartCall
+ /// Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ static ClientAsyncReaderWriter<W, R>* Create(
+ ChannelInterface* channel, CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
+
+ return new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientAsyncReaderWriter<W, R>)))
+ ClientAsyncReaderWriter<W, R>(call, context, start, tag);
+ }
+};
+} // namespace internal
+
/// Async client-side interface for bi-directional streaming,
/// where the outgoing message stream going to the server
/// has messages of type \a W, and the incoming message stream coming
@@ -434,25 +491,6 @@
class ClientAsyncReaderWriter final
: public ClientAsyncReaderWriterInterface<W, R> {
public:
- /// Create a stream object.
- /// Start the RPC request if \a start is set.
- /// \a tag will be notified on \a cq when the call has been started (i.e.
- /// intitial metadata sent). If \a start is not set, \a tag must be
- /// nullptr and the actual call must be initiated by StartCall
- /// Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- static ClientAsyncReaderWriter* Create(ChannelInterface* channel,
- CompletionQueue* cq,
- const RpcMethod& method,
- ClientContext* context, bool start,
- void* tag) {
- Call call = channel->CreateCall(method, context, cq);
-
- return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncReaderWriter)))
- ClientAsyncReaderWriter(call, context, start, tag);
- }
-
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncReaderWriter));
@@ -532,8 +570,9 @@
}
private:
- ClientAsyncReaderWriter(Call call, ClientContext* context, bool start,
- void* tag)
+ friend class internal::ClientAsyncReaderWriterFactory<W, R>;
+ ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context,
+ bool start, void* tag)
: context_(context), call_(call), started_(start) {
if (start) {
StartCallInternal(tag);
@@ -554,18 +593,26 @@
}
ClientContext* context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
- CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
write_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
};
template <class W, class R>
-class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface,
- public AsyncReaderInterface<R> {
+class ServerAsyncReaderInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncReaderInterface<R> {
public:
/// Indicate that the stream is to be finished with a certain status code
/// and also send out \a msg response to the client.
@@ -692,20 +739,23 @@
}
private:
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
finish_ops_;
};
template <class W>
-class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface,
- public AsyncWriterInterface<W> {
+class ServerAsyncWriterInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W> {
public:
/// Indicate that the stream is to be finished with a certain status code.
/// Request notification for when the server has sent the appropriate
@@ -823,7 +873,7 @@
}
private:
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
template <class T>
void EnsureInitialMetadataSent(T* ops) {
@@ -837,20 +887,25 @@
}
}
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
write_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_ops_;
};
/// Server-side interface for asynchronous bi-directional streaming.
template <class W, class R>
-class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface,
- public AsyncWriterInterface<W>,
- public AsyncReaderInterface<R> {
+class ServerAsyncReaderWriterInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W>,
+ public internal::AsyncReaderInterface<R> {
public:
/// Indicate that the stream is to be finished with a certain status code.
/// Request notification for when the server has sent the appropriate
@@ -980,7 +1035,7 @@
private:
friend class ::grpc::Server;
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
template <class T>
void EnsureInitialMetadataSent(T* ops) {
@@ -994,14 +1049,18 @@
}
}
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
write_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_ops_;
};
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index e472f04..6d51c78 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -69,11 +69,9 @@
virtual void Finish(R* msg, Status* status, void* tag) = 0;
};
-/// Async API for client-side unary RPCs, where the message response
-/// received from the server is of type \a R.
+namespace internal {
template <class R>
-class ClientAsyncResponseReader final
- : public ClientAsyncResponseReaderInterface<R> {
+class ClientAsyncResponseReaderFactory {
public:
/// Start a call and write the request out if \a start is set.
/// \a tag will be notified on \a cq when the call has been started (i.e.
@@ -82,17 +80,24 @@
/// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
template <class W>
- static ClientAsyncResponseReader* Create(ChannelInterface* channel,
- CompletionQueue* cq,
- const RpcMethod& method,
- ClientContext* context,
- const W& request, bool start) {
- Call call = channel->CreateCall(method, context, cq);
+ static ClientAsyncResponseReader<R>* Create(
+ ChannelInterface* channel, CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context,
+ const W& request, bool start) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncResponseReader)))
- ClientAsyncResponseReader(call, context, request, start);
+ call.call(), sizeof(ClientAsyncResponseReader<R>)))
+ ClientAsyncResponseReader<R>(call, context, request, start);
}
+};
+} // namespace internal
+/// Async API for client-side unary RPCs, where the message response
+/// received from the server is of type \a R.
+template <class R>
+class ClientAsyncResponseReader final
+ : public ClientAsyncResponseReaderInterface<R> {
+ public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncResponseReader));
@@ -137,13 +142,14 @@
}
private:
+ friend class internal::ClientAsyncResponseReaderFactory<R>;
ClientContext* const context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
template <class W>
- ClientAsyncResponseReader(Call call, ClientContext* context, const W& request,
- bool start)
+ ClientAsyncResponseReader(::grpc::internal::Call call, ClientContext* context,
+ const W& request, bool start)
: context_(context), call_(call), started_(start) {
// Bind the metadata at time of StartCallInternal but set up the rest here
// TODO(ctiller): don't assert
@@ -162,19 +168,23 @@
static void* operator new(std::size_t size);
static void* operator new(std::size_t size, void* p) { return p; }
- SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
+ ::grpc::internal::SneakyCallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
init_buf;
- CallOpSet<CallOpRecvInitialMetadata> meta_buf;
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
- CallOpClientRecvStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_buf;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>,
+ ::grpc::internal::CallOpClientRecvStatus>
finish_buf;
};
/// Async server-side API for handling unary calls, where the single
/// response message sent to the client is of type \a W.
template <class W>
-class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface {
+class ServerAsyncResponseWriter final
+ : public internal::ServerAsyncStreamingInterface {
public:
explicit ServerAsyncResponseWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -262,13 +272,15 @@
}
private:
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_buf_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_buf_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
finish_buf_;
};
diff --git a/include/grpc++/impl/codegen/byte_buffer.h b/include/grpc++/impl/codegen/byte_buffer.h
index 57d731b..fe73ce7 100644
--- a/include/grpc++/impl/codegen/byte_buffer.h
+++ b/include/grpc++/impl/codegen/byte_buffer.h
@@ -31,18 +31,19 @@
namespace grpc {
+namespace internal {
+class CallOpSendMessage;
template <class R>
class CallOpRecvMessage;
+class CallOpGenericRecvMessage;
class MethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
-namespace CallOpGenericRecvMessageHelper {
template <class R>
class DeserializeFuncType;
-} // namespace CallOpGenericRecvMessageHelper
-
+} // namespace internal
/// A sequence of bytes.
class ByteBuffer final {
public:
@@ -97,17 +98,17 @@
private:
friend class SerializationTraits<ByteBuffer, void>;
- friend class CallOpSendMessage;
+ friend class internal::CallOpSendMessage;
template <class R>
- friend class CallOpRecvMessage;
- friend class CallOpGenericRecvMessage;
- friend class MethodHandler;
+ friend class internal::CallOpRecvMessage;
+ friend class internal::CallOpGenericRecvMessage;
+ friend class internal::MethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class RpcMethodHandler;
+ friend class internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ServerStreamingHandler;
+ friend class internal::ServerStreamingHandler;
template <class R>
- friend class CallOpGenericRecvMessageHelper::DeserializeFuncType;
+ friend class internal::DeserializeFuncType;
grpc_byte_buffer* buffer_;
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index 06f107f..1a98829 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -43,11 +43,13 @@
namespace grpc {
class ByteBuffer;
-class Call;
-class CallHook;
class CompletionQueue;
extern CoreCodegenInterface* g_core_codegen_interface;
+namespace internal {
+class Call;
+class CallHook;
+
const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
// TODO(yangg) if the map is changed before we send, the pointers will be a
@@ -75,6 +77,7 @@
}
return metadata_array;
}
+} // namespace internal
/// Per-message write options.
class WriteOptions {
@@ -199,6 +202,7 @@
bool last_message_;
};
+namespace internal {
/// Default argument for CallOpSet. I is unused by the class, but can be
/// used for generating multiple names for the same thing.
template <int I>
@@ -387,7 +391,6 @@
bool allow_not_getting_message_;
};
-namespace CallOpGenericRecvMessageHelper {
class DeserializeFunc {
public:
virtual Status Deserialize(ByteBuffer* buf) = 0;
@@ -407,7 +410,6 @@
private:
R* message_; // Not a managed pointer because management is external to this
};
-} // namespace CallOpGenericRecvMessageHelper
class CallOpGenericRecvMessage {
public:
@@ -418,8 +420,7 @@
void RecvMessage(R* message) {
// Use an explicit base class pointer to avoid resolution error in the
// following unique_ptr::reset for some old implementations.
- CallOpGenericRecvMessageHelper::DeserializeFunc* func =
- new CallOpGenericRecvMessageHelper::DeserializeFuncType<R>(message);
+ DeserializeFunc* func = new DeserializeFuncType<R>(message);
deserialize_.reset(func);
}
@@ -459,7 +460,7 @@
}
private:
- std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
+ std::unique_ptr<DeserializeFunc> deserialize_;
ByteBuffer recv_buf_;
bool allow_not_getting_message_;
};
@@ -714,7 +715,7 @@
grpc_call* call_;
int max_receive_message_size_;
};
-
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CALL_H
diff --git a/include/grpc++/impl/codegen/call_hook.h b/include/grpc++/impl/codegen/call_hook.h
index d026cc8..44e9de2 100644
--- a/include/grpc++/impl/codegen/call_hook.h
+++ b/include/grpc++/impl/codegen/call_hook.h
@@ -21,6 +21,7 @@
namespace grpc {
+namespace internal {
class CallOpSetInterface;
class Call;
@@ -31,6 +32,7 @@
virtual ~CallHook() {}
virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/channel_interface.h b/include/grpc++/impl/codegen/channel_interface.h
index 1b7590b..769f853 100644
--- a/include/grpc++/impl/codegen/channel_interface.h
+++ b/include/grpc++/impl/codegen/channel_interface.h
@@ -24,10 +24,8 @@
#include <grpc/impl/codegen/connectivity_state.h>
namespace grpc {
-class Call;
+class ChannelInterface;
class ClientContext;
-class RpcMethod;
-class CallOpSetInterface;
class CompletionQueue;
template <class R>
@@ -36,14 +34,22 @@
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
+
+namespace internal {
+class Call;
+class CallOpSetInterface;
+class RpcMethod;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
template <class R>
-class ClientAsyncReader;
+class ClientAsyncReaderFactory;
template <class W>
-class ClientAsyncWriter;
+class ClientAsyncWriterFactory;
template <class W, class R>
-class ClientAsyncReaderWriter;
+class ClientAsyncReaderWriterFactory;
template <class R>
-class ClientAsyncResponseReader;
+class ClientAsyncResponseReaderFactory;
+} // namespace internal
/// Codegen interface for \a grpc::Channel.
class ChannelInterface {
@@ -88,23 +94,21 @@
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
- friend class ::grpc::ClientAsyncReader;
+ friend class ::grpc::internal::ClientAsyncReaderFactory;
template <class W>
- friend class ::grpc::ClientAsyncWriter;
+ friend class ::grpc::internal::ClientAsyncWriterFactory;
template <class W, class R>
- friend class ::grpc::ClientAsyncReaderWriter;
+ friend class ::grpc::internal::ClientAsyncReaderWriterFactory;
template <class R>
- friend class ::grpc::ClientAsyncResponseReader;
+ friend class ::grpc::internal::ClientAsyncResponseReaderFactory;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
- friend class ::grpc::RpcMethod;
- virtual Call CreateCall(const RpcMethod& method, ClientContext* context,
- CompletionQueue* cq) = 0;
- virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
+ friend class ::grpc::internal::RpcMethod;
+ virtual internal::Call CreateCall(const internal::RpcMethod& method,
+ ClientContext* context,
+ CompletionQueue* cq) = 0;
+ virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) = 0;
virtual void* RegisterMethod(const char* method) = 0;
virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
@@ -112,7 +116,6 @@
virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) = 0;
};
-
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index 6d7e13b..22b581c 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -60,7 +60,16 @@
class ChannelInterface;
class CompletionQueue;
class CallCredentials;
+class ClientContext;
+
+namespace internal {
class RpcMethod;
+class CallOpClientRecvStatus;
+class CallOpRecvInitialMetadata;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
+} // namespace internal
+
template <class R>
class ClientReader;
template <class W>
@@ -345,8 +354,8 @@
ClientContext& operator=(const ClientContext&);
friend class ::grpc::testing::InteropClientContextInspector;
- friend class CallOpClientRecvStatus;
- friend class CallOpRecvInitialMetadata;
+ friend class ::grpc::internal::CallOpClientRecvStatus;
+ friend class ::grpc::internal::CallOpRecvInitialMetadata;
friend class Channel;
template <class R>
friend class ::grpc::ClientReader;
@@ -363,11 +372,7 @@
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
grpc_call* call() const { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
@@ -399,8 +404,8 @@
mutable std::shared_ptr<const AuthContext> auth_context_;
struct census_context* census_context_;
std::multimap<grpc::string, grpc::string> send_initial_metadata_;
- MetadataMap recv_initial_metadata_;
- MetadataMap trailing_metadata_;
+ internal::MetadataMap recv_initial_metadata_;
+ internal::MetadataMap trailing_metadata_;
grpc_call* propagate_from_call_;
PropagationOptions propagation_options_;
diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h
index 7c540fa..170c562 100644
--- a/include/grpc++/impl/codegen/client_unary_call.h
+++ b/include/grpc++/impl/codegen/client_unary_call.h
@@ -30,43 +30,60 @@
class Channel;
class ClientContext;
class CompletionQueue;
-class RpcMethod;
+namespace internal {
+class RpcMethod;
/// Wrapper that performs a blocking unary call
template <class InputMessage, class OutputMessage>
Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, const InputMessage& request,
OutputMessage* result) {
- CompletionQueue cq(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue
- Call call(channel->CreateCall(method, context, &cq));
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
- CallOpClientSendClose, CallOpClientRecvStatus>
- ops;
- Status status = ops.SendMessage(request);
- if (!status.ok()) {
- return status;
- }
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- ops.RecvInitialMetadata(context);
- ops.RecvMessage(result);
- ops.ClientSendClose();
- ops.ClientRecvStatus(context, &status);
- call.PerformOps(&ops);
- if (cq.Pluck(&ops)) {
- if (!ops.got_message && status.ok()) {
- return Status(StatusCode::UNIMPLEMENTED,
- "No message returned for unary request");
- }
- } else {
- GPR_CODEGEN_ASSERT(!status.ok());
- }
- return status;
-}
+ return BlockingUnaryCallImpl<InputMessage, OutputMessage>(
+ channel, method, context, request, result)
+ .status();
+};
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl {
+ public:
+ BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method,
+ ClientContext* context, const InputMessage& request,
+ OutputMessage* result) {
+ CompletionQueue cq(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue
+ Call call(channel->CreateCall(method, context, &cq));
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
+ CallOpClientSendClose, CallOpClientRecvStatus>
+ ops;
+ status_ = ops.SendMessage(request);
+ if (!status_.ok()) {
+ return;
+ }
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ ops.RecvInitialMetadata(context);
+ ops.RecvMessage(result);
+ ops.ClientSendClose();
+ ops.ClientRecvStatus(context, &status_);
+ call.PerformOps(&ops);
+ if (cq.Pluck(&ops)) {
+ if (!ops.got_message && status_.ok()) {
+ status_ = Status(StatusCode::UNIMPLEMENTED,
+ "No message returned for unary request");
+ }
+ } else {
+ GPR_CODEGEN_ASSERT(!status_.ok());
+ }
+ }
+ Status status() { return status_; }
+
+ private:
+ Status status_;
+};
+
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index e2c0c29..14de30a 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -56,7 +56,19 @@
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
-}
+} // namespace internal
+
+class Channel;
+class ChannelInterface;
+class ClientContext;
+class CompletionQueue;
+class Server;
+class ServerBuilder;
+class ServerContext;
+
+namespace internal {
+class CompletionQueueTag;
+class RpcMethod;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -66,16 +78,11 @@
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
-
-class Channel;
-class ChannelInterface;
-class ClientContext;
-class CompletionQueueTag;
-class CompletionQueue;
-class RpcMethod;
-class Server;
-class ServerBuilder;
-class ServerContext;
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
+} // namespace internal
extern CoreCodegenInterface* g_core_codegen_interface;
@@ -220,22 +227,18 @@
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
- friend class RpcMethodHandler;
+ friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ClientStreamingHandler;
+ friend class ::grpc::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ServerStreamingHandler;
+ friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
- friend class TemplatedBidiStreamingHandler;
- friend class UnknownMethodHandler;
+ friend class ::grpc::internal::TemplatedBidiStreamingHandler;
+ friend class ::grpc::internal::UnknownMethodHandler;
friend class ::grpc::Server;
friend class ::grpc::ServerContext;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
/// EXPERIMENTAL
/// Creates a Thread Local cache to store the first event
@@ -256,7 +259,7 @@
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
- bool Pluck(CompletionQueueTag* tag) {
+ bool Pluck(internal::CompletionQueueTag* tag) {
auto deadline =
g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
@@ -277,7 +280,7 @@
/// implementation to simple call the other TryPluck function with a zero
/// timeout. i.e:
/// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
- void TryPluck(CompletionQueueTag* tag) {
+ void TryPluck(internal::CompletionQueueTag* tag) {
auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
@@ -293,7 +296,7 @@
///
/// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
/// that the tag is internal not something that is returned to the user.
- void TryPluck(CompletionQueueTag* tag, gpr_timespec deadline) {
+ void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) {
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
diff --git a/include/grpc++/impl/codegen/completion_queue_tag.h b/include/grpc++/impl/codegen/completion_queue_tag.h
index 4d7d3a9..cb16bcf 100644
--- a/include/grpc++/impl/codegen/completion_queue_tag.h
+++ b/include/grpc++/impl/codegen/completion_queue_tag.h
@@ -21,6 +21,7 @@
namespace grpc {
+namespace internal {
/// An interface allowing implementors to process and filter event tags.
class CompletionQueueTag {
public:
@@ -31,6 +32,7 @@
/// queue
virtual bool FinalizeResult(void** tag, bool* status) = 0;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/metadata_map.h b/include/grpc++/impl/codegen/metadata_map.h
index b739859..fd4750e 100644
--- a/include/grpc++/impl/codegen/metadata_map.h
+++ b/include/grpc++/impl/codegen/metadata_map.h
@@ -23,6 +23,7 @@
namespace grpc {
+namespace internal {
class MetadataMap {
public:
MetadataMap() { memset(&arr_, 0, sizeof(arr_)); }
@@ -50,6 +51,7 @@
grpc_metadata_array arr_;
std::multimap<grpc::string_ref, grpc::string_ref> map_;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h
index e14cb0e..c0af4ca 100644
--- a/include/grpc++/impl/codegen/method_handler_impl.h
+++ b/include/grpc++/impl/codegen/method_handler_impl.h
@@ -26,6 +26,7 @@
namespace grpc {
+namespace internal {
/// A wrapper class of an application provided rpc method handler.
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler : public MethodHandler {
@@ -266,6 +267,7 @@
}
};
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
diff --git a/include/grpc++/impl/codegen/rpc_method.h b/include/grpc++/impl/codegen/rpc_method.h
index ac13ac5..54e5236 100644
--- a/include/grpc++/impl/codegen/rpc_method.h
+++ b/include/grpc++/impl/codegen/rpc_method.h
@@ -24,7 +24,7 @@
#include <grpc++/impl/codegen/channel_interface.h>
namespace grpc {
-
+namespace internal {
/// Descriptor of an RPC method
class RpcMethod {
public:
@@ -55,6 +55,7 @@
void* const channel_tag_;
};
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_RPC_METHOD_H
diff --git a/include/grpc++/impl/codegen/rpc_service_method.h b/include/grpc++/impl/codegen/rpc_service_method.h
index d356012..5ba11e8 100644
--- a/include/grpc++/impl/codegen/rpc_service_method.h
+++ b/include/grpc++/impl/codegen/rpc_service_method.h
@@ -32,8 +32,8 @@
namespace grpc {
class ServerContext;
-class StreamContextInterface;
+namespace internal {
/// Base class for running an RPC handler.
class MethodHandler {
public:
@@ -71,6 +71,7 @@
void* server_tag_;
std::unique_ptr<MethodHandler> handler_;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index b5e37fd..a2d6967 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -55,7 +55,6 @@
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
-}
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -65,9 +64,11 @@
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
-
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler;
class Call;
-class CallOpBuffer;
+} // namespace internal
+
class CompletionQueue;
class Server;
class ServerInterface;
@@ -247,14 +248,14 @@
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
- friend class RpcMethodHandler;
+ friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ClientStreamingHandler;
+ friend class ::grpc::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ServerStreamingHandler;
+ friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
- friend class TemplatedBidiStreamingHandler;
- friend class UnknownMethodHandler;
+ friend class ::grpc::internal::TemplatedBidiStreamingHandler;
+ friend class ::grpc::internal::UnknownMethodHandler;
friend class ::grpc::ClientContext;
/// Prevent copying.
@@ -263,9 +264,9 @@
class CompletionOp;
- void BeginCompletionOp(Call* call);
+ void BeginCompletionOp(internal::Call* call);
/// Return the tag queued by BeginCompletionOp()
- CompletionQueueTag* GetCompletionOpTag();
+ internal::CompletionQueueTag* GetCompletionOpTag();
ServerContext(gpr_timespec deadline, grpc_metadata_array* arr);
@@ -282,7 +283,7 @@
CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
- MetadataMap client_metadata_;
+ internal::MetadataMap client_metadata_;
std::multimap<grpc::string, grpc::string> initial_metadata_;
std::multimap<grpc::string, grpc::string> trailing_metadata_;
@@ -290,7 +291,9 @@
grpc_compression_level compression_level_;
grpc_compression_algorithm compression_algorithm_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> pending_ops_;
+ internal::CallOpSet<internal::CallOpSendInitialMetadata,
+ internal::CallOpSendMessage>
+ pending_ops_;
bool has_pending_ops_;
};
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
index 55937f1..3bcf4c8 100644
--- a/include/grpc++/impl/codegen/server_interface.h
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -30,20 +30,21 @@
class AsyncGenericService;
class Channel;
class GenericServerContext;
-class RpcService;
-class ServerAsyncStreamingInterface;
class ServerCompletionQueue;
class ServerContext;
class ServerCredentials;
class Service;
-class ThreadPoolInterface;
extern CoreCodegenInterface* g_core_codegen_interface;
/// Models a gRPC server.
///
/// Servers are configured and started via \a grpc::ServerBuilder.
-class ServerInterface : public CallHook {
+namespace internal {
+class ServerAsyncStreamingInterface;
+} // namespace internal
+
+class ServerInterface : public internal::CallHook {
public:
virtual ~ServerInterface() {}
@@ -78,7 +79,7 @@
virtual void Wait() = 0;
protected:
- friend class Service;
+ friend class ::grpc::Service;
/// Register a service. This call does not take ownership of the service.
/// The service must exist for the lifetime of the Server instance.
@@ -116,12 +117,13 @@
virtual grpc_server* server() = 0;
- virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+ virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) = 0;
- class BaseAsyncRequest : public CompletionQueueTag {
+ class BaseAsyncRequest : public internal::CompletionQueueTag {
public:
BaseAsyncRequest(ServerInterface* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag,
bool delete_on_finalize);
virtual ~BaseAsyncRequest();
@@ -131,7 +133,7 @@
protected:
ServerInterface* const server_;
ServerContext* const context_;
- ServerAsyncStreamingInterface* const stream_;
+ internal::ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
void* const tag_;
const bool delete_on_finalize_;
@@ -141,7 +143,7 @@
class RegisteredAsyncRequest : public BaseAsyncRequest {
public:
RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag);
// uses BaseAsyncRequest::FinalizeResult
@@ -155,7 +157,7 @@
public:
NoPayloadAsyncRequest(void* registered_method, ServerInterface* server,
ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
: RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
@@ -170,7 +172,7 @@
public:
PayloadAsyncRequest(void* registered_method, ServerInterface* server,
ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
@@ -212,7 +214,7 @@
void* const registered_method_;
ServerInterface* const server_;
ServerContext* const context_;
- ServerAsyncStreamingInterface* const stream_;
+ internal::ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
ServerCompletionQueue* const notification_cq_;
void* const tag_;
@@ -223,7 +225,7 @@
class GenericAsyncRequest : public BaseAsyncRequest {
public:
GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
@@ -235,8 +237,9 @@
};
template <class Message>
- void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ void RequestAsyncCall(internal::RpcServiceMethod* method,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* message) {
@@ -246,8 +249,9 @@
message);
}
- void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ void RequestAsyncCall(internal::RpcServiceMethod* method,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
GPR_CODEGEN_ASSERT(method);
@@ -256,7 +260,7 @@
}
void RequestAsyncGenericCall(GenericServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
diff --git a/include/grpc++/impl/codegen/service_type.h b/include/grpc++/impl/codegen/service_type.h
index 2dc4ea0..71c3d99 100644
--- a/include/grpc++/impl/codegen/service_type.h
+++ b/include/grpc++/impl/codegen/service_type.h
@@ -28,13 +28,14 @@
namespace grpc {
-class Call;
class CompletionQueue;
class Server;
class ServerInterface;
class ServerCompletionQueue;
class ServerContext;
+namespace internal {
+class Call;
class ServerAsyncStreamingInterface {
public:
virtual ~ServerAsyncStreamingInterface() {}
@@ -48,9 +49,10 @@
virtual void SendInitialMetadata(void* tag) = 0;
private:
- friend class ServerInterface;
+ friend class ::grpc::ServerInterface;
virtual void BindCall(Call* call) = 0;
};
+} // namespace internal
/// Desriptor of an RPC service and its various RPC methods
class Service {
@@ -88,40 +90,38 @@
protected:
template <class Message>
void RequestAsyncUnary(int index, ServerContext* context, Message* request,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
- void RequestAsyncClientStreaming(int index, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
+ void RequestAsyncClientStreaming(
+ int index, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
template <class Message>
- void RequestAsyncServerStreaming(int index, ServerContext* context,
- Message* request,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
+ void RequestAsyncServerStreaming(
+ int index, ServerContext* context, Message* request,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
- void RequestAsyncBidiStreaming(int index, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
+ void RequestAsyncBidiStreaming(
+ int index, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
- void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
+ void AddMethod(internal::RpcServiceMethod* method) {
+ methods_.emplace_back(method);
+ }
void MarkMethodAsync(int index) {
GPR_CODEGEN_ASSERT(
@@ -139,7 +139,7 @@
methods_[index].reset();
}
- void MarkMethodStreamed(int index, MethodHandler* streamed_method) {
+ void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
"Cannot mark an async or generic method Streamed");
methods_[index]->SetHandler(streamed_method);
@@ -148,14 +148,14 @@
// case of BIDI_STREAMING that has 1 read and 1 write, in that order,
// and split server-side streaming is BIDI_STREAMING with 1 read and
// any number of writes, in that order.
- methods_[index]->SetMethodType(::grpc::RpcMethod::BIDI_STREAMING);
+ methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
}
private:
friend class Server;
friend class ServerInterface;
ServerInterface* server_;
- std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
+ std::vector<std::unique_ptr<internal::RpcServiceMethod>> methods_;
};
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index c1784f1..a6dd26f 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -30,6 +30,7 @@
namespace grpc {
+namespace internal {
/// Common interface for all synchronous client side streaming.
class ClientStreamingInterface {
public:
@@ -141,10 +142,12 @@
}
};
+} // namespace internal
+
/// Client-side interface for streaming reads of message of type \a R.
template <class R>
-class ClientReaderInterface : public ClientStreamingInterface,
- public ReaderInterface<R> {
+class ClientReaderInterface : public internal::ClientStreamingInterface,
+ public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
@@ -153,35 +156,25 @@
virtual void WaitForInitialMetadata() = 0;
};
+namespace internal {
+template <class R>
+class ClientReaderFactory {
+ public:
+ template <class W>
+ static ClientReader<R>* Create(ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request) {
+ return new ClientReader<R>(channel, method, context, request);
+ }
+};
+} // namespace internal
+
/// Synchronous (blocking) client-side API for doing server-streaming RPCs,
/// where the stream of messages coming from the server has messages
/// of type \a R.
template <class R>
class ClientReader final : public ClientReaderInterface<R> {
public:
- /// Block to create a stream and write the initial metadata and \a request
- /// out. Note that \a context will be used to fill in custom initial
- /// metadata used to send to the server when starting the call.
- template <class W>
- ClientReader(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context, const W& request)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
- ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
- ops.ClientSendClose();
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
-
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
@@ -192,7 +185,8 @@
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
- CallOpSet<CallOpRecvInitialMetadata> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); /// status ignored
@@ -209,7 +203,9 @@
/// already received (if initial metadata is received, it can be then
/// accessed through the \a ClientContext associated with this call).
bool Read(R* msg) override {
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
@@ -224,7 +220,7 @@
/// The \a ClientContext associated with this call is updated with
/// possible metadata received from the server.
Status Finish() override {
- CallOpSet<CallOpClientRecvStatus> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops;
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
@@ -233,15 +229,41 @@
}
private:
+ friend class internal::ClientReaderFactory<R>;
ClientContext* context_;
CompletionQueue cq_;
- Call call_;
+ ::grpc::internal::Call call_;
+
+ /// Block to create a stream and write the initial metadata and \a request
+ /// out. Note that \a context will be used to fill in custom initial
+ /// metadata used to send to the server when starting the call.
+ template <class W>
+ ClientReader(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
+ ops.ClientSendClose();
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
};
/// Client-side interface for streaming writes of message type \a W.
template <class W>
-class ClientWriterInterface : public ClientStreamingInterface,
- public WriterInterface<W> {
+class ClientWriterInterface : public internal::ClientStreamingInterface,
+ public internal::WriterInterface<W> {
public:
/// Half close writing from the client. (signal that the stream of messages
/// coming from the client is complete).
@@ -252,37 +274,25 @@
virtual bool WritesDone() = 0;
};
+namespace internal {
+template <class W>
+class ClientWriterFactory {
+ public:
+ template <class R>
+ static ClientWriter<W>* Create(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response) {
+ return new ClientWriter<W>(channel, method, context, response);
+ }
+};
+} // namespace internal
+
/// Synchronous (blocking) client-side API for doing client-streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W.
template <class W>
class ClientWriter : public ClientWriterInterface<W> {
public:
- /// Block to create a stream (i.e. send request headers and other initial
- /// metadata to the server). Note that \a context will be used to fill
- /// in custom initial metadata. \a response will be filled in with the
- /// single expected response message from the server upon a successful
- /// call to the \a Finish method of this instance.
- template <class R>
- ClientWriter(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context, R* response)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- finish_ops_.RecvMessage(response);
- finish_ops_.AllowNoMessage();
-
- if (!context_->initial_metadata_corked_) {
- CallOpSet<CallOpSendInitialMetadata> ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
- }
-
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
@@ -292,7 +302,8 @@
void WaitForInitialMetadata() {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
- CallOpSet<CallOpRecvInitialMetadata> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
@@ -304,10 +315,11 @@
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call).
- using WriterInterface<W>::Write;
+ using ::grpc::internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
@@ -328,7 +340,7 @@
}
bool WritesDone() override {
- CallOpSet<CallOpClientSendClose> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
@@ -352,21 +364,51 @@
}
private:
+ friend class internal::ClientWriterFactory<W>;
+
+ /// Block to create a stream (i.e. send request headers and other initial
+ /// metadata to the server). Note that \a context will be used to fill
+ /// in custom initial metadata. \a response will be filled in with the
+ /// single expected response message from the server upon a successful
+ /// call to the \a Finish method of this instance.
+ template <class R>
+ ClientWriter(ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ finish_ops_.RecvMessage(response);
+ finish_ops_.AllowNoMessage();
+
+ if (!context_->initial_metadata_corked_) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
+ }
+
ClientContext* context_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
- CallOpClientRecvStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpGenericRecvMessage,
+ ::grpc::internal::CallOpClientRecvStatus>
finish_ops_;
CompletionQueue cq_;
- Call call_;
+ ::grpc::internal::Call call_;
};
/// Client-side interface for bi-directional streaming with
/// client-to-server stream messages of type \a W and
/// server-to-client stream messages of type \a R.
template <class W, class R>
-class ClientReaderWriterInterface : public ClientStreamingInterface,
- public WriterInterface<W>,
- public ReaderInterface<R> {
+class ClientReaderWriterInterface : public internal::ClientStreamingInterface,
+ public internal::WriterInterface<W>,
+ public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
@@ -375,7 +417,7 @@
virtual void WaitForInitialMetadata() = 0;
/// Half close writing from the client. (signal that the stream of messages
- /// coming from the client is complete).
+ /// coming from the clinet is complete).
/// Blocks until currently-pending writes are completed.
/// Thread-safe with respect to \a ReaderInterface::Read
///
@@ -383,6 +425,18 @@
virtual bool WritesDone() = 0;
};
+namespace internal {
+template <class W, class R>
+class ClientReaderWriterFactory {
+ public:
+ static ClientReaderWriter<W, R>* Create(
+ ::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context) {
+ return new ClientReaderWriter<W, R>(channel, method, context);
+ }
+};
+} // namespace internal
+
/// Synchronous (blocking) client-side API for bi-directional streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W, and the incoming messages stream coming from the server has
@@ -390,25 +444,6 @@
template <class W, class R>
class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
public:
- /// Block to create a stream and write the initial metadata and \a request
- /// out. Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- if (!context_->initial_metadata_corked_) {
- CallOpSet<CallOpSendInitialMetadata> ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
- }
-
/// Block waiting to read initial metadata from the server.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
@@ -418,7 +453,8 @@
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
- CallOpSet<CallOpRecvInitialMetadata> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
@@ -434,7 +470,9 @@
/// Also receives initial metadata if not already received (updates the \a
/// ClientContext associated with this call in that case).
bool Read(R* msg) override {
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
@@ -448,10 +486,11 @@
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
- using WriterInterface<W>::Write;
+ using ::grpc::internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
@@ -472,7 +511,7 @@
}
bool WritesDone() override {
- CallOpSet<CallOpClientSendClose> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
@@ -484,7 +523,9 @@
/// - the \a ClientContext associated with this call is updated with
/// possible trailing metadata sent from the server.
Status Finish() override {
- CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
@@ -496,15 +537,38 @@
}
private:
+ friend class internal::ClientReaderWriterFactory<W, R>;
+
ClientContext* context_;
CompletionQueue cq_;
- Call call_;
+ ::grpc::internal::Call call_;
+
+ /// Block to create a stream and write the initial metadata and \a request
+ /// out. Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ ClientReaderWriter(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ if (!context_->initial_metadata_corked_) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
+ }
};
/// Server-side interface for streaming reads of message of type \a R.
template <class R>
-class ServerReaderInterface : public ServerStreamingInterface,
- public ReaderInterface<R> {};
+class ServerReaderInterface : public internal::ServerStreamingInterface,
+ public internal::ReaderInterface<R> {};
/// Synchronous (blocking) server-side API for doing client-streaming RPCs,
/// where the incoming message stream coming from the client has messages of
@@ -512,15 +576,13 @@
template <class R>
class ServerReader final : public ServerReaderInterface<R> {
public:
- ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
-
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata> ops;
+ internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
@@ -537,21 +599,27 @@
}
bool Read(R* msg) override {
- CallOpSet<CallOpRecvMessage<R>> ops;
+ internal::CallOpSet<internal::CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
private:
- Call* const call_;
+ internal::Call* const call_;
ServerContext* const ctx_;
+
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::ClientStreamingHandler;
+
+ ServerReader(internal::Call* call, ServerContext* ctx)
+ : call_(call), ctx_(ctx) {}
};
/// Server-side interface for streaming writes of message of type \a W.
template <class W>
-class ServerWriterInterface : public ServerStreamingInterface,
- public WriterInterface<W> {};
+class ServerWriterInterface : public internal::ServerStreamingInterface,
+ public internal::WriterInterface<W> {};
/// Synchronous (blocking) server-side API for doing for doing a
/// server-streaming RPCs, where the outgoing message stream coming from the
@@ -559,8 +627,6 @@
template <class W>
class ServerWriter final : public ServerWriterInterface<W> {
public:
- ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
-
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics.
/// Note that initial metadata will be affected by the
@@ -568,7 +634,7 @@
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata> ops;
+ internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
@@ -584,11 +650,12 @@
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
- using WriterInterface<W>::Write;
+ using internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
if (options.is_last_message()) {
options.set_buffer_hint();
}
+
if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) {
return false;
}
@@ -613,15 +680,21 @@
}
private:
- Call* const call_;
+ internal::Call* const call_;
ServerContext* const ctx_;
+
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::ServerStreamingHandler;
+
+ ServerWriter(internal::Call* call, ServerContext* ctx)
+ : call_(call), ctx_(ctx) {}
};
/// Server-side interface for bi-directional streaming.
template <class W, class R>
-class ServerReaderWriterInterface : public ServerStreamingInterface,
- public WriterInterface<W>,
- public ReaderInterface<R> {};
+class ServerReaderWriterInterface : public internal::ServerStreamingInterface,
+ public internal::WriterInterface<W>,
+ public internal::ReaderInterface<R> {};
/// Actual implementation of bi-directional streaming
namespace internal {
@@ -688,6 +761,7 @@
Call* const call_;
ServerContext* const ctx_;
};
+
} // namespace internal
/// Synchronous (blocking) server-side API for a bidirectional
@@ -697,8 +771,6 @@
template <class W, class R>
class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
public:
- ServerReaderWriter(Call* call, ServerContext* ctx) : body_(call, ctx) {}
-
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
@@ -715,13 +787,18 @@
/// Side effect:
/// Also sends initial metadata if not already sent (using the \a
/// ServerContext associated with this call).
- using WriterInterface<W>::Write;
+ using internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
return body_.Write(msg, options);
}
private:
internal::ServerReaderWriterBody<W, R> body_;
+
+ friend class internal::TemplatedBidiStreamingHandler<ServerReaderWriter<W, R>,
+ false>;
+ ServerReaderWriter(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx) {}
};
/// A class to represent a flow-controlled unary call. This is something
@@ -736,9 +813,6 @@
class ServerUnaryStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
- ServerUnaryStreamer(Call* call, ServerContext* ctx)
- : body_(call, ctx), read_done_(false), write_done_(false) {}
-
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
@@ -775,7 +849,7 @@
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
- using WriterInterface<ResponseType>::Write;
+ using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response, WriteOptions options) override {
if (write_done_ || !read_done_) {
return false;
@@ -788,6 +862,11 @@
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
bool write_done_;
+
+ friend class internal::TemplatedBidiStreamingHandler<
+ ServerUnaryStreamer<RequestType, ResponseType>, true>;
+ ServerUnaryStreamer(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx), read_done_(false), write_done_(false) {}
};
/// A class to represent a flow-controlled server-side streaming call.
@@ -799,9 +878,6 @@
class ServerSplitStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
- ServerSplitStreamer(Call* call, ServerContext* ctx)
- : body_(call, ctx), read_done_(false) {}
-
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
@@ -838,7 +914,7 @@
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
- using WriterInterface<ResponseType>::Write;
+ using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response, WriteOptions options) override {
return read_done_ && body_.Write(response, options);
}
@@ -846,6 +922,11 @@
private:
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
+
+ friend class internal::TemplatedBidiStreamingHandler<
+ ServerSplitStreamer<RequestType, ResponseType>, false>;
+ ServerSplitStreamer(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx), read_done_(false) {}
};
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/time.h b/include/grpc++/impl/codegen/time.h
index 589deb4..d464d6e 100644
--- a/include/grpc++/impl/codegen/time.h
+++ b/include/grpc++/impl/codegen/time.h
@@ -19,6 +19,8 @@
#ifndef GRPCXX_IMPL_CODEGEN_TIME_H
#define GRPCXX_IMPL_CODEGEN_TIME_H
+#include <chrono>
+
#include <grpc++/impl/codegen/config.h>
#include <grpc/impl/codegen/grpc_types.h>
@@ -59,10 +61,6 @@
} // namespace grpc
-#include <chrono>
-
-#include <grpc/impl/codegen/grpc_types.h>
-
namespace grpc {
// from and to should be absolute time.
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 0a3aae8..01c4a60 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -175,7 +175,8 @@
/// \param num_cqs How many completion queues does \a cqs hold.
void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
- void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) override;
+ void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) override;
void ShutdownInternal(gpr_timespec deadline) override;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index a948abe..0888bef 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -40,7 +40,6 @@
class AsyncGenericService;
class ResourceQuota;
class CompletionQueue;
-class RpcService;
class Server;
class ServerCompletionQueue;
class ServerCredentials;
diff --git a/include/grpc/census.h b/include/grpc/census.h
index de8e7a6..2258af8 100644
--- a/include/grpc/census.h
+++ b/include/grpc/census.h
@@ -16,10 +16,6 @@
*
*/
-/** RPC-internal Census API's. These are designed to be generic enough that
- * they can (ultimately) be used in many different RPC systems (with differing
- * implementations). */
-
#ifndef GRPC_CENSUS_H
#define GRPC_CENSUS_H
@@ -29,439 +25,12 @@
extern "C" {
#endif
-/** Identify census features that can be enabled via census_initialize(). */
-enum census_features {
- CENSUS_FEATURE_NONE = 0, /** Do not enable census. */
- CENSUS_FEATURE_TRACING = 1, /** Enable census tracing. */
- CENSUS_FEATURE_STATS = 2, /** Enable Census stats collection. */
- CENSUS_FEATURE_CPU = 4, /** Enable Census CPU usage collection. */
- CENSUS_FEATURE_ALL =
- CENSUS_FEATURE_TRACING | CENSUS_FEATURE_STATS | CENSUS_FEATURE_CPU
-};
-
-/** Shutdown and startup census subsystem. The 'features' argument should be
- * the OR (|) of census_features values. If census fails to initialize, then
- * census_initialize() will return -1, otherwise the set of enabled features
- * (which may be smaller than that provided in the `features` argument, see
- * census_supported()) is returned. It is an error to call census_initialize()
- * more than once (without an intervening census_shutdown()). These functions
- * are not thread-safe. */
-CENSUSAPI int census_initialize(int features);
-CENSUSAPI void census_shutdown(void);
-
-/** Return the features supported by the current census implementation (not all
- * features will be available on all platforms). */
-CENSUSAPI int census_supported(void);
-
-/** Return the census features currently enabled. */
-CENSUSAPI int census_enabled(void);
-
/**
A Census Context is a handle used by Census to represent the current tracing
and stats collection information. Contexts should be propagated across RPC's
- (this is the responsibility of the local RPC system). A context is typically
- used as the first argument to most census functions. Conceptually, they
- should be thought of as specific to a single RPC/thread. The user visible
- context representation is that of a collection of key:value string pairs,
- each of which is termed a 'tag'; these form the basis against which Census
- metrics will be recorded. Keys are unique within a context. */
+ (this is the responsibility of the local RPC system). */
typedef struct census_context census_context;
-/** A tag is a key:value pair. Both keys and values are nil-terminated strings,
- containing printable ASCII characters (decimal 32-126). Keys must be at
- least one character in length. Both keys and values can have at most
- CENSUS_MAX_TAG_KB_LEN characters (including the terminating nil). The
- maximum number of tags that can be propagated is
- CENSUS_MAX_PROPAGATED_TAGS. Users should also remember that some systems
- may have limits on, e.g., the number of bytes that can be transmitted as
- metadata, and that larger tags means more memory consumed and time in
- processing. */
-typedef struct {
- const char *key;
- const char *value;
- uint8_t flags;
-} census_tag;
-
-/** Maximum length of a tag's key or value. */
-#define CENSUS_MAX_TAG_KV_LEN 255
-/** Maximum number of propagatable tags. */
-#define CENSUS_MAX_PROPAGATED_TAGS 255
-
-/** Tag flags. */
-#define CENSUS_TAG_PROPAGATE 1 /** Tag should be propagated over RPC */
-#define CENSUS_TAG_STATS 2 /** Tag will be used for statistics aggregation */
-#define CENSUS_TAG_RESERVED 4 /** Reserved for internal use. */
-/** Flag values 4,8,16,32,64,128 are reserved for future/internal use. Clients
- should not use or rely on their values. */
-
-#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
-#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
-
-/** An instance of this structure is kept by every context, and records the
- basic information associated with the creation of that context. */
-typedef struct {
- int n_propagated_tags; /** number of propagated tags */
- int n_local_tags; /** number of non-propagated (local) tags */
- int n_deleted_tags; /** number of tags that were deleted */
- int n_added_tags; /** number of tags that were added */
- int n_modified_tags; /** number of tags that were modified */
- int n_invalid_tags; /** number of tags with bad keys or values (e.g.
- longer than CENSUS_MAX_TAG_KV_LEN) */
- int n_ignored_tags; /** number of tags ignored because of
- CENSUS_MAX_PROPAGATED_TAGS limit. */
-} census_context_status;
-
-/** Create a new context, adding and removing tags from an existing context.
- This will copy all tags from the 'tags' input, so it is recommended
- to add as many tags in a single operation as is practical for the client.
- @param base Base context to build upon. Can be NULL.
- @param tags A set of tags to be added/changed/deleted. Tags with keys that
- are in 'tags', but not 'base', are added to the context. Keys that are in
- both 'tags' and 'base' will have their value/flags modified. Tags with keys
- in both, but with NULL values, will be deleted from the context. Tags with
- invalid (too long or short) keys or values will be ignored.
- If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
- binary or non-binary tags, they will be ignored, as will deletions of
- tags that don't exist.
- @param ntags number of tags in 'tags'
- @param status If not NULL, will return a pointer to a census_context_status
- structure containing information about the new context and status of the
- tags used in its creation.
- @return A new, valid census_context.
-*/
-CENSUSAPI census_context *census_context_create(
- const census_context *base, const census_tag *tags, int ntags,
- census_context_status const **status);
-
-/** Destroy a context. Once this function has been called, the context cannot
- be reused. */
-CENSUSAPI void census_context_destroy(census_context *context);
-
-/** Get a pointer to the original status from the context creation. */
-CENSUSAPI const census_context_status *census_context_get_status(
- const census_context *context);
-
-/** Structure used for iterating over the tags in a context. API clients should
- not use or reference internal fields - neither their contents or
- presence/absence are guaranteed. */
-typedef struct {
- const census_context *context;
- int base;
- int index;
- char *kvm;
-} census_context_iterator;
-
-/** Initialize a census_tag_iterator. Must be called before first use. */
-CENSUSAPI void census_context_initialize_iterator(
- const census_context *context, census_context_iterator *iterator);
-
-/** Get the contents of the "next" tag in the context. If there are no more
- tags, returns 0 (and 'tag' contents will be unchanged), otherwise returns 1.
- */
-CENSUSAPI int census_context_next_tag(census_context_iterator *iterator,
- census_tag *tag);
-
-/** Get a context tag by key. Returns 0 if the key is not present. */
-CENSUSAPI int census_context_get_tag(const census_context *context,
- const char *key, census_tag *tag);
-
-/** Tag set encode/decode functionality. These functions are intended
- for use by RPC systems only, for purposes of transmitting/receiving contexts.
- */
-
-/** Encode a context into a buffer.
- @param context context to be encoded
- @param buffer buffer into which the context will be encoded.
- @param buf_size number of available bytes in buffer.
- @return The number of buffer bytes consumed for the encoded context, or
- zero if the buffer was of insufficient size. */
-CENSUSAPI size_t census_context_encode(const census_context *context,
- char *buffer, size_t buf_size);
-
-/** Decode context buffer encoded with census_context_encode(). Returns NULL
- if there is an error in parsing either buffer. */
-CENSUSAPI census_context *census_context_decode(const char *buffer,
- size_t size);
-
-/** Distributed traces can have a number of options. */
-enum census_trace_mask_values {
- CENSUS_TRACE_MASK_NONE = 0, /** Default, empty flags */
- CENSUS_TRACE_MASK_IS_SAMPLED = 1 /** RPC tracing enabled for this context. */
-};
-
-/** Get the current trace mask associated with this context. The value returned
- will be the logical OR of census_trace_mask_values values. */
-CENSUSAPI int census_trace_mask(const census_context *context);
-
-/** Set the trace mask associated with a context. */
-CENSUSAPI void census_set_trace_mask(int trace_mask);
-
-/** The concept of "operation" is a fundamental concept for Census. In an RPC
- system, an operation typically represents a single RPC, or a significant
- sub-part thereof (e.g. a single logical "read" RPC to a distributed storage
- system might do several other actions in parallel, from looking up metadata
- indices to making requests of other services - each of these could be a
- sub-operation with the larger RPC operation). Census uses operations for the
- following:
-
- CPU accounting: If enabled, census will measure the thread CPU time
- consumed between operation start and end times.
-
- Active operations: Census will maintain information on all currently
- active operations.
-
- Distributed tracing: Each operation serves as a logical trace span.
-
- Stats collection: Stats are broken down by operation (e.g. latency
- breakdown for each unique RPC path).
-
- The following functions serve to delineate the start and stop points for
- each logical operation. */
-
-/**
- This structure represents a timestamp as used by census to record the time
- at which an operation begins.
-*/
-typedef struct {
- /** Use gpr_timespec for default implementation. High performance
- * implementations should use a cycle-counter based timestamp. */
- gpr_timespec ts;
-} census_timestamp;
-
-/**
- Mark the beginning of an RPC operation. The information required to call the
- functions to record the start of RPC operations (both client and server) may
- not be callable at the true start time of the operation, due to information
- not being available (e.g. the census context data will not be available in a
- server RPC until at least initial metadata has been processed). To ensure
- correct CPU accounting and latency recording, RPC systems can call this
- function to get the timestamp of operation beginning. This can later be used
- as an argument to census_start_{client,server}_rpc_op(). NB: for correct
- CPU accounting, the system must guarantee that the same thread is used
- for all request processing after this function is called.
-
- @return A timestamp representing the operation start time.
-*/
-CENSUSAPI census_timestamp census_start_rpc_op_timestamp(void);
-
-/**
- Represent functions to map RPC name ID to service/method names. Census
- breaks down all RPC stats by service and method names. We leave the
- definition and format of these to the RPC system. For efficiency purposes,
- we encode these as a single 64 bit identifier, and allow the RPC system to
- provide a structure for functions that can convert these to service and
- method strings.
-
- TODO(aveitch): Instead of providing this as an argument to the rpc_start_op()
- functions, maybe it should be set once at census initialization.
-*/
-typedef struct {
- const char *(*get_rpc_service_name)(int64_t id);
- const char *(*get_rpc_method_name)(int64_t id);
-} census_rpc_name_info;
-
-/**
- Start a client rpc operation. This function should be called as early in the
- client RPC path as possible. This function will create a new context. If
- the context argument is non-null, then the new context will inherit all
- its properties, with the following changes:
- - create a new operation ID for the new context, marking it as a child of
- the previous operation.
- - use the new RPC path and peer information for tracing and stats
- collection purposes, rather than those from the original context
-
- If the context argument is NULL, then a new root context is created. This
- is particularly important for tracing purposes (the trace spans generated
- will be unassociated with any other trace spans, except those
- downstream). The trace_mask will be used for tracing operations associated
- with the new context.
-
- In some RPC systems (e.g. where load balancing is used), peer information
- may not be available at the time the operation starts. In this case, use a
- NULL value for peer, and set it later using the
- census_set_rpc_client_peer() function.
-
- @param context The parent context. Can be NULL.
- @param rpc_name_id The rpc name identifier to be associated with this RPC.
- @param rpc_name_info Used to decode rpc_name_id.
- @param peer RPC peer. If not available at the time, NULL can be used,
- and a later census_set_rpc_client_peer() call made.
- @param trace_mask An OR of census_trace_mask_values values. Only used in
- the creation of a new root context (context == NULL).
- @param start_time A timestamp returned from census_start_rpc_op_timestamp().
- Can be NULL. Used to set the true time the operation
- begins.
-
- @return A new census context.
- */
-CENSUSAPI census_context *census_start_client_rpc_op(
- const census_context *context, int64_t rpc_name_id,
- const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
- const census_timestamp *start_time);
-
-/**
- Add peer information to a context representing a client RPC operation.
-*/
-CENSUSAPI void census_set_rpc_client_peer(census_context *context,
- const char *peer);
-
-/**
- Start a server RPC operation. Returns a new context to be used in future
- census calls. If buffer is non-NULL, then the buffer contents should
- represent the client context, as generated by census_context_serialize().
- If buffer is NULL, a new root context is created.
-
- @param buffer Buffer containing bytes output from census_context_serialize().
- @param rpc_name_id The rpc name identifier to be associated with this RPC.
- @param rpc_name_info Used to decode rpc_name_id.
- @param peer RPC peer.
- @param trace_mask An OR of census_trace_mask_values values. Only used in
- the creation of a new root context (buffer == NULL).
- @param start_time A timestamp returned from census_start_rpc_op_timestamp().
- Can be NULL. Used to set the true time the operation
- begins.
-
- @return A new census context.
- */
-CENSUSAPI census_context *census_start_server_rpc_op(
- const char *buffer, int64_t rpc_name_id,
- const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
- census_timestamp *start_time);
-
-/**
- Start a new, non-RPC operation. In general, this function works very
- similarly to census_start_client_rpc_op, with the primary difference being
- the replacement of host/path information with the more generic family/name
- tags. If the context argument is non-null, then the new context will
- inherit all its properties, with the following changes:
- - create a new operation ID for the new context, marking it as a child of
- the previous operation.
- - use the family and name information for tracing and stats collection
- purposes, rather than those from the original context
-
- If the context argument is NULL, then a new root context is created. This
- is particularly important for tracing purposes (the trace spans generated
- will be unassociated with any other trace spans, except those
- downstream). The trace_mask will be used for tracing
- operations associated with the new context.
-
- @param context The base context. Can be NULL.
- @param family Family name to associate with the trace
- @param name Name within family to associate with traces/stats
- @param trace_mask An OR of census_trace_mask_values values. Only used if
- context is NULL.
-
- @return A new census context.
- */
-CENSUSAPI census_context *census_start_op(census_context *context,
- const char *family, const char *name,
- int trace_mask);
-
-/**
- End an operation started by any of the census_start_*_op*() calls. The
- context used in this call will no longer be valid once this function
- completes.
-
- @param context Context associated with operation which is ending.
- @param status status associated with the operation. Not interpreted by
- census.
-*/
-CENSUSAPI void census_end_op(census_context *context, int status);
-
-#define CENSUS_TRACE_RECORD_START_OP ((uint32_t)0)
-#define CENSUS_TRACE_RECORD_END_OP ((uint32_t)1)
-
-/** Insert a trace record into the trace stream. The record consists of an
- arbitrary size buffer, the size of which is provided in 'n'.
- @param context Trace context
- @param type User-defined type to associate with trace entry.
- @param buffer Pointer to buffer to use
- @param n Number of bytes in buffer
-*/
-CENSUSAPI void census_trace_print(census_context *context, uint32_t type,
- const char *buffer, size_t n);
-
-/** Trace record. */
-typedef struct {
- census_timestamp timestamp; /** Time of record creation */
- uint64_t trace_id; /** Trace ID associated with record */
- uint64_t op_id; /** Operation ID associated with record */
- uint32_t type; /** Type (as used in census_trace_print() */
- const char *buffer; /** Buffer (from census_trace_print() */
- size_t buf_size; /** Number of bytes inside buffer */
-} census_trace_record;
-
-/** Start a scan of existing trace records. While a scan is ongoing, addition
- of new trace records will be blocked if the underlying trace buffers
- fill up, so trace processing systems should endeavor to complete
- reading as soon as possible.
- @param consume if non-zero, indicates that reading records also "consumes"
- the previously read record - i.e. releases space in the trace log
- while scanning is ongoing.
- @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing)
-*/
-CENSUSAPI int census_trace_scan_start(int consume);
-
-/** Get a trace record. The data pointed to by the trace buffer is guaranteed
- stable until the next census_get_trace_record() call (if the consume
- argument to census_trace_scan_start was non-zero) or census_trace_scan_end()
- is called (otherwise).
- @param trace_record structure that will be filled in with oldest trace record.
- @returns -1 if an error occurred (e.g. no previous call to
- census_trace_scan_start()), 0 if there is no more trace data (and
- trace_record will not be modified) or 1 otherwise.
-*/
-CENSUSAPI int census_get_trace_record(census_trace_record *trace_record);
-
-/** End a scan previously started by census_trace_scan_start() */
-CENSUSAPI void census_trace_scan_end();
-
-/** Core stats collection API's. The following concepts are used:
- * Resource: Users record measurements for a single resource. Examples
- include RPC latency, CPU seconds consumed, and bytes transmitted.
- * Aggregation: An aggregation of a set of measurements. Census supports the
- following aggregation types:
- * Distribution - statistical distribution information, used for
- recording average, standard deviation etc. Can include a histogram.
- * Interval - a count of events that happen in a rolling time window.
- * View: A view is a combination of a Resource, a set of tag keys and an
- Aggregation. When a measurement for a Resource matches the View tags, it is
- recorded (for each unique set of tag values) using the Aggregation type.
- Each resource can have an arbitrary number of views by which it will be
- broken down.
-
- Census uses protos to define each of the above, and output results. This
- ensures unification across the different language and runtime
- implementations. The proto definitions can be found in src/proto/census.
-*/
-
-/** Define a new resource. `resource_pb` should contain an encoded Resource
- protobuf, `resource_pb_size` being the size of the buffer. Returns a -ve
- value on error, or a positive (>= 0) resource id (for use in
- census_delete_resource() and census_record_values()). In order to be valid, a
- resource must have a name, and at least one numerator in its unit type. The
- resource name must be unique, and an error will be returned if it is not. */
-CENSUSAPI int32_t census_define_resource(const uint8_t *resource_pb,
- size_t resource_pb_size);
-
-/** Delete a resource created by census_define_resource(). */
-CENSUSAPI void census_delete_resource(int32_t resource_id);
-
-/** Determine the id of a resource, given its name. returns -1 if the resource
- does not exist. */
-CENSUSAPI int32_t census_resource_id(const char *name);
-
-/** A single value to be recorded comprises two parts: an ID for the particular
- * resource and the value to be recorded against it. */
-typedef struct {
- int32_t resource_id;
- double value;
-} census_value;
-
-/** Record new usage values against the given context. */
-CENSUSAPI void census_record_values(census_context *context,
- census_value *values, size_t nvalues);
-
#ifdef __cplusplus
}
#endif
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 95b1447..758aaf5 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -316,6 +316,43 @@
*/
GRPCAPI void grpc_server_credentials_release(grpc_server_credentials *creds);
+/** Server certificate config object holds the server's public certificates and
+ associated private keys, as well as any CA certificates needed for client
+ certificate validation (if applicable). Create using
+ grpc_ssl_server_certificate_config_create(). */
+typedef struct grpc_ssl_server_certificate_config
+ grpc_ssl_server_certificate_config;
+
+/** Creates a grpc_ssl_server_certificate_config object.
+ - pem_roots_cert is the NULL-terminated string containing the PEM encoding of
+ the client root certificates. This parameter may be NULL if the server does
+ not want the client to be authenticated with SSL.
+ - pem_key_cert_pairs is an array private key / certificate chains of the
+ server. This parameter cannot be NULL.
+ - num_key_cert_pairs indicates the number of items in the private_key_files
+ and cert_chain_files parameters. It must be at least 1.
+ - It is the caller's responsibility to free this object via
+ grpc_ssl_server_certificate_config_destroy(). */
+GRPCAPI grpc_ssl_server_certificate_config *
+grpc_ssl_server_certificate_config_create(
+ const char *pem_root_certs,
+ const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs);
+
+/** Destroys a grpc_ssl_server_certificate_config object. */
+GRPCAPI void grpc_ssl_server_certificate_config_destroy(
+ grpc_ssl_server_certificate_config *config);
+
+/** Callback to retrieve updated SSL server certificates, private keys, and
+ trusted CAs (for client authentication).
+ - user_data parameter, if not NULL, contains opaque data to be used by the
+ callback.
+ - Use grpc_ssl_server_certificate_config_create to create the config.
+ - The caller assumes ownership of the config. */
+typedef grpc_ssl_certificate_config_reload_status (
+ *grpc_ssl_server_certificate_config_callback)(
+ void *user_data, grpc_ssl_server_certificate_config **config);
+
/** Deprecated in favor of grpc_ssl_server_credentials_create_ex.
Creates an SSL server_credentials object.
- pem_roots_cert is the NULL-terminated string containing the PEM encoding of
@@ -332,7 +369,8 @@
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, int force_client_auth, void *reserved);
-/** Same as grpc_ssl_server_credentials_create method except uses
+/** Deprecated in favor of grpc_ssl_server_credentials_create_with_options.
+ Same as grpc_ssl_server_credentials_create method except uses
grpc_ssl_client_certificate_request_type enum to support more ways to
authenticate client cerificates.*/
GRPCAPI grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
@@ -341,6 +379,40 @@
grpc_ssl_client_certificate_request_type client_certificate_request,
void *reserved);
+typedef struct grpc_ssl_server_credentials_options
+ grpc_ssl_server_credentials_options;
+
+/** Creates an options object using a certificate config. Use this method when
+ the certificates and keys of the SSL server will not change during the
+ server's lifetime.
+ - Takes ownership of the certificate_config parameter. */
+GRPCAPI grpc_ssl_server_credentials_options *
+grpc_ssl_server_credentials_create_options_using_config(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config *certificate_config);
+
+/** Creates an options object using a certificate config fetcher. Use this
+ method to reload the certificates and keys of the SSL server without
+ interrupting the operation of the server. Initial certificate config will be
+ fetched during server initialization.
+ - user_data parameter, if not NULL, contains opaque data which will be passed
+ to the fetcher (see definition of
+ grpc_ssl_server_certificate_config_callback). */
+GRPCAPI grpc_ssl_server_credentials_options *
+grpc_ssl_server_credentials_create_options_using_config_fetcher(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config_callback cb, void *user_data);
+
+/** Destroys a grpc_ssl_server_credentials_options object. */
+GRPCAPI void grpc_ssl_server_credentials_options_destroy(
+ grpc_ssl_server_credentials_options *options);
+
+/** Creates an SSL server_credentials object using the provided options struct.
+ - Takes ownership of the options parameter. */
+GRPCAPI grpc_server_credentials *
+grpc_ssl_server_credentials_create_with_options(
+ grpc_ssl_server_credentials_options *options);
+
/** --- Server-side secure ports. --- */
/** Add a HTTP2 over an encrypted link over tcp listener.
diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h
index fde300d..60e167e 100644
--- a/include/grpc/grpc_security_constants.h
+++ b/include/grpc/grpc_security_constants.h
@@ -48,6 +48,13 @@
GRPC_SSL_ROOTS_OVERRIDE_FAIL
} grpc_ssl_roots_override_result;
+/** Callback results for dynamically loading a SSL certificate config. */
+typedef enum {
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED,
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW,
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL
+} grpc_ssl_certificate_config_reload_status;
+
typedef enum {
/** Server does not request client certificate. A client can present a self
signed or signed certificates if it wishes to do so and they would be
diff --git a/include/grpc/impl/codegen/connectivity_state.h b/include/grpc/impl/codegen/connectivity_state.h
index 545b4fd..b70dbef 100644
--- a/include/grpc/impl/codegen/connectivity_state.h
+++ b/include/grpc/impl/codegen/connectivity_state.h
@@ -25,8 +25,6 @@
/** Connectivity state of a channel. */
typedef enum {
- /** channel has just been initialized */
- GRPC_CHANNEL_INIT = -1,
/** channel is idle */
GRPC_CHANNEL_IDLE,
/** channel is connecting */
diff --git a/package.xml b/package.xml
index d08b803..9dee62f 100644
--- a/package.xml
+++ b/package.xml
@@ -242,6 +242,7 @@
<file baseinstalldir="/" name="src/core/tsi/transport_security_adapter.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_interface.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
@@ -395,28 +396,11 @@
<file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_plugin.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/aggregation.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/base_resources.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/census_rpc_stats.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/gen/trace_context.pb.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/intrusive_hash_map.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/intrusive_hash_map_internal.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/resource.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/rpc_metric_id.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/trace_context.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/trace_label.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/trace_propagation.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/trace_status.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/trace_string.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/tracing.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h" role="src" />
@@ -615,6 +599,7 @@
<file baseinstalldir="/" name="src/core/tsi/transport_security_adapter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/backup_poller.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/channel_connectivity.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.cc" role="src" />
@@ -654,6 +639,7 @@
<file baseinstalldir="/" name="third_party/nanopb/pb_encode.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc" role="src" />
@@ -663,21 +649,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/base_resources.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/context.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/gen/trace_context.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_context.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/grpc_plugin.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/initialize.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/intrusive_hash_map.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/mlog.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/operation.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/placeholders.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/resource.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/trace_context.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/census/tracing.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc" role="src" />
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index c2db8ef..253280b 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -140,7 +140,6 @@
printer->Print(vars, "namespace grpc {\n");
printer->Print(vars, "class CompletionQueue;\n");
printer->Print(vars, "class Channel;\n");
- printer->Print(vars, "class RpcService;\n");
printer->Print(vars, "class ServerCompletionQueue;\n");
printer->Print(vars, "class ServerContext;\n");
printer->Print(vars, "} // namespace grpc\n\n");
@@ -324,7 +323,8 @@
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
- "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
+ "virtual ::grpc::ClientReaderInterface< $Response$>* "
+ "$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request) = 0;\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
@@ -546,7 +546,8 @@
const grpc_generator::Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
- printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
+ printer->Print(*vars,
+ "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
}
void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
@@ -718,7 +719,7 @@
printer->Print(*vars,
"WithStreamedUnaryMethod_$Method$() {\n"
" ::grpc::Service::MarkMethodStreamed($Idx$,\n"
- " new ::grpc::StreamedUnaryHandler< $Request$, "
+ " new ::grpc::internal::StreamedUnaryHandler< $Request$, "
"$Response$>(std::bind"
"(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
"Streamed$Method$, this, std::placeholders::_1, "
@@ -766,15 +767,16 @@
"{}\n");
printer->Print(" public:\n");
printer->Indent();
- printer->Print(*vars,
- "WithSplitStreamingMethod_$Method$() {\n"
- " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
- " new ::grpc::SplitServerStreamingHandler< $Request$, "
- "$Response$>(std::bind"
- "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
- "Streamed$Method$, this, std::placeholders::_1, "
- "std::placeholders::_2)));\n"
- "}\n");
+ printer->Print(
+ *vars,
+ "WithSplitStreamingMethod_$Method$() {\n"
+ " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
+ " new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
+ "$Response$>(std::bind"
+ "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
+ "Streamed$Method$, this, std::placeholders::_1, "
+ "std::placeholders::_2)));\n"
+ "}\n");
printer->Print(*vars,
"~WithSplitStreamingMethod_$Method$() override {\n"
" BaseClassMustBeDerivedFromService(this);\n"
@@ -914,7 +916,8 @@
" {\n public:\n");
printer->Indent();
printer->Print(
- "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
+ "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
+ "channel);\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
}
@@ -1185,10 +1188,9 @@
"::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response) {\n");
printer->Print(*vars,
- " return ::grpc::BlockingUnaryCall(channel_.get(), "
- "rpcmethod_$Method$_, "
- "context, request, response);\n"
- "}\n\n");
+ " return ::grpc::internal::BlockingUnaryCall"
+ "(channel_.get(), rpcmethod_$Method$_, "
+ "context, request, response);\n}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
@@ -1198,25 +1200,27 @@
"ClientContext* context, "
"const $Request$& request, "
"::grpc::CompletionQueue* cq) {\n");
- printer->Print(*vars,
- " return "
- "::grpc::ClientAsyncResponseReader< $Response$>::Create("
- "channel_.get(), cq, "
- "rpcmethod_$Method$_, "
- "context, request, $AsyncStart$);\n"
- "}\n\n");
+ printer->Print(
+ *vars,
+ " return "
+ "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
+ "::Create(channel_.get(), cq, "
+ "rpcmethod_$Method$_, "
+ "context, request, $AsyncStart$);\n"
+ "}\n\n");
}
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::ClientWriter< $Request$>* "
"$ns$$Service$::Stub::$Method$Raw("
"::grpc::ClientContext* context, $Response$* response) {\n");
- printer->Print(*vars,
- " return new ::grpc::ClientWriter< $Request$>("
- "channel_.get(), "
- "rpcmethod_$Method$_, "
- "context, response);\n"
- "}\n\n");
+ printer->Print(
+ *vars,
+ " return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
+ "channel_.get(), "
+ "rpcmethod_$Method$_, "
+ "context, response);\n"
+ "}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
@@ -1227,12 +1231,13 @@
"$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
"::grpc::ClientContext* context, $Response$* response, "
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
- printer->Print(*vars,
- " return ::grpc::ClientAsyncWriter< $Request$>::Create("
- "channel_.get(), cq, "
- "rpcmethod_$Method$_, "
- "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
- "}\n\n");
+ printer->Print(
+ *vars,
+ " return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
+ "::Create(channel_.get(), cq, "
+ "rpcmethod_$Method$_, "
+ "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
+ "}\n\n");
}
} else if (ServerOnlyStreaming(method)) {
printer->Print(
@@ -1240,12 +1245,13 @@
"::grpc::ClientReader< $Response$>* "
"$ns$$Service$::Stub::$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request) {\n");
- printer->Print(*vars,
- " return new ::grpc::ClientReader< $Response$>("
- "channel_.get(), "
- "rpcmethod_$Method$_, "
- "context, request);\n"
- "}\n\n");
+ printer->Print(
+ *vars,
+ " return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
+ "channel_.get(), "
+ "rpcmethod_$Method$_, "
+ "context, request);\n"
+ "}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
@@ -1257,12 +1263,13 @@
"$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request, "
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
- printer->Print(*vars,
- " return ::grpc::ClientAsyncReader< $Response$>::Create("
- "channel_.get(), cq, "
- "rpcmethod_$Method$_, "
- "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
- "}\n\n");
+ printer->Print(
+ *vars,
+ " return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
+ "::Create(channel_.get(), cq, "
+ "rpcmethod_$Method$_, "
+ "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
+ "}\n\n");
}
} else if (method->BidiStreaming()) {
printer->Print(
@@ -1270,8 +1277,8 @@
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
"$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
printer->Print(*vars,
- " return new ::grpc::ClientReaderWriter< "
- "$Request$, $Response$>("
+ " return ::grpc::internal::ClientReaderWriterFactory< "
+ "$Request$, $Response$>::Create("
"channel_.get(), "
"rpcmethod_$Method$_, "
"context);\n"
@@ -1286,14 +1293,14 @@
"$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
"ClientContext* context, "
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
- printer->Print(
- *vars,
- " return "
- "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>::Create("
- "channel_.get(), cq, "
- "rpcmethod_$Method$_, "
- "context, $AsyncStart$$AsyncCreateArgs$);\n"
- "}\n\n");
+ printer->Print(*vars,
+ " return "
+ "::grpc::internal::ClientAsyncReaderWriterFactory< "
+ "$Request$, $Response$>::Create("
+ "channel_.get(), cq, "
+ "rpcmethod_$Method$_, "
+ "context, $AsyncStart$$AsyncCreateArgs$);\n"
+ "}\n\n");
}
}
}
@@ -1404,7 +1411,7 @@
printer->Print(*vars,
", rpcmethod_$Method$_("
"$prefix$$Service$_method_names[$Idx$], "
- "::grpc::RpcMethod::$StreamingType$, "
+ "::grpc::internal::RpcMethod::$StreamingType$, "
"channel"
")\n");
}
@@ -1427,38 +1434,38 @@
if (method->NoStreaming()) {
printer->Print(
*vars,
- "AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
- " ::grpc::RpcMethod::NORMAL_RPC,\n"
- " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
+ " ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
+ " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
"$Request$, "
"$Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
} else if (ClientOnlyStreaming(method.get())) {
printer->Print(
*vars,
- "AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
- " ::grpc::RpcMethod::CLIENT_STREAMING,\n"
- " new ::grpc::ClientStreamingHandler< "
+ " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
+ " new ::grpc::internal::ClientStreamingHandler< "
"$ns$$Service$::Service, $Request$, $Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
} else if (ServerOnlyStreaming(method.get())) {
printer->Print(
*vars,
- "AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
- " ::grpc::RpcMethod::SERVER_STREAMING,\n"
- " new ::grpc::ServerStreamingHandler< "
+ " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
+ " new ::grpc::internal::ServerStreamingHandler< "
"$ns$$Service$::Service, $Request$, $Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
} else if (method->BidiStreaming()) {
printer->Print(
*vars,
- "AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
- " ::grpc::RpcMethod::BIDI_STREAMING,\n"
- " new ::grpc::BidiStreamingHandler< "
+ " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
+ " new ::grpc::internal::BidiStreamingHandler< "
"$ns$$Service$::Service, $Request$, $Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
}
diff --git a/src/core/ext/census/README.md b/src/core/ext/census/README.md
deleted file mode 100644
index a9826fe..0000000
--- a/src/core/ext/census/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-<!---
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
--->
-
-# Census - a resource measurement and tracing system
-
-This directory contains code for Census, which will ultimately provide the
-following features for any gRPC-using system:
-* A [dapper](http://research.google.com/pubs/pub36356.html)-like tracing
- system, enabling tracing across a distributed infrastructure.
-* RPC statistics and measurements for key metrics, such as latency, bytes
- transferred, number of errors etc.
-* Resource measurement framework which can be used for measuring custom
- metrics. Through the use of [tags](#Tags), these can be broken down across
- the entire distributed stack.
-* Easy integration of the above with
- [Google Cloud Trace](https://cloud.google.com/tools/cloud-trace) and
- [Google Cloud Monitoring](https://cloud.google.com/monitoring/).
-
-## Concepts
-
-### Context
-
-### Operations
-
-### Tags
-
-### Metrics
-
-## API
-
-### Internal/RPC API
-
-### External/Client API
-
-### RPC API
-
-## Files in this directory
-
-Note that files and functions in this directory can be split into two
-categories:
-* Files that define core census library functions. Functions etc. in these
- files are named census\_\*, and constitute the core census library
- functionality. At some time in the future, these will become a standalone
- library.
-* Files that define functions etc. that provide a convenient interface between
- grpc and the core census functionality. These files are all named
- grpc\_\*.{c,h}, and define function names beginning with grpc\_census\_\*.
-
diff --git a/src/core/ext/census/aggregation.h b/src/core/ext/census/aggregation.h
deleted file mode 100644
index 1ba7953..0000000
--- a/src/core/ext/census/aggregation.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <stddef.h>
-
-#ifndef GRPC_CORE_EXT_CENSUS_AGGREGATION_H
-#define GRPC_CORE_EXT_CENSUS_AGGREGATION_H
-
-/** Structure used to describe an aggregation type. */
-struct census_aggregation_ops {
- /* Create a new aggregation. The pointer returned can be used in future calls
- to clone(), free(), record(), data() and reset(). */
- void *(*create)(const void *create_arg);
- /* Make a copy of an aggregation created by create() */
- void *(*clone)(const void *aggregation);
- /* Destroy an aggregation created by create() */
- void (*free)(void *aggregation);
- /* Record a new value against aggregation. */
- void (*record)(void *aggregation, double value);
- /* Return current aggregation data. The caller must cast this object into
- the correct type for the aggregation result. The object returned can be
- freed by using free_data(). */
- void *(*data)(const void *aggregation);
- /* free data returned by data() */
- void (*free_data)(void *data);
- /* Reset an aggregation to default (zero) values. */
- void (*reset)(void *aggregation);
- /* Merge 'from' aggregation into 'to'. Both aggregations must be compatible */
- void (*merge)(void *to, const void *from);
- /* Fill buffer with printable string version of aggregation contents. For
- debugging only. Returns the number of bytes added to buffer (a value == n
- implies the buffer was of insufficient size). */
- size_t (*print)(const void *aggregation, char *buffer, size_t n);
-};
-
-#endif /* GRPC_CORE_EXT_CENSUS_AGGREGATION_H */
diff --git a/src/core/ext/census/base_resources.cc b/src/core/ext/census/base_resources.cc
deleted file mode 100644
index 3697c6f..0000000
--- a/src/core/ext/census/base_resources.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/base_resources.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/census.h>
-#include <grpc/support/log.h>
-
-#include "src/core/ext/census/resource.h"
-
-// Add base RPC resource definitions for use by RPC runtime.
-//
-// TODO(aveitch): All of these are currently hardwired definitions encoded in
-// the code in this file. These should be converted to use an external
-// configuration mechanism, in which these resources are defined in a text
-// file, which is compiled to .pb format and read by still-to-be-written
-// configuration functions.
-
-// Define all base resources. This should be called by census initialization.
-void define_base_resources() {
- google_census_Resource_BasicUnit numerator =
- google_census_Resource_BasicUnit_SECS;
- resource r = {(char *)"client_rpc_latency", // name
- (char *)"Client RPC latency in seconds", // description
- 0, // prefix
- 1, // n_numerators
- &numerator, // numerators
- 0, // n_denominators
- NULL}; // denominators
- define_resource(&r);
- r = {(char *)"server_rpc_latency", // name
- (char *)"Server RPC latency in seconds", // description
- 0, // prefix
- 1, // n_numerators
- &numerator, // numerators
- 0, // n_denominators
- NULL}; // denominators
- define_resource(&r);
-}
diff --git a/src/core/ext/census/base_resources.h b/src/core/ext/census/base_resources.h
deleted file mode 100644
index d24923b..0000000
--- a/src/core/ext/census/base_resources.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H
-#define GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Define all base resources. This should be called by census initialization. */
-void define_base_resources();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H */
diff --git a/src/core/ext/census/census_init.cc b/src/core/ext/census/census_init.cc
deleted file mode 100644
index d7f719f..0000000
--- a/src/core/ext/census/census_init.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/census_interface.h"
-
-#include <grpc/support/log.h>
-#include "src/core/ext/census/census_rpc_stats.h"
-#include "src/core/ext/census/census_tracing.h"
-
-void census_init(void) {
- census_tracing_init();
- census_stats_store_init();
-}
-
-void census_shutdown(void) {
- census_stats_store_shutdown();
- census_tracing_shutdown();
-}
diff --git a/src/core/ext/census/census_interface.h b/src/core/ext/census/census_interface.h
deleted file mode 100644
index 113c2b1..0000000
--- a/src/core/ext/census/census_interface.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_CENSUS_INTERFACE_H
-#define GRPC_CORE_EXT_CENSUS_CENSUS_INTERFACE_H
-
-#include <grpc/support/port_platform.h>
-
-/* Maximum length of an individual census trace annotation. */
-#define CENSUS_MAX_ANNOTATION_LENGTH 200
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Structure of a census op id. Define as structure because 64bit integer is not
- available on every platform for C89. */
-typedef struct census_op_id {
- uint32_t upper;
- uint32_t lower;
-} census_op_id;
-
-typedef struct census_rpc_stats census_rpc_stats;
-
-/* Initializes Census library. No-op if Census is already initialized. */
-void census_init(void);
-
-/* Shutdown Census Library. */
-void census_shutdown(void);
-
-/* Annotates grpc method name on a census_op_id. The method name has the format
- of <full quantified rpc service name>/<rpc function name>. Returns 0 iff
- op_id and method_name are all valid. op_id is valid after its creation and
- before calling census_tracing_end_op().
-
- TODO(hongyu): Figure out valid characters set for service name and command
- name and document requirements here.*/
-int census_add_method_tag(census_op_id op_id, const char *method_name);
-
-/* Annotates tracing information to a specific op_id.
- Up to CENSUS_MAX_ANNOTATION_LENGTH bytes are recorded. */
-void census_tracing_print(census_op_id op_id, const char *annotation);
-
-/* Starts tracing for an RPC. Returns a locally unique census_op_id */
-census_op_id census_tracing_start_op(void);
-
-/* Ends tracing. Calling this function will invalidate the input op_id. */
-void census_tracing_end_op(census_op_id op_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_CENSUS_INTERFACE_H */
diff --git a/src/core/ext/census/census_log.cc b/src/core/ext/census/census_log.cc
deleted file mode 100644
index 100047f..0000000
--- a/src/core/ext/census/census_log.cc
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/* Available log space is divided up in blocks of
- CENSUS_LOG_2_MAX_RECORD_SIZE bytes. A block can be in one of the
- following three data structures:
- - Free blocks (free_block_list)
- - Blocks with unread data (dirty_block_list)
- - Blocks currently attached to cores (core_local_blocks[])
-
- census_log_start_write() moves a block from core_local_blocks[] to the
- end of dirty_block_list when block:
- - is out-of-space OR
- - has an incomplete record (an incomplete record occurs when a thread calls
- census_log_start_write() and is context-switched before calling
- census_log_end_write()
- So, blocks in dirty_block_list are ordered, from oldest to newest, by time
- when block is detached from the core.
-
- census_log_read_next() first iterates over dirty_block_list and then
- core_local_blocks[]. It moves completely read blocks from dirty_block_list
- to free_block_list. Blocks in core_local_blocks[] are not freed, even when
- completely read.
-
- If log is configured to discard old records and free_block_list is empty,
- census_log_start_write() iterates over dirty_block_list to allocate a
- new block. It moves the oldest available block (no pending read/write) to
- core_local_blocks[].
-
- core_local_block_struct is used to implement a map from core id to the block
- associated with that core. This mapping is advisory. It is possible that the
- block returned by this mapping is no longer associated with that core. This
- mapping is updated, lazily, by census_log_start_write().
-
- Locking in block struct:
-
- Exclusive g_log.lock must be held before calling any functions operatong on
- block structs except census_log_start_write() and
- census_log_end_write().
-
- Writes to a block are serialized via writer_lock.
- census_log_start_write() acquires this lock and
- census_log_end_write() releases it. On failure to acquire the lock,
- writer allocates a new block for the current core and updates
- core_local_block accordingly.
-
- Simultaneous read and write access is allowed. Reader can safely read up to
- committed bytes (bytes_committed).
-
- reader_lock protects the block, currently being read, from getting recycled.
- start_read() acquires reader_lock and end_read() releases the lock.
-
- Read/write access to a block is disabled via try_disable_access(). It returns
- with both writer_lock and reader_lock held. These locks are subsequently
- released by enable_access() to enable access to the block.
-
- A note on naming: Most function/struct names are prepended by cl_
- (shorthand for census_log). Further, functions that manipulate structures
- include the name of the structure, which will be passed as the first
- argument. E.g. cl_block_initialize() will initialize a cl_block.
-*/
-#include "src/core/ext/census/census_log.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/atm.h>
-#include <grpc/support/cpu.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/useful.h>
-#include <string.h>
-
-/* End of platform specific code */
-
-typedef struct census_log_block_list_struct {
- struct census_log_block_list_struct *next;
- struct census_log_block_list_struct *prev;
- struct census_log_block *block;
-} cl_block_list_struct;
-
-typedef struct census_log_block {
- /* Pointer to underlying buffer */
- char *buffer;
- gpr_atm writer_lock;
- gpr_atm reader_lock;
- /* Keeps completely written bytes. Declared atomic because accessed
- simultaneously by reader and writer. */
- gpr_atm bytes_committed;
- /* Bytes already read */
- int32_t bytes_read;
- /* Links for list */
- cl_block_list_struct link;
-/* We want this structure to be cacheline aligned. We assume the following
- sizes for the various parts on 32/64bit systems:
- type 32b size 64b size
- char* 4 8
- 3x gpr_atm 12 24
- int32_t 4 8 (assumes padding)
- cl_block_list_struct 12 24
- TOTAL 32 64
-
- Depending on the size of our cacheline and the architecture, we
- selectively add char buffering to this structure. The size is checked
- via assert in census_log_initialize(). */
-#if defined(GPR_ARCH_64)
-#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 64)
-#else
-#if defined(GPR_ARCH_32)
-#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 32)
-#else
-#error "Unknown architecture"
-#endif
-#endif
-#if CL_BLOCK_PAD_SIZE > 0
- char padding[CL_BLOCK_PAD_SIZE];
-#endif
-} cl_block;
-
-/* A list of cl_blocks, doubly-linked through cl_block::link. */
-typedef struct census_log_block_list {
- int32_t count; /* Number of items in list. */
- cl_block_list_struct ht; /* head/tail of linked list. */
-} cl_block_list;
-
-/* Cacheline aligned block pointers to avoid false sharing. Block pointer must
- be initialized via set_block(), before calling other functions */
-typedef struct census_log_core_local_block {
- gpr_atm block;
-/* Ensure cachline alignment: we assume sizeof(gpr_atm) == 4 or 8 */
-#if defined(GPR_ARCH_64)
-#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 8)
-#else
-#if defined(GPR_ARCH_32)
-#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 4)
-#else
-#error "Unknown architecture"
-#endif
-#endif
-#if CL_CORE_LOCAL_BLOCK_PAD_SIZE > 0
- char padding[CL_CORE_LOCAL_BLOCK_PAD_SIZE];
-#endif
-} cl_core_local_block;
-
-struct census_log {
- int discard_old_records;
- /* Number of cores (aka hardware-contexts) */
- unsigned num_cores;
- /* number of CENSUS_LOG_2_MAX_RECORD_SIZE blocks in log */
- int32_t num_blocks;
- cl_block *blocks; /* Block metadata. */
- cl_core_local_block *core_local_blocks; /* Keeps core to block mappings. */
- gpr_mu lock;
- int initialized; /* has log been initialized? */
- /* Keeps the state of the reader iterator. A value of 0 indicates that
- iterator has reached the end. census_log_init_reader() resets the
- value to num_core to restart iteration. */
- uint32_t read_iterator_state;
- /* Points to the block being read. If non-NULL, the block is locked for
- reading (block_being_read_->reader_lock is held). */
- cl_block *block_being_read;
- /* A non-zero value indicates that log is full. */
- gpr_atm is_full;
- char *buffer;
- cl_block_list free_block_list;
- cl_block_list dirty_block_list;
- gpr_atm out_of_space_count;
-};
-
-/* Single internal log */
-static struct census_log g_log;
-
-/* Functions that operate on an atomic memory location used as a lock */
-
-/* Returns non-zero if lock is acquired */
-static int cl_try_lock(gpr_atm *lock) { return gpr_atm_acq_cas(lock, 0, 1); }
-
-static void cl_unlock(gpr_atm *lock) { gpr_atm_rel_store(lock, 0); }
-
-/* Functions that operate on cl_core_local_block's */
-
-static void cl_core_local_block_set_block(cl_core_local_block *clb,
- cl_block *block) {
- gpr_atm_rel_store(&clb->block, (gpr_atm)block);
-}
-
-static cl_block *cl_core_local_block_get_block(cl_core_local_block *clb) {
- return (cl_block *)gpr_atm_acq_load(&clb->block);
-}
-
-/* Functions that operate on cl_block_list_struct's */
-
-static void cl_block_list_struct_initialize(cl_block_list_struct *bls,
- cl_block *block) {
- bls->next = bls->prev = bls;
- bls->block = block;
-}
-
-/* Functions that operate on cl_block_list's */
-
-static void cl_block_list_initialize(cl_block_list *list) {
- list->count = 0;
- cl_block_list_struct_initialize(&list->ht, NULL);
-}
-
-/* Returns head of *this, or NULL if empty. */
-static cl_block *cl_block_list_head(cl_block_list *list) {
- return list->ht.next->block;
-}
-
-/* Insert element *e after *pos. */
-static void cl_block_list_insert(cl_block_list *list, cl_block_list_struct *pos,
- cl_block_list_struct *e) {
- list->count++;
- e->next = pos->next;
- e->prev = pos;
- e->next->prev = e;
- e->prev->next = e;
-}
-
-/* Insert block at the head of the list */
-static void cl_block_list_insert_at_head(cl_block_list *list, cl_block *block) {
- cl_block_list_insert(list, &list->ht, &block->link);
-}
-
-/* Insert block at the tail of the list */
-static void cl_block_list_insert_at_tail(cl_block_list *list, cl_block *block) {
- cl_block_list_insert(list, list->ht.prev, &block->link);
-}
-
-/* Removes block *b. Requires *b be in the list. */
-static void cl_block_list_remove(cl_block_list *list, cl_block *b) {
- list->count--;
- b->link.next->prev = b->link.prev;
- b->link.prev->next = b->link.next;
-}
-
-/* Functions that operate on cl_block's */
-
-static void cl_block_initialize(cl_block *block, char *buffer) {
- block->buffer = buffer;
- gpr_atm_rel_store(&block->writer_lock, 0);
- gpr_atm_rel_store(&block->reader_lock, 0);
- gpr_atm_rel_store(&block->bytes_committed, 0);
- block->bytes_read = 0;
- cl_block_list_struct_initialize(&block->link, block);
-}
-
-/* Guards against exposing partially written buffer to the reader. */
-static void cl_block_set_bytes_committed(cl_block *block,
- int32_t bytes_committed) {
- gpr_atm_rel_store(&block->bytes_committed, bytes_committed);
-}
-
-static int32_t cl_block_get_bytes_committed(cl_block *block) {
- return gpr_atm_acq_load(&block->bytes_committed);
-}
-
-/* Tries to disable future read/write access to this block. Succeeds if:
- - no in-progress write AND
- - no in-progress read AND
- - 'discard_data' set to true OR no unread data
- On success, clears the block state and returns with writer_lock_ and
- reader_lock_ held. These locks are released by a subsequent
- cl_block_access_enable() call. */
-static int cl_block_try_disable_access(cl_block *block, int discard_data) {
- if (!cl_try_lock(&block->writer_lock)) {
- return 0;
- }
- if (!cl_try_lock(&block->reader_lock)) {
- cl_unlock(&block->writer_lock);
- return 0;
- }
- if (!discard_data &&
- (block->bytes_read != cl_block_get_bytes_committed(block))) {
- cl_unlock(&block->reader_lock);
- cl_unlock(&block->writer_lock);
- return 0;
- }
- cl_block_set_bytes_committed(block, 0);
- block->bytes_read = 0;
- return 1;
-}
-
-static void cl_block_enable_access(cl_block *block) {
- cl_unlock(&block->reader_lock);
- cl_unlock(&block->writer_lock);
-}
-
-/* Returns with writer_lock held. */
-static void *cl_block_start_write(cl_block *block, size_t size) {
- int32_t bytes_committed;
- if (!cl_try_lock(&block->writer_lock)) {
- return NULL;
- }
- bytes_committed = cl_block_get_bytes_committed(block);
- if (bytes_committed + size > CENSUS_LOG_MAX_RECORD_SIZE) {
- cl_unlock(&block->writer_lock);
- return NULL;
- }
- return block->buffer + bytes_committed;
-}
-
-/* Releases writer_lock and increments committed bytes by 'bytes_written'.
- 'bytes_written' must be <= 'size' specified in the corresponding
- StartWrite() call. This function is thread-safe. */
-static void cl_block_end_write(cl_block *block, size_t bytes_written) {
- cl_block_set_bytes_committed(
- block, cl_block_get_bytes_committed(block) + bytes_written);
- cl_unlock(&block->writer_lock);
-}
-
-/* Returns a pointer to the first unread byte in buffer. The number of bytes
- available are returned in 'bytes_available'. Acquires reader lock that is
- released by a subsequent cl_block_end_read() call. Returns NULL if:
- - read in progress
- - no data available */
-static void *cl_block_start_read(cl_block *block, size_t *bytes_available) {
- void *record;
- if (!cl_try_lock(&block->reader_lock)) {
- return NULL;
- }
- /* bytes_committed may change from under us. Use bytes_available to update
- bytes_read below. */
- *bytes_available = cl_block_get_bytes_committed(block) - block->bytes_read;
- if (*bytes_available == 0) {
- cl_unlock(&block->reader_lock);
- return NULL;
- }
- record = block->buffer + block->bytes_read;
- block->bytes_read += *bytes_available;
- return record;
-}
-
-static void cl_block_end_read(cl_block *block) {
- cl_unlock(&block->reader_lock);
-}
-
-/* Internal functions operating on g_log */
-
-/* Allocates a new free block (or recycles an available dirty block if log is
- configured to discard old records). Returns NULL if out-of-space. */
-static cl_block *cl_allocate_block(void) {
- cl_block *block = cl_block_list_head(&g_log.free_block_list);
- if (block != NULL) {
- cl_block_list_remove(&g_log.free_block_list, block);
- return block;
- }
- if (!g_log.discard_old_records) {
- /* No free block and log is configured to keep old records. */
- return NULL;
- }
- /* Recycle dirty block. Start from the oldest. */
- for (block = cl_block_list_head(&g_log.dirty_block_list); block != NULL;
- block = block->link.next->block) {
- if (cl_block_try_disable_access(block, 1 /* discard data */)) {
- cl_block_list_remove(&g_log.dirty_block_list, block);
- return block;
- }
- }
- return NULL;
-}
-
-/* Allocates a new block and updates core id => block mapping. 'old_block'
- points to the block that the caller thinks is attached to
- 'core_id'. 'old_block' may be NULL. Returns non-zero if:
- - allocated a new block OR
- - 'core_id' => 'old_block' mapping changed (another thread allocated a
- block before lock was acquired). */
-static int cl_allocate_core_local_block(int32_t core_id, cl_block *old_block) {
- /* Now that we have the lock, check if core-local mapping has changed. */
- cl_core_local_block *core_local_block = &g_log.core_local_blocks[core_id];
- cl_block *block = cl_core_local_block_get_block(core_local_block);
- if ((block != NULL) && (block != old_block)) {
- return 1;
- }
- if (block != NULL) {
- cl_core_local_block_set_block(core_local_block, NULL);
- cl_block_list_insert_at_tail(&g_log.dirty_block_list, block);
- }
- block = cl_allocate_block();
- if (block == NULL) {
- gpr_atm_rel_store(&g_log.is_full, 1);
- return 0;
- }
- cl_core_local_block_set_block(core_local_block, block);
- cl_block_enable_access(block);
- return 1;
-}
-
-static cl_block *cl_get_block(void *record) {
- uintptr_t p = (uintptr_t)((char *)record - g_log.buffer);
- uintptr_t index = p >> CENSUS_LOG_2_MAX_RECORD_SIZE;
- return &g_log.blocks[index];
-}
-
-/* Gets the next block to read and tries to free 'prev' block (if not NULL).
- Returns NULL if reached the end. */
-static cl_block *cl_next_block_to_read(cl_block *prev) {
- cl_block *block = NULL;
- if (g_log.read_iterator_state == g_log.num_cores) {
- /* We are traversing dirty list; find the next dirty block. */
- if (prev != NULL) {
- /* Try to free the previous block if there is no unread data. This block
- may have unread data if previously incomplete record completed between
- read_next() calls. */
- block = prev->link.next->block;
- if (cl_block_try_disable_access(prev, 0 /* do not discard data */)) {
- cl_block_list_remove(&g_log.dirty_block_list, prev);
- cl_block_list_insert_at_head(&g_log.free_block_list, prev);
- gpr_atm_rel_store(&g_log.is_full, 0);
- }
- } else {
- block = cl_block_list_head(&g_log.dirty_block_list);
- }
- if (block != NULL) {
- return block;
- }
- /* We are done with the dirty list; moving on to core-local blocks. */
- }
- while (g_log.read_iterator_state > 0) {
- g_log.read_iterator_state--;
- block = cl_core_local_block_get_block(
- &g_log.core_local_blocks[g_log.read_iterator_state]);
- if (block != NULL) {
- return block;
- }
- }
- return NULL;
-}
-
-/* External functions: primary stats_log interface */
-void census_log_initialize(size_t size_in_mb, int discard_old_records) {
- int32_t ix;
- /* Check cacheline alignment. */
- GPR_ASSERT(sizeof(cl_block) % GPR_CACHELINE_SIZE == 0);
- GPR_ASSERT(sizeof(cl_core_local_block) % GPR_CACHELINE_SIZE == 0);
- GPR_ASSERT(!g_log.initialized);
- g_log.discard_old_records = discard_old_records;
- g_log.num_cores = gpr_cpu_num_cores();
- /* Ensure at least as many blocks as there are cores. */
- g_log.num_blocks = GPR_MAX(
- g_log.num_cores, (size_in_mb << 20) >> CENSUS_LOG_2_MAX_RECORD_SIZE);
- gpr_mu_init(&g_log.lock);
- g_log.read_iterator_state = 0;
- g_log.block_being_read = NULL;
- gpr_atm_rel_store(&g_log.is_full, 0);
- g_log.core_local_blocks = (cl_core_local_block *)gpr_malloc_aligned(
- g_log.num_cores * sizeof(cl_core_local_block), GPR_CACHELINE_SIZE_LOG);
- memset(g_log.core_local_blocks, 0,
- g_log.num_cores * sizeof(cl_core_local_block));
- g_log.blocks = (cl_block *)gpr_malloc_aligned(
- g_log.num_blocks * sizeof(cl_block), GPR_CACHELINE_SIZE_LOG);
- memset(g_log.blocks, 0, g_log.num_blocks * sizeof(cl_block));
- g_log.buffer = gpr_malloc(g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE);
- memset(g_log.buffer, 0, g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE);
- cl_block_list_initialize(&g_log.free_block_list);
- cl_block_list_initialize(&g_log.dirty_block_list);
- for (ix = 0; ix < g_log.num_blocks; ++ix) {
- cl_block *block = g_log.blocks + ix;
- cl_block_initialize(block,
- g_log.buffer + (CENSUS_LOG_MAX_RECORD_SIZE * ix));
- cl_block_try_disable_access(block, 1 /* discard data */);
- cl_block_list_insert_at_tail(&g_log.free_block_list, block);
- }
- gpr_atm_rel_store(&g_log.out_of_space_count, 0);
- g_log.initialized = 1;
-}
-
-void census_log_shutdown(void) {
- GPR_ASSERT(g_log.initialized);
- gpr_mu_destroy(&g_log.lock);
- gpr_free_aligned(g_log.core_local_blocks);
- g_log.core_local_blocks = NULL;
- gpr_free_aligned(g_log.blocks);
- g_log.blocks = NULL;
- gpr_free(g_log.buffer);
- g_log.buffer = NULL;
- g_log.initialized = 0;
-}
-
-void *census_log_start_write(size_t size) {
- /* Used to bound number of times block allocation is attempted. */
- int32_t attempts_remaining = g_log.num_blocks;
- /* TODO(aveitch): move this inside the do loop when current_cpu is fixed */
- int32_t core_id = gpr_cpu_current_cpu();
- GPR_ASSERT(g_log.initialized);
- if (size > CENSUS_LOG_MAX_RECORD_SIZE) {
- return NULL;
- }
- do {
- int allocated;
- void *record = NULL;
- cl_block *block =
- cl_core_local_block_get_block(&g_log.core_local_blocks[core_id]);
- if (block && (record = cl_block_start_write(block, size))) {
- return record;
- }
- /* Need to allocate a new block. We are here if:
- - No block associated with the core OR
- - Write in-progress on the block OR
- - block is out of space */
- if (gpr_atm_acq_load(&g_log.is_full)) {
- gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
- return NULL;
- }
- gpr_mu_lock(&g_log.lock);
- allocated = cl_allocate_core_local_block(core_id, block);
- gpr_mu_unlock(&g_log.lock);
- if (!allocated) {
- gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
- return NULL;
- }
- } while (attempts_remaining--);
- /* Give up. */
- gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
- return NULL;
-}
-
-void census_log_end_write(void *record, size_t bytes_written) {
- GPR_ASSERT(g_log.initialized);
- cl_block_end_write(cl_get_block(record), bytes_written);
-}
-
-void census_log_init_reader(void) {
- GPR_ASSERT(g_log.initialized);
- gpr_mu_lock(&g_log.lock);
- /* If a block is locked for reading unlock it. */
- if (g_log.block_being_read != NULL) {
- cl_block_end_read(g_log.block_being_read);
- g_log.block_being_read = NULL;
- }
- g_log.read_iterator_state = g_log.num_cores;
- gpr_mu_unlock(&g_log.lock);
-}
-
-const void *census_log_read_next(size_t *bytes_available) {
- GPR_ASSERT(g_log.initialized);
- gpr_mu_lock(&g_log.lock);
- if (g_log.block_being_read != NULL) {
- cl_block_end_read(g_log.block_being_read);
- }
- do {
- g_log.block_being_read = cl_next_block_to_read(g_log.block_being_read);
- if (g_log.block_being_read != NULL) {
- void *record =
- cl_block_start_read(g_log.block_being_read, bytes_available);
- if (record != NULL) {
- gpr_mu_unlock(&g_log.lock);
- return record;
- }
- }
- } while (g_log.block_being_read != NULL);
- gpr_mu_unlock(&g_log.lock);
- return NULL;
-}
-
-size_t census_log_remaining_space(void) {
- size_t space;
- GPR_ASSERT(g_log.initialized);
- gpr_mu_lock(&g_log.lock);
- if (g_log.discard_old_records) {
- /* Remaining space is not meaningful; just return the entire log space. */
- space = g_log.num_blocks << CENSUS_LOG_2_MAX_RECORD_SIZE;
- } else {
- space = g_log.free_block_list.count * CENSUS_LOG_MAX_RECORD_SIZE;
- }
- gpr_mu_unlock(&g_log.lock);
- return space;
-}
-
-int census_log_out_of_space_count(void) {
- GPR_ASSERT(g_log.initialized);
- return gpr_atm_acq_load(&g_log.out_of_space_count);
-}
diff --git a/src/core/ext/census/census_log.h b/src/core/ext/census/census_log.h
deleted file mode 100644
index ee336ae..0000000
--- a/src/core/ext/census/census_log.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_CENSUS_LOG_H
-#define GRPC_CORE_EXT_CENSUS_CENSUS_LOG_H
-
-#include <stddef.h>
-
-/* Maximum record size, in bytes. */
-#define CENSUS_LOG_2_MAX_RECORD_SIZE 14 /* 2^14 = 16KB */
-#define CENSUS_LOG_MAX_RECORD_SIZE (1 << CENSUS_LOG_2_MAX_RECORD_SIZE)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Initialize the statistics logging subsystem with the given log size. A log
- size of 0 will result in the smallest possible log for the platform
- (approximately CENSUS_LOG_MAX_RECORD_SIZE * gpr_cpu_num_cores()). If
- discard_old_records is non-zero, then new records will displace older ones
- when the log is full. This function must be called before any other
- census_log functions.
-*/
-void census_log_initialize(size_t size_in_mb, int discard_old_records);
-
-/* Shutdown the logging subsystem. Caller must ensure that:
- - no in progress or future call to any census_log functions
- - no incomplete records
-*/
-void census_log_shutdown(void);
-
-/* Allocates and returns a 'size' bytes record and marks it in use. A
- subsequent census_log_end_write() marks the record complete. The
- 'bytes_written' census_log_end_write() argument must be <=
- 'size'. Returns NULL if out-of-space AND:
- - log is configured to keep old records OR
- - all blocks are pinned by incomplete records.
-*/
-void *census_log_start_write(size_t size);
-
-void census_log_end_write(void *record, size_t bytes_written);
-
-/* census_log_read_next() iterates over blocks with data and for each block
- returns a pointer to the first unread byte. The number of bytes that can be
- read are returned in 'bytes_available'. Reader is expected to read all
- available data. Reading the data consumes it i.e. it cannot be read again.
- census_log_read_next() returns NULL if the end is reached i.e last block
- is read. census_log_init_reader() starts the iteration or aborts the
- current iteration.
-*/
-void census_log_init_reader(void);
-const void *census_log_read_next(size_t *bytes_available);
-
-/* Returns estimated remaining space across all blocks, in bytes. If log is
- configured to discard old records, returns total log space. Otherwise,
- returns space available in empty blocks (partially filled blocks are
- treated as full).
-*/
-size_t census_log_remaining_space(void);
-
-/* Returns the number of times grpc_stats_log_start_write() failed due to
- out-of-space. */
-int census_log_out_of_space_count(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_CENSUS_LOG_H */
diff --git a/src/core/ext/census/census_rpc_stats.cc b/src/core/ext/census/census_rpc_stats.cc
deleted file mode 100644
index 0aca1f1..0000000
--- a/src/core/ext/census/census_rpc_stats.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/sync.h>
-#include "src/core/ext/census/census_interface.h"
-#include "src/core/ext/census/census_rpc_stats.h"
-#include "src/core/ext/census/census_tracing.h"
-#include "src/core/ext/census/hash_table.h"
-#include "src/core/ext/census/window_stats.h"
-#include "src/core/lib/support/murmur_hash.h"
-#include "src/core/lib/support/string.h"
-
-#define NUM_INTERVALS 3
-#define MINUTE_INTERVAL 0
-#define HOUR_INTERVAL 1
-#define TOTAL_INTERVAL 2
-
-/* for easier typing */
-typedef census_per_method_rpc_stats per_method_stats;
-
-/* Ensure mu is only initialized once. */
-static gpr_once g_stats_store_mu_init = GPR_ONCE_INIT;
-/* Guards two stats stores. */
-static gpr_mu g_mu;
-static census_ht *g_client_stats_store = NULL;
-static census_ht *g_server_stats_store = NULL;
-
-static void init_mutex(void) { gpr_mu_init(&g_mu); }
-
-static void init_mutex_once(void) {
- gpr_once_init(&g_stats_store_mu_init, init_mutex);
-}
-
-static int cmp_str_keys(const void *k1, const void *k2) {
- return strcmp((const char *)k1, (const char *)k2);
-}
-
-/* TODO(hongyu): replace it with cityhash64 */
-static uint64_t simple_hash(const void *k) {
- size_t len = strlen(k);
- uint64_t higher = gpr_murmur_hash3((const char *)k, len / 2, 0);
- return higher << 32 |
- gpr_murmur_hash3((const char *)k + len / 2, len - len / 2, 0);
-}
-
-static void delete_stats(void *stats) {
- census_window_stats_destroy((struct census_window_stats *)stats);
-}
-
-static void delete_key(void *key) { gpr_free(key); }
-
-static const census_ht_option ht_opt = {
- CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */,
- simple_hash /* hash function */, cmp_str_keys /* key comparator */,
- delete_stats /* data deleter */, delete_key /* key deleter */
-};
-
-static void init_rpc_stats(void *stats) {
- memset(stats, 0, sizeof(census_rpc_stats));
-}
-
-static void stat_add_proportion(double p, void *base, const void *addme) {
- census_rpc_stats *b = (census_rpc_stats *)base;
- census_rpc_stats *a = (census_rpc_stats *)addme;
- b->cnt += p * a->cnt;
- b->rpc_error_cnt += p * a->rpc_error_cnt;
- b->app_error_cnt += p * a->app_error_cnt;
- b->elapsed_time_ms += p * a->elapsed_time_ms;
- b->api_request_bytes += p * a->api_request_bytes;
- b->wire_request_bytes += p * a->wire_request_bytes;
- b->api_response_bytes += p * a->api_response_bytes;
- b->wire_response_bytes += p * a->wire_response_bytes;
-}
-
-static void stat_add(void *base, const void *addme) {
- stat_add_proportion(1.0, base, addme);
-}
-
-static gpr_timespec min_hour_total_intervals[3] = {
- {60, 0}, {3600, 0}, {36000000, 0}};
-
-static const census_window_stats_stat_info window_stats_settings = {
- sizeof(census_rpc_stats), init_rpc_stats, stat_add, stat_add_proportion};
-
-census_rpc_stats *census_rpc_stats_create_empty(void) {
- census_rpc_stats *ret =
- (census_rpc_stats *)gpr_malloc(sizeof(census_rpc_stats));
- memset(ret, 0, sizeof(census_rpc_stats));
- return ret;
-}
-
-void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats *data) {
- int i = 0;
- for (i = 0; i < data->num_entries; i++) {
- if (data->stats[i].method != NULL) {
- gpr_free((void *)data->stats[i].method);
- }
- }
- if (data->stats != NULL) {
- gpr_free(data->stats);
- }
- data->num_entries = 0;
- data->stats = NULL;
-}
-
-static void record_stats(census_ht *store, census_op_id op_id,
- const census_rpc_stats *stats) {
- gpr_mu_lock(&g_mu);
- if (store != NULL) {
- census_trace_obj *trace = NULL;
- census_internal_lock_trace_store();
- trace = census_get_trace_obj_locked(op_id);
- if (trace != NULL) {
- const char *method_name = census_get_trace_method_name(trace);
- struct census_window_stats *window_stats = NULL;
- census_ht_key key;
- key.ptr = (void *)method_name;
- window_stats = census_ht_find(store, key);
- census_internal_unlock_trace_store();
- if (window_stats == NULL) {
- window_stats = census_window_stats_create(3, min_hour_total_intervals,
- 30, &window_stats_settings);
- key.ptr = gpr_strdup(key.ptr);
- census_ht_insert(store, key, (void *)window_stats);
- }
- census_window_stats_add(window_stats, gpr_now(GPR_CLOCK_REALTIME), stats);
- } else {
- census_internal_unlock_trace_store();
- }
- }
- gpr_mu_unlock(&g_mu);
-}
-
-void census_record_rpc_client_stats(census_op_id op_id,
- const census_rpc_stats *stats) {
- record_stats(g_client_stats_store, op_id, stats);
-}
-
-void census_record_rpc_server_stats(census_op_id op_id,
- const census_rpc_stats *stats) {
- record_stats(g_server_stats_store, op_id, stats);
-}
-
-/* Get stats from input stats store */
-static void get_stats(census_ht *store, census_aggregated_rpc_stats *data) {
- GPR_ASSERT(data != NULL);
- if (data->num_entries != 0) {
- census_aggregated_rpc_stats_set_empty(data);
- }
- gpr_mu_lock(&g_mu);
- if (store != NULL) {
- size_t n;
- unsigned i, j;
- gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
- census_ht_kv *kv = census_ht_get_all_elements(store, &n);
- if (kv != NULL) {
- data->num_entries = n;
- data->stats =
- (per_method_stats *)gpr_malloc(sizeof(per_method_stats) * n);
- for (i = 0; i < n; i++) {
- census_window_stats_sums sums[NUM_INTERVALS];
- for (j = 0; j < NUM_INTERVALS; j++) {
- sums[j].statistic = (void *)census_rpc_stats_create_empty();
- }
- data->stats[i].method = gpr_strdup(kv[i].k.ptr);
- census_window_stats_get_sums(kv[i].v, now, sums);
- data->stats[i].minute_stats =
- *(census_rpc_stats *)sums[MINUTE_INTERVAL].statistic;
- data->stats[i].hour_stats =
- *(census_rpc_stats *)sums[HOUR_INTERVAL].statistic;
- data->stats[i].total_stats =
- *(census_rpc_stats *)sums[TOTAL_INTERVAL].statistic;
- for (j = 0; j < NUM_INTERVALS; j++) {
- gpr_free(sums[j].statistic);
- }
- }
- gpr_free(kv);
- }
- }
- gpr_mu_unlock(&g_mu);
-}
-
-void census_get_client_stats(census_aggregated_rpc_stats *data) {
- get_stats(g_client_stats_store, data);
-}
-
-void census_get_server_stats(census_aggregated_rpc_stats *data) {
- get_stats(g_server_stats_store, data);
-}
-
-void census_stats_store_init(void) {
- init_mutex_once();
- gpr_mu_lock(&g_mu);
- if (g_client_stats_store == NULL && g_server_stats_store == NULL) {
- g_client_stats_store = census_ht_create(&ht_opt);
- g_server_stats_store = census_ht_create(&ht_opt);
- } else {
- gpr_log(GPR_ERROR, "Census stats store already initialized.");
- }
- gpr_mu_unlock(&g_mu);
-}
-
-void census_stats_store_shutdown(void) {
- init_mutex_once();
- gpr_mu_lock(&g_mu);
- if (g_client_stats_store != NULL) {
- census_ht_destroy(g_client_stats_store);
- g_client_stats_store = NULL;
- } else {
- gpr_log(GPR_ERROR, "Census server stats store not initialized.");
- }
- if (g_server_stats_store != NULL) {
- census_ht_destroy(g_server_stats_store);
- g_server_stats_store = NULL;
- } else {
- gpr_log(GPR_ERROR, "Census client stats store not initialized.");
- }
- gpr_mu_unlock(&g_mu);
-}
diff --git a/src/core/ext/census/census_rpc_stats.h b/src/core/ext/census/census_rpc_stats.h
deleted file mode 100644
index 8004ade..0000000
--- a/src/core/ext/census/census_rpc_stats.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_CENSUS_RPC_STATS_H
-#define GRPC_CORE_EXT_CENSUS_CENSUS_RPC_STATS_H
-
-#include <grpc/support/port_platform.h>
-#include "src/core/ext/census/census_interface.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct census_rpc_stats {
- uint64_t cnt;
- uint64_t rpc_error_cnt;
- uint64_t app_error_cnt;
- double elapsed_time_ms;
- double api_request_bytes;
- double wire_request_bytes;
- double api_response_bytes;
- double wire_response_bytes;
-};
-
-/* Creates an empty rpc stats object on heap. */
-census_rpc_stats *census_rpc_stats_create_empty(void);
-
-typedef struct census_per_method_rpc_stats {
- const char *method;
- census_rpc_stats minute_stats; /* cumulative stats in the past minute */
- census_rpc_stats hour_stats; /* cumulative stats in the past hour */
- census_rpc_stats total_stats; /* cumulative stats from last gc */
-} census_per_method_rpc_stats;
-
-typedef struct census_aggregated_rpc_stats {
- int num_entries;
- census_per_method_rpc_stats *stats;
-} census_aggregated_rpc_stats;
-
-/* Initializes an aggregated rpc stats object to an empty state. */
-void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats *data);
-
-/* Records client side stats of a rpc. */
-void census_record_rpc_client_stats(census_op_id op_id,
- const census_rpc_stats *stats);
-
-/* Records server side stats of a rpc. */
-void census_record_rpc_server_stats(census_op_id op_id,
- const census_rpc_stats *stats);
-
-/* The following two functions are intended for inprocess query of
- per-service per-method stats from grpc implementations. */
-
-/* Populates *data_map with server side aggregated per-service per-method
- stats.
- DO NOT CALL from outside of grpc code. */
-void census_get_server_stats(census_aggregated_rpc_stats *data_map);
-
-/* Populates *data_map with client side aggregated per-service per-method
- stats.
- DO NOT CALL from outside of grpc code. */
-void census_get_client_stats(census_aggregated_rpc_stats *data_map);
-
-void census_stats_store_init(void);
-void census_stats_store_shutdown(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_CENSUS_RPC_STATS_H */
diff --git a/src/core/ext/census/census_tracing.cc b/src/core/ext/census/census_tracing.cc
deleted file mode 100644
index 199b260..0000000
--- a/src/core/ext/census/census_tracing.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/census_tracing.h"
-#include "src/core/ext/census/census_interface.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/sync.h>
-#include "src/core/ext/census/hash_table.h"
-#include "src/core/lib/support/string.h"
-
-void census_trace_obj_destroy(census_trace_obj *obj) {
- census_trace_annotation *p = obj->annotations;
- while (p != NULL) {
- census_trace_annotation *next = p->next;
- gpr_free(p);
- p = next;
- }
- gpr_free(obj->method);
- gpr_free(obj);
-}
-
-static void delete_trace_obj(void *obj) {
- census_trace_obj_destroy((census_trace_obj *)obj);
-}
-
-static const census_ht_option ht_opt = {
- CENSUS_HT_UINT64 /* key type */,
- 571 /* n_of_buckets */,
- NULL /* hash */,
- NULL /* compare_keys */,
- delete_trace_obj /* delete data */,
- NULL /* delete key */
-};
-
-static gpr_once g_init_mutex_once = GPR_ONCE_INIT;
-static gpr_mu g_mu; /* Guards following two static variables. */
-static census_ht *g_trace_store = NULL;
-static uint64_t g_id = 0;
-
-static census_ht_key op_id_as_key(census_op_id *id) {
- return *(census_ht_key *)id;
-}
-
-static uint64_t op_id_2_uint64(census_op_id *id) {
- uint64_t ret;
- memcpy(&ret, id, sizeof(census_op_id));
- return ret;
-}
-
-static void init_mutex(void) { gpr_mu_init(&g_mu); }
-
-static void init_mutex_once(void) {
- gpr_once_init(&g_init_mutex_once, init_mutex);
-}
-
-census_op_id census_tracing_start_op(void) {
- gpr_mu_lock(&g_mu);
- {
- census_trace_obj *ret = gpr_malloc(sizeof(census_trace_obj));
- memset(ret, 0, sizeof(census_trace_obj));
- g_id++;
- memcpy(&ret->id, &g_id, sizeof(census_op_id));
- ret->rpc_stats.cnt = 1;
- ret->ts = gpr_now(GPR_CLOCK_REALTIME);
- census_ht_insert(g_trace_store, op_id_as_key(&ret->id), (void *)ret);
- gpr_log(GPR_DEBUG, "Start tracing for id %lu", g_id);
- gpr_mu_unlock(&g_mu);
- return ret->id;
- }
-}
-
-int census_add_method_tag(census_op_id op_id, const char *method) {
- int ret = 0;
- census_trace_obj *trace = NULL;
- gpr_mu_lock(&g_mu);
- trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
- if (trace == NULL) {
- ret = 1;
- } else {
- trace->method = gpr_strdup(method);
- }
- gpr_mu_unlock(&g_mu);
- return ret;
-}
-
-void census_tracing_print(census_op_id op_id, const char *anno_txt) {
- census_trace_obj *trace = NULL;
- gpr_mu_lock(&g_mu);
- trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
- if (trace != NULL) {
- census_trace_annotation *anno = gpr_malloc(sizeof(census_trace_annotation));
- anno->ts = gpr_now(GPR_CLOCK_REALTIME);
- {
- char *d = anno->txt;
- const char *s = anno_txt;
- int n = 0;
- for (; n < CENSUS_MAX_ANNOTATION_LENGTH && *s != '\0'; ++n) {
- *d++ = *s++;
- }
- *d = '\0';
- }
- anno->next = trace->annotations;
- trace->annotations = anno;
- }
- gpr_mu_unlock(&g_mu);
-}
-
-void census_tracing_end_op(census_op_id op_id) {
- census_trace_obj *trace = NULL;
- gpr_mu_lock(&g_mu);
- trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
- if (trace != NULL) {
- trace->rpc_stats.elapsed_time_ms = gpr_timespec_to_micros(
- gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), trace->ts));
- gpr_log(GPR_DEBUG, "End tracing for id %lu, method %s, latency %f us",
- op_id_2_uint64(&op_id), trace->method,
- trace->rpc_stats.elapsed_time_ms);
- census_ht_erase(g_trace_store, op_id_as_key(&op_id));
- }
- gpr_mu_unlock(&g_mu);
-}
-
-void census_tracing_init(void) {
- init_mutex_once();
- gpr_mu_lock(&g_mu);
- if (g_trace_store == NULL) {
- g_id = 1;
- g_trace_store = census_ht_create(&ht_opt);
- } else {
- gpr_log(GPR_ERROR, "Census trace store already initialized.");
- }
- gpr_mu_unlock(&g_mu);
-}
-
-void census_tracing_shutdown(void) {
- gpr_mu_lock(&g_mu);
- if (g_trace_store != NULL) {
- census_ht_destroy(g_trace_store);
- g_trace_store = NULL;
- } else {
- gpr_log(GPR_ERROR, "Census trace store is not initialized.");
- }
- gpr_mu_unlock(&g_mu);
-}
-
-void census_internal_lock_trace_store(void) { gpr_mu_lock(&g_mu); }
-
-void census_internal_unlock_trace_store(void) { gpr_mu_unlock(&g_mu); }
-
-census_trace_obj *census_get_trace_obj_locked(census_op_id op_id) {
- if (g_trace_store == NULL) {
- gpr_log(GPR_ERROR, "Census trace store is not initialized.");
- return NULL;
- }
- return (census_trace_obj *)census_ht_find(g_trace_store,
- op_id_as_key(&op_id));
-}
-
-const char *census_get_trace_method_name(const census_trace_obj *trace) {
- return trace->method;
-}
-
-static census_trace_annotation *dup_annotation_chain(
- census_trace_annotation *from) {
- census_trace_annotation *ret = NULL;
- census_trace_annotation **to = &ret;
- for (; from != NULL; from = from->next) {
- *to = gpr_malloc(sizeof(census_trace_annotation));
- memcpy(*to, from, sizeof(census_trace_annotation));
- to = &(*to)->next;
- }
- return ret;
-}
-
-static census_trace_obj *trace_obj_dup(census_trace_obj *from) {
- census_trace_obj *to = NULL;
- GPR_ASSERT(from != NULL);
- to = gpr_malloc(sizeof(census_trace_obj));
- to->id = from->id;
- to->ts = from->ts;
- to->rpc_stats = from->rpc_stats;
- to->method = gpr_strdup(from->method);
- to->annotations = dup_annotation_chain(from->annotations);
- return to;
-}
-
-census_trace_obj **census_get_active_ops(int *num_active_ops) {
- census_trace_obj **ret = NULL;
- gpr_mu_lock(&g_mu);
- if (g_trace_store != NULL) {
- size_t n = 0;
- census_ht_kv *all_kvs = census_ht_get_all_elements(g_trace_store, &n);
- *num_active_ops = (int)n;
- if (n != 0) {
- size_t i = 0;
- ret = gpr_malloc(sizeof(census_trace_obj *) * n);
- for (i = 0; i < n; i++) {
- ret[i] = trace_obj_dup((census_trace_obj *)all_kvs[i].v);
- }
- }
- gpr_free(all_kvs);
- }
- gpr_mu_unlock(&g_mu);
- return ret;
-}
diff --git a/src/core/ext/census/census_tracing.h b/src/core/ext/census/census_tracing.h
deleted file mode 100644
index ccb767f..0000000
--- a/src/core/ext/census/census_tracing.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_CENSUS_TRACING_H
-#define GRPC_CORE_EXT_CENSUS_CENSUS_TRACING_H
-
-#include <grpc/support/time.h>
-#include "src/core/ext/census/census_rpc_stats.h"
-
-/* WARNING: The data structures and APIs provided by this file are for GRPC
- library's internal use ONLY. They might be changed in backward-incompatible
- ways and are not subject to any deprecation policy.
- They are not recommended for external use.
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Struct for a trace annotation. */
-typedef struct census_trace_annotation {
- gpr_timespec ts; /* timestamp of the annotation */
- char txt[CENSUS_MAX_ANNOTATION_LENGTH + 1]; /* actual txt annotation */
- struct census_trace_annotation *next;
-} census_trace_annotation;
-
-typedef struct census_trace_obj {
- census_op_id id;
- gpr_timespec ts;
- census_rpc_stats rpc_stats;
- char *method;
- census_trace_annotation *annotations;
-} census_trace_obj;
-
-/* Deletes trace object. */
-void census_trace_obj_destroy(census_trace_obj *obj);
-
-/* Initializes trace store. This function is thread safe. */
-void census_tracing_init(void);
-
-/* Shutsdown trace store. This function is thread safe. */
-void census_tracing_shutdown(void);
-
-/* Gets trace obj corresponding to the input op_id. Returns NULL if trace store
- is not initialized or trace obj is not found. Requires trace store being
- locked before calling this function. */
-census_trace_obj *census_get_trace_obj_locked(census_op_id op_id);
-
-/* The following two functions acquire and release the trace store global lock.
- They are for census internal use only. */
-void census_internal_lock_trace_store(void);
-void census_internal_unlock_trace_store(void);
-
-/* Gets method name associated with the input trace object. */
-const char *census_get_trace_method_name(const census_trace_obj *trace);
-
-/* Returns an array of pointers to trace objects of currently active operations
- and fills in number of active operations. Returns NULL if there are no active
- operations.
- Caller owns the returned objects. */
-census_trace_obj **census_get_active_ops(int *num_active_ops);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_CENSUS_TRACING_H */
diff --git a/src/core/ext/census/context.cc b/src/core/ext/census/context.cc
deleted file mode 100644
index 9b25a32..0000000
--- a/src/core/ext/census/context.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/census.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/useful.h>
-#include <stdbool.h>
-#include <string.h>
-#include "src/core/lib/support/string.h"
-
-// Functions in this file support the public context API, including
-// encoding/decoding as part of context propagation across RPC's. The overall
-// requirements (in approximate priority order) for the
-// context representation:
-// 1. Efficient conversion to/from wire format
-// 2. Minimal bytes used on-wire
-// 3. Efficient context creation
-// 4. Efficient lookup of tag value for a key
-// 5. Efficient iteration over tags
-// 6. Minimal memory footprint
-//
-// Notes on tradeoffs/decisions:
-// * tag includes 1 byte length of key, as well as nil-terminating byte. These
-// are to aid in efficient parsing and the ability to directly return key
-// strings. This is more important than saving a single byte/tag on the wire.
-// * The wire encoding uses only single byte values. This eliminates the need
-// to handle endian-ness conversions. It also means there is a hard upper
-// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS.
-// * Keep all tag information (keys/values/flags) in a single memory buffer,
-// that can be directly copied to the wire.
-
-// min and max valid chars in tag keys and values. All printable ASCII is OK.
-#define MIN_VALID_TAG_CHAR 32 // ' '
-#define MAX_VALID_TAG_CHAR 126 // '~'
-
-// Structure representing a set of tags. Essentially a count of number of tags
-// present, and pointer to a chunk of memory that contains the per-tag details.
-struct tag_set {
- int ntags; // number of tags.
- int ntags_alloc; // ntags + number of deleted tags (total number of tags
- // in all of kvm). This will always be == ntags, except during the process
- // of building a new tag set.
- size_t kvm_size; // number of bytes allocated for key/value storage.
- size_t kvm_used; // number of bytes of used key/value memory
- char *kvm; // key/value memory. Consists of repeated entries of:
- // Offset Size Description
- // 0 1 Key length, including trailing 0. (K)
- // 1 1 Value length, including trailing 0 (V)
- // 2 1 Flags
- // 3 K Key bytes
- // 3 + K V Value bytes
- //
- // We refer to the first 3 entries as the 'tag header'. If extra values are
- // introduced in the header, you will need to modify the TAG_HEADER_SIZE
- // constant, the raw_tag structure (and everything that uses it) and the
- // encode/decode functions appropriately.
-};
-
-// Number of bytes in tag header.
-#define TAG_HEADER_SIZE 3 // key length (1) + value length (1) + flags (1)
-// Offsets to tag header entries.
-#define KEY_LEN_OFFSET 0
-#define VALUE_LEN_OFFSET 1
-#define FLAG_OFFSET 2
-
-// raw_tag represents the raw-storage form of a tag in the kvm of a tag_set.
-struct raw_tag {
- uint8_t key_len;
- uint8_t value_len;
- uint8_t flags;
- char *key;
- char *value;
-};
-
-// Use a reserved flag bit for indication of deleted tag.
-#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED
-#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED)
-
-// Primary representation of a context. Composed of 2 underlying tag_set
-// structs, one each for propagated and local (non-propagated) tags. This is
-// to efficiently support tag encoding/decoding.
-// TODO(aveitch): need to add tracing id's/structure.
-struct census_context {
- struct tag_set tags[2];
- census_context_status status;
-};
-
-// Indices into the tags member of census_context
-#define PROPAGATED_TAGS 0
-#define LOCAL_TAGS 1
-
-// Validate (check all characters are in range and size is less than limit) a
-// key or value string. Returns 0 if the string is invalid, or the length
-// (including terminator) if valid.
-static size_t validate_tag(const char *kv) {
- size_t len = 1;
- char ch;
- while ((ch = *kv++) != 0) {
- if (ch < MIN_VALID_TAG_CHAR || ch > MAX_VALID_TAG_CHAR) {
- return 0;
- }
- len++;
- }
- if (len > CENSUS_MAX_TAG_KV_LEN) {
- return 0;
- }
- return len;
-}
-
-// Extract a raw tag given a pointer (raw) to the tag header. Allow for some
-// extra bytes in the tag header (see encode/decode functions for usage: this
-// allows for future expansion of the tag header).
-static char *decode_tag(struct raw_tag *tag, char *header, int offset) {
- tag->key_len = (uint8_t)(*header++);
- tag->value_len = (uint8_t)(*header++);
- tag->flags = (uint8_t)(*header++);
- header += offset;
- tag->key = header;
- header += tag->key_len;
- tag->value = header;
- return header + tag->value_len;
-}
-
-// Make a copy (in 'to') of an existing tag_set.
-static void tag_set_copy(struct tag_set *to, const struct tag_set *from) {
- memcpy(to, from, sizeof(struct tag_set));
- to->kvm = (char *)gpr_malloc(to->kvm_size);
- memcpy(to->kvm, from->kvm, from->kvm_used);
-}
-
-// Delete a tag from a tag_set, if it exists (returns true if it did).
-static bool tag_set_delete_tag(struct tag_set *tags, const char *key,
- size_t key_len) {
- char *kvp = tags->kvm;
- for (int i = 0; i < tags->ntags_alloc; i++) {
- uint8_t *flags = (uint8_t *)(kvp + FLAG_OFFSET);
- struct raw_tag tag;
- kvp = decode_tag(&tag, kvp, 0);
- if (CENSUS_TAG_IS_DELETED(tag.flags)) continue;
- if ((key_len == tag.key_len) && (memcmp(key, tag.key, key_len) == 0)) {
- *flags |= CENSUS_TAG_DELETED;
- tags->ntags--;
- return true;
- }
- }
- return false;
-}
-
-// Delete a tag from a context, return true if it existed.
-static bool context_delete_tag(census_context *context, const census_tag *tag,
- size_t key_len) {
- return (
- tag_set_delete_tag(&context->tags[LOCAL_TAGS], tag->key, key_len) ||
- tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len));
-}
-
-// Add a tag to a tag_set. Return true on success, false if the tag could
-// not be added because of constraints on tag set size. This function should
-// not be called if the tag may already exist (in a non-deleted state) in
-// the tag_set, as that would result in two tags with the same key.
-static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
- size_t key_len, size_t value_len) {
- if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) {
- return false;
- }
- const size_t tag_size = key_len + value_len + TAG_HEADER_SIZE;
- if (tags->kvm_used + tag_size > tags->kvm_size) {
- // allocate new memory if needed
- tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
- char *new_kvm = (char *)gpr_malloc(tags->kvm_size);
- if (tags->kvm_used > 0) memcpy(new_kvm, tags->kvm, tags->kvm_used);
- gpr_free(tags->kvm);
- tags->kvm = new_kvm;
- }
- char *kvp = tags->kvm + tags->kvm_used;
- *kvp++ = (char)key_len;
- *kvp++ = (char)value_len;
- // ensure reserved flags are not used.
- *kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS));
- memcpy(kvp, tag->key, key_len);
- kvp += key_len;
- memcpy(kvp, tag->value, value_len);
- tags->kvm_used += tag_size;
- tags->ntags++;
- tags->ntags_alloc++;
- return true;
-}
-
-// Add/modify/delete a tag to/in a context. Caller must validate that tag key
-// etc. are valid.
-static void context_modify_tag(census_context *context, const census_tag *tag,
- size_t key_len, size_t value_len) {
- // First delete the tag if it is already present.
- bool deleted = context_delete_tag(context, tag, key_len);
- bool added = false;
- if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
- added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len,
- value_len);
- } else {
- added =
- tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len, value_len);
- }
-
- if (deleted) {
- context->status.n_modified_tags++;
- } else {
- if (added) {
- context->status.n_added_tags++;
- } else {
- context->status.n_ignored_tags++;
- }
- }
-}
-
-// Remove memory used for deleted tags from a tag set. Basic algorithm:
-// 1) Walk through tag set to find first deleted tag. Record where it is.
-// 2) Find the next not-deleted tag. Copy all of kvm from there to the end
-// "over" the deleted tags
-// 3) repeat #1 and #2 until we have seen all tags
-// 4) if we are still looking for a not-deleted tag, then all the end portion
-// of the kvm is deleted. Just reduce the used amount of memory by the
-// appropriate amount.
-static void tag_set_flatten(struct tag_set *tags) {
- if (tags->ntags == tags->ntags_alloc) return;
- bool found_deleted = false; // found a deleted tag.
- char *kvp = tags->kvm;
- char *dbase = NULL; // record location of deleted tag
- for (int i = 0; i < tags->ntags_alloc; i++) {
- struct raw_tag tag;
- char *next_kvp = decode_tag(&tag, kvp, 0);
- if (found_deleted) {
- if (!CENSUS_TAG_IS_DELETED(tag.flags)) {
- ptrdiff_t reduce = kvp - dbase; // #bytes in deleted tags
- GPR_ASSERT(reduce > 0);
- ptrdiff_t copy_size = tags->kvm + tags->kvm_used - kvp;
- GPR_ASSERT(copy_size > 0);
- memmove(dbase, kvp, (size_t)copy_size);
- tags->kvm_used -= (size_t)reduce;
- next_kvp -= reduce;
- found_deleted = false;
- }
- } else {
- if (CENSUS_TAG_IS_DELETED(tag.flags)) {
- dbase = kvp;
- found_deleted = true;
- }
- }
- kvp = next_kvp;
- }
- if (found_deleted) {
- GPR_ASSERT(dbase > tags->kvm);
- tags->kvm_used = (size_t)(dbase - tags->kvm);
- }
- tags->ntags_alloc = tags->ntags;
-}
-
-census_context *census_context_create(const census_context *base,
- const census_tag *tags, int ntags,
- census_context_status const **status) {
- census_context *context =
- (census_context *)gpr_malloc(sizeof(census_context));
- // If we are given a base, copy it into our new tag set. Otherwise set it
- // to zero/NULL everything.
- if (base == NULL) {
- memset(context, 0, sizeof(census_context));
- } else {
- tag_set_copy(&context->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]);
- tag_set_copy(&context->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]);
- memset(&context->status, 0, sizeof(context->status));
- }
- // Walk over the additional tags and, for those that aren't invalid, modify
- // the context to add/replace/delete as required.
- for (int i = 0; i < ntags; i++) {
- const census_tag *tag = &tags[i];
- size_t key_len = validate_tag(tag->key);
- // ignore the tag if it is invalid or too short.
- if (key_len <= 1) {
- context->status.n_invalid_tags++;
- } else {
- if (tag->value != NULL) {
- size_t value_len = validate_tag(tag->value);
- if (value_len != 0) {
- context_modify_tag(context, tag, key_len, value_len);
- } else {
- context->status.n_invalid_tags++;
- }
- } else {
- if (context_delete_tag(context, tag, key_len)) {
- context->status.n_deleted_tags++;
- }
- }
- }
- }
- // Remove any deleted tags, update status if needed, and return.
- tag_set_flatten(&context->tags[PROPAGATED_TAGS]);
- tag_set_flatten(&context->tags[LOCAL_TAGS]);
- context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
- context->status.n_local_tags = context->tags[LOCAL_TAGS].ntags;
- if (status) {
- *status = &context->status;
- }
- return context;
-}
-
-const census_context_status *census_context_get_status(
- const census_context *context) {
- return &context->status;
-}
-
-void census_context_destroy(census_context *context) {
- gpr_free(context->tags[PROPAGATED_TAGS].kvm);
- gpr_free(context->tags[LOCAL_TAGS].kvm);
- gpr_free(context);
-}
-
-void census_context_initialize_iterator(const census_context *context,
- census_context_iterator *iterator) {
- iterator->context = context;
- iterator->index = 0;
- if (context->tags[PROPAGATED_TAGS].ntags != 0) {
- iterator->base = PROPAGATED_TAGS;
- iterator->kvm = context->tags[PROPAGATED_TAGS].kvm;
- } else if (context->tags[LOCAL_TAGS].ntags != 0) {
- iterator->base = LOCAL_TAGS;
- iterator->kvm = context->tags[LOCAL_TAGS].kvm;
- } else {
- iterator->base = -1;
- }
-}
-
-int census_context_next_tag(census_context_iterator *iterator,
- census_tag *tag) {
- if (iterator->base < 0) {
- return 0;
- }
- struct raw_tag raw;
- iterator->kvm = decode_tag(&raw, iterator->kvm, 0);
- tag->key = raw.key;
- tag->value = raw.value;
- tag->flags = raw.flags;
- if (++iterator->index == iterator->context->tags[iterator->base].ntags) {
- do {
- if (iterator->base == LOCAL_TAGS) {
- iterator->base = -1;
- return 1;
- }
- } while (iterator->context->tags[++iterator->base].ntags == 0);
- iterator->index = 0;
- iterator->kvm = iterator->context->tags[iterator->base].kvm;
- }
- return 1;
-}
-
-// Find a tag in a tag_set by key. Return true if found, false otherwise.
-static bool tag_set_get_tag(const struct tag_set *tags, const char *key,
- size_t key_len, census_tag *tag) {
- char *kvp = tags->kvm;
- for (int i = 0; i < tags->ntags; i++) {
- struct raw_tag raw;
- kvp = decode_tag(&raw, kvp, 0);
- if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) {
- tag->key = raw.key;
- tag->value = raw.value;
- tag->flags = raw.flags;
- return true;
- }
- }
- return false;
-}
-
-int census_context_get_tag(const census_context *context, const char *key,
- census_tag *tag) {
- size_t key_len = strlen(key) + 1;
- if (key_len == 1) {
- return 0;
- }
- if (tag_set_get_tag(&context->tags[PROPAGATED_TAGS], key, key_len, tag) ||
- tag_set_get_tag(&context->tags[LOCAL_TAGS], key, key_len, tag)) {
- return 1;
- }
- return 0;
-}
-
-// Context encoding and decoding functions.
-//
-// Wire format for tag_set's on the wire:
-//
-// First, a tag set header:
-//
-// offset bytes description
-// 0 1 version number
-// 1 1 number of bytes in this header. This allows for future
-// expansion.
-// 2 1 number of bytes in each tag header.
-// 3 1 ntags value from tag set.
-//
-// This is followed by the key/value memory from struct tag_set.
-
-#define ENCODED_VERSION 0 // Version number
-#define ENCODED_HEADER_SIZE 4 // size of tag set header
-
-// Encode a tag set. Returns 0 if buffer is too small.
-static size_t tag_set_encode(const struct tag_set *tags, char *buffer,
- size_t buf_size) {
- if (buf_size < ENCODED_HEADER_SIZE + tags->kvm_used) {
- return 0;
- }
- buf_size -= ENCODED_HEADER_SIZE;
- *buffer++ = (char)ENCODED_VERSION;
- *buffer++ = (char)ENCODED_HEADER_SIZE;
- *buffer++ = (char)TAG_HEADER_SIZE;
- *buffer++ = (char)tags->ntags;
- if (tags->ntags == 0) {
- return ENCODED_HEADER_SIZE;
- }
- memcpy(buffer, tags->kvm, tags->kvm_used);
- return ENCODED_HEADER_SIZE + tags->kvm_used;
-}
-
-size_t census_context_encode(const census_context *context, char *buffer,
- size_t buf_size) {
- return tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size);
-}
-
-// Decode a tag set.
-static void tag_set_decode(struct tag_set *tags, const char *buffer,
- size_t size) {
- uint8_t version = (uint8_t)(*buffer++);
- uint8_t header_size = (uint8_t)(*buffer++);
- uint8_t tag_header_size = (uint8_t)(*buffer++);
- tags->ntags = tags->ntags_alloc = (int)(*buffer++);
- if (tags->ntags == 0) {
- tags->ntags_alloc = 0;
- tags->kvm_size = 0;
- tags->kvm_used = 0;
- tags->kvm = NULL;
- return;
- }
- if (header_size != ENCODED_HEADER_SIZE) {
- GPR_ASSERT(version != ENCODED_VERSION);
- GPR_ASSERT(ENCODED_HEADER_SIZE < header_size);
- buffer += (header_size - ENCODED_HEADER_SIZE);
- }
- tags->kvm_used = size - header_size;
- tags->kvm_size = tags->kvm_used + CENSUS_MAX_TAG_KV_LEN;
- tags->kvm = (char *)gpr_malloc(tags->kvm_size);
- if (tag_header_size != TAG_HEADER_SIZE) {
- // something new in the tag information. I don't understand it, so
- // don't copy it over.
- GPR_ASSERT(version != ENCODED_VERSION);
- GPR_ASSERT(tag_header_size > TAG_HEADER_SIZE);
- char *kvp = tags->kvm;
- for (int i = 0; i < tags->ntags; i++) {
- memcpy(kvp, buffer, TAG_HEADER_SIZE);
- kvp += header_size;
- struct raw_tag raw;
- buffer =
- decode_tag(&raw, (char *)buffer, tag_header_size - TAG_HEADER_SIZE);
- memcpy(kvp, raw.key, (size_t)raw.key_len + raw.value_len);
- kvp += raw.key_len + raw.value_len;
- }
- } else {
- memcpy(tags->kvm, buffer, tags->kvm_used);
- }
-}
-
-census_context *census_context_decode(const char *buffer, size_t size) {
- census_context *context =
- (census_context *)gpr_malloc(sizeof(census_context));
- memset(&context->tags[LOCAL_TAGS], 0, sizeof(struct tag_set));
- if (buffer == NULL) {
- memset(&context->tags[PROPAGATED_TAGS], 0, sizeof(struct tag_set));
- } else {
- tag_set_decode(&context->tags[PROPAGATED_TAGS], buffer, size);
- }
- memset(&context->status, 0, sizeof(context->status));
- context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
- return context;
-}
diff --git a/src/core/ext/census/gen/README.md b/src/core/ext/census/gen/README.md
deleted file mode 100644
index d4612bc..0000000
--- a/src/core/ext/census/gen/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Files generated for use by Census stats and trace recording subsystem.
-
-# Files
-* census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the
- script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto
- $PWD/src/core/ext/census/gen src/core/ext/census/gen`
-* trace_context.pb.{h,c} - Generated from
- src/core/ext/census/trace_context.proto, using the script
- `tools/codegen/core/gen_nano_proto.sh src/proto/census/trace_context.proto
- $PWD/src/core/ext/census/gen src/core/ext/census/gen`
diff --git a/src/core/ext/census/gen/census.pb.c b/src/core/ext/census/gen/census.pb.c
deleted file mode 100644
index 88efa73..0000000
--- a/src/core/ext/census/gen/census.pb.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-/* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.3.5-dev */
-
-#include "src/core/ext/census/gen/census.pb.h"
-
-#if PB_PROTO_HEADER_VERSION != 30
-#error Regenerate this file with the current version of nanopb generator.
-#endif
-
-
-
-const pb_field_t google_census_Duration_fields[3] = {
- PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, google_census_Duration, seconds, seconds, 0),
- PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, google_census_Duration, nanos, seconds, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Timestamp_fields[3] = {
- PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, google_census_Timestamp, seconds, seconds, 0),
- PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, google_census_Timestamp, nanos, seconds, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Resource_fields[4] = {
- PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Resource, name, name, 0),
- PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Resource, description, name, 0),
- PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Resource, unit, description, &google_census_Resource_MeasurementUnit_fields),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Resource_MeasurementUnit_fields[4] = {
- PB_FIELD( 1, INT32 , OPTIONAL, STATIC , FIRST, google_census_Resource_MeasurementUnit, prefix, prefix, 0),
- PB_FIELD( 2, UENUM , REPEATED, CALLBACK, OTHER, google_census_Resource_MeasurementUnit, numerator, prefix, 0),
- PB_FIELD( 3, UENUM , REPEATED, CALLBACK, OTHER, google_census_Resource_MeasurementUnit, denominator, numerator, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_AggregationDescriptor_fields[4] = {
- PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, google_census_AggregationDescriptor, type, type, 0),
- PB_ONEOF_FIELD(options, 2, MESSAGE , ONEOF, STATIC , OTHER, google_census_AggregationDescriptor, bucket_boundaries, type, &google_census_AggregationDescriptor_BucketBoundaries_fields),
- PB_ONEOF_FIELD(options, 3, MESSAGE , ONEOF, STATIC , OTHER, google_census_AggregationDescriptor, interval_boundaries, type, &google_census_AggregationDescriptor_IntervalBoundaries_fields),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2] = {
- PB_FIELD( 1, DOUBLE , REPEATED, CALLBACK, FIRST, google_census_AggregationDescriptor_BucketBoundaries, bounds, bounds, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2] = {
- PB_FIELD( 1, DOUBLE , REPEATED, CALLBACK, FIRST, google_census_AggregationDescriptor_IntervalBoundaries, window_size, window_size, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Distribution_fields[5] = {
- PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, google_census_Distribution, count, count, 0),
- PB_FIELD( 2, DOUBLE , OPTIONAL, STATIC , OTHER, google_census_Distribution, mean, count, 0),
- PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Distribution, range, mean, &google_census_Distribution_Range_fields),
- PB_FIELD( 4, INT64 , REPEATED, CALLBACK, OTHER, google_census_Distribution, bucket_count, range, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Distribution_Range_fields[3] = {
- PB_FIELD( 1, DOUBLE , OPTIONAL, STATIC , FIRST, google_census_Distribution_Range, min, min, 0),
- PB_FIELD( 2, DOUBLE , OPTIONAL, STATIC , OTHER, google_census_Distribution_Range, max, min, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_IntervalStats_fields[2] = {
- PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_IntervalStats, window, window, &google_census_IntervalStats_Window_fields),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_IntervalStats_Window_fields[4] = {
- PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, google_census_IntervalStats_Window, window_size, window_size, &google_census_Duration_fields),
- PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, google_census_IntervalStats_Window, count, window_size, 0),
- PB_FIELD( 3, DOUBLE , OPTIONAL, STATIC , OTHER, google_census_IntervalStats_Window, mean, count, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Tag_fields[3] = {
- PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, google_census_Tag, key, key, 0),
- PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, google_census_Tag, value, key, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_View_fields[6] = {
- PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_View, name, name, 0),
- PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_View, description, name, 0),
- PB_FIELD( 3, STRING , OPTIONAL, CALLBACK, OTHER, google_census_View, resource_name, description, 0),
- PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_View, aggregation, resource_name, &google_census_AggregationDescriptor_fields),
- PB_FIELD( 5, STRING , REPEATED, CALLBACK, OTHER, google_census_View, tag_key, aggregation, 0),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Aggregation_fields[7] = {
- PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Aggregation, name, name, 0),
- PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Aggregation, description, name, 0),
- PB_ONEOF_FIELD(data, 3, UINT64 , ONEOF, STATIC , OTHER, google_census_Aggregation, count, description, 0),
- PB_ONEOF_FIELD(data, 4, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, distribution, description, &google_census_Distribution_fields),
- PB_ONEOF_FIELD(data, 5, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, interval_stats, description, &google_census_IntervalStats_fields),
- PB_FIELD( 6, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Aggregation, tag, data.interval_stats, &google_census_Tag_fields),
- PB_LAST_FIELD
-};
-
-const pb_field_t google_census_Metric_fields[5] = {
- PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Metric, view_name, view_name, 0),
- PB_FIELD( 2, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric, aggregation, view_name, &google_census_Aggregation_fields),
- PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, start, aggregation, &google_census_Timestamp_fields),
- PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, end, start, &google_census_Timestamp_fields),
- PB_LAST_FIELD
-};
-
-
-/* Check that field information fits in pb_field_t */
-#if !defined(PB_FIELD_32BIT)
-/* If you get an error here, it means that you need to define PB_FIELD_32BIT
- * compile-time option. You can do that in pb.h or on compiler command line.
- *
- * The reason you need to do this is that some of your messages contain tag
- * numbers or field sizes that are larger than what can fit in 8 or 16 bit
- * field descriptors.
- */
-PB_STATIC_ASSERT((pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Aggregation, tag) < 65536 && pb_membersize(google_census_Metric, aggregation) < 65536 && pb_membersize(google_census_Metric, start) < 65536 && pb_membersize(google_census_Metric, end) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Resource_google_census_Resource_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_Metric)
-#endif
-
-#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
-/* If you get an error here, it means that you need to define PB_FIELD_16BIT
- * compile-time option. You can do that in pb.h or on compiler command line.
- *
- * The reason you need to do this is that some of your messages contain tag
- * numbers or field sizes that are larger than what can fit in the default
- * 8 bit descriptors.
- */
-PB_STATIC_ASSERT((pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Aggregation, tag) < 256 && pb_membersize(google_census_Metric, aggregation) < 256 && pb_membersize(google_census_Metric, start) < 256 && pb_membersize(google_census_Metric, end) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Resource_google_census_Resource_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_Metric)
-#endif
-
-
-/* On some platforms (such as AVR), double is really float.
- * These are not directly supported by nanopb, but see example_avr_double.
- * To get rid of this error, remove any double fields from your .proto.
- */
-PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)
-
diff --git a/src/core/ext/census/gen/census.pb.h b/src/core/ext/census/gen/census.pb.h
deleted file mode 100644
index 5f28335..0000000
--- a/src/core/ext/census/gen/census.pb.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-/* Automatically generated nanopb header */
-/* Generated by nanopb-0.3.5-dev */
-
-#ifndef GRPC_CORE_EXT_CENSUS_GEN_CENSUS_PB_H
-#define GRPC_CORE_EXT_CENSUS_GEN_CENSUS_PB_H
-#include "third_party/nanopb/pb.h"
-#if PB_PROTO_HEADER_VERSION != 30
-#error Regenerate this file with the current version of nanopb generator.
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Enum definitions */
-typedef enum _google_census_Resource_BasicUnit {
- google_census_Resource_BasicUnit_UNKNOWN = 0,
- google_census_Resource_BasicUnit_BITS = 1,
- google_census_Resource_BasicUnit_BYTES = 2,
- google_census_Resource_BasicUnit_SECS = 3,
- google_census_Resource_BasicUnit_CORES = 4,
- google_census_Resource_BasicUnit_MAX_UNITS = 5
-} google_census_Resource_BasicUnit;
-
-typedef enum _google_census_AggregationDescriptor_AggregationType {
- google_census_AggregationDescriptor_AggregationType_UNKNOWN = 0,
- google_census_AggregationDescriptor_AggregationType_COUNT = 1,
- google_census_AggregationDescriptor_AggregationType_DISTRIBUTION = 2,
- google_census_AggregationDescriptor_AggregationType_INTERVAL = 3
-} google_census_AggregationDescriptor_AggregationType;
-
-/* Struct definitions */
-typedef struct _google_census_AggregationDescriptor_BucketBoundaries {
- pb_callback_t bounds;
-} google_census_AggregationDescriptor_BucketBoundaries;
-
-typedef struct _google_census_AggregationDescriptor_IntervalBoundaries {
- pb_callback_t window_size;
-} google_census_AggregationDescriptor_IntervalBoundaries;
-
-typedef struct _google_census_IntervalStats {
- pb_callback_t window;
-} google_census_IntervalStats;
-
-typedef struct _google_census_AggregationDescriptor {
- bool has_type;
- google_census_AggregationDescriptor_AggregationType type;
- pb_size_t which_options;
- union {
- google_census_AggregationDescriptor_BucketBoundaries bucket_boundaries;
- google_census_AggregationDescriptor_IntervalBoundaries interval_boundaries;
- } options;
-} google_census_AggregationDescriptor;
-
-typedef struct _google_census_Distribution_Range {
- bool has_min;
- double min;
- bool has_max;
- double max;
-} google_census_Distribution_Range;
-
-typedef struct _google_census_Duration {
- bool has_seconds;
- int64_t seconds;
- bool has_nanos;
- int32_t nanos;
-} google_census_Duration;
-
-typedef struct _google_census_Resource_MeasurementUnit {
- bool has_prefix;
- int32_t prefix;
- pb_callback_t numerator;
- pb_callback_t denominator;
-} google_census_Resource_MeasurementUnit;
-
-typedef struct _google_census_Tag {
- bool has_key;
- char key[255];
- bool has_value;
- char value[255];
-} google_census_Tag;
-
-typedef struct _google_census_Timestamp {
- bool has_seconds;
- int64_t seconds;
- bool has_nanos;
- int32_t nanos;
-} google_census_Timestamp;
-
-typedef struct _google_census_Distribution {
- bool has_count;
- int64_t count;
- bool has_mean;
- double mean;
- bool has_range;
- google_census_Distribution_Range range;
- pb_callback_t bucket_count;
-} google_census_Distribution;
-
-typedef struct _google_census_IntervalStats_Window {
- bool has_window_size;
- google_census_Duration window_size;
- bool has_count;
- int64_t count;
- bool has_mean;
- double mean;
-} google_census_IntervalStats_Window;
-
-typedef struct _google_census_Metric {
- pb_callback_t view_name;
- pb_callback_t aggregation;
- bool has_start;
- google_census_Timestamp start;
- bool has_end;
- google_census_Timestamp end;
-} google_census_Metric;
-
-typedef struct _google_census_Resource {
- pb_callback_t name;
- pb_callback_t description;
- bool has_unit;
- google_census_Resource_MeasurementUnit unit;
-} google_census_Resource;
-
-typedef struct _google_census_View {
- pb_callback_t name;
- pb_callback_t description;
- pb_callback_t resource_name;
- bool has_aggregation;
- google_census_AggregationDescriptor aggregation;
- pb_callback_t tag_key;
-} google_census_View;
-
-typedef struct _google_census_Aggregation {
- pb_callback_t name;
- pb_callback_t description;
- pb_size_t which_data;
- union {
- uint64_t count;
- google_census_Distribution distribution;
- google_census_IntervalStats interval_stats;
- } data;
- pb_callback_t tag;
-} google_census_Aggregation;
-
-/* Default values for struct fields */
-
-/* Initializer values for message structs */
-#define google_census_Duration_init_default {false, 0, false, 0}
-#define google_census_Timestamp_init_default {false, 0, false, 0}
-#define google_census_Resource_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_default}
-#define google_census_Resource_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}}
-#define google_census_AggregationDescriptor_init_default {false, (google_census_AggregationDescriptor_AggregationType)0, 0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}}
-#define google_census_AggregationDescriptor_BucketBoundaries_init_default {{{NULL}, NULL}}
-#define google_census_AggregationDescriptor_IntervalBoundaries_init_default {{{NULL}, NULL}}
-#define google_census_Distribution_init_default {false, 0, false, 0, false, google_census_Distribution_Range_init_default, {{NULL}, NULL}}
-#define google_census_Distribution_Range_init_default {false, 0, false, 0}
-#define google_census_IntervalStats_init_default {{{NULL}, NULL}}
-#define google_census_IntervalStats_Window_init_default {false, google_census_Duration_init_default, false, 0, false, 0}
-#define google_census_Tag_init_default {false, "", false, ""}
-#define google_census_View_init_default {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}}
-#define google_census_Aggregation_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, {0}, {{NULL}, NULL}}
-#define google_census_Metric_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default}
-#define google_census_Duration_init_zero {false, 0, false, 0}
-#define google_census_Timestamp_init_zero {false, 0, false, 0}
-#define google_census_Resource_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_zero}
-#define google_census_Resource_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}}
-#define google_census_AggregationDescriptor_init_zero {false, (google_census_AggregationDescriptor_AggregationType)0, 0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}}
-#define google_census_AggregationDescriptor_BucketBoundaries_init_zero {{{NULL}, NULL}}
-#define google_census_AggregationDescriptor_IntervalBoundaries_init_zero {{{NULL}, NULL}}
-#define google_census_Distribution_init_zero {false, 0, false, 0, false, google_census_Distribution_Range_init_zero, {{NULL}, NULL}}
-#define google_census_Distribution_Range_init_zero {false, 0, false, 0}
-#define google_census_IntervalStats_init_zero {{{NULL}, NULL}}
-#define google_census_IntervalStats_Window_init_zero {false, google_census_Duration_init_zero, false, 0, false, 0}
-#define google_census_Tag_init_zero {false, "", false, ""}
-#define google_census_View_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}}
-#define google_census_Aggregation_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, {0}, {{NULL}, NULL}}
-#define google_census_Metric_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero}
-
-/* Field tags (for use in manual encoding/decoding) */
-#define google_census_AggregationDescriptor_BucketBoundaries_bounds_tag 1
-#define google_census_AggregationDescriptor_IntervalBoundaries_window_size_tag 1
-#define google_census_IntervalStats_window_tag 1
-#define google_census_AggregationDescriptor_bucket_boundaries_tag 2
-
-#define google_census_AggregationDescriptor_interval_boundaries_tag 3
-#define google_census_AggregationDescriptor_type_tag 1
-#define google_census_Distribution_Range_min_tag 1
-#define google_census_Distribution_Range_max_tag 2
-#define google_census_Duration_seconds_tag 1
-#define google_census_Duration_nanos_tag 2
-#define google_census_Resource_MeasurementUnit_prefix_tag 1
-#define google_census_Resource_MeasurementUnit_numerator_tag 2
-#define google_census_Resource_MeasurementUnit_denominator_tag 3
-#define google_census_Tag_key_tag 1
-#define google_census_Tag_value_tag 2
-#define google_census_Timestamp_seconds_tag 1
-#define google_census_Timestamp_nanos_tag 2
-#define google_census_Distribution_count_tag 1
-#define google_census_Distribution_mean_tag 2
-#define google_census_Distribution_range_tag 3
-#define google_census_Distribution_bucket_count_tag 4
-#define google_census_IntervalStats_Window_window_size_tag 1
-#define google_census_IntervalStats_Window_count_tag 2
-#define google_census_IntervalStats_Window_mean_tag 3
-#define google_census_Metric_view_name_tag 1
-#define google_census_Metric_aggregation_tag 2
-#define google_census_Metric_start_tag 3
-#define google_census_Metric_end_tag 4
-#define google_census_Resource_name_tag 1
-#define google_census_Resource_description_tag 2
-#define google_census_Resource_unit_tag 3
-#define google_census_View_name_tag 1
-#define google_census_View_description_tag 2
-#define google_census_View_resource_name_tag 3
-#define google_census_View_aggregation_tag 4
-#define google_census_View_tag_key_tag 5
-#define google_census_Aggregation_count_tag 3
-
-#define google_census_Aggregation_distribution_tag 4
-
-#define google_census_Aggregation_interval_stats_tag 5
-#define google_census_Aggregation_name_tag 1
-#define google_census_Aggregation_description_tag 2
-#define google_census_Aggregation_tag_tag 6
-
-/* Struct field encoding specification for nanopb */
-extern const pb_field_t google_census_Duration_fields[3];
-extern const pb_field_t google_census_Timestamp_fields[3];
-extern const pb_field_t google_census_Resource_fields[4];
-extern const pb_field_t google_census_Resource_MeasurementUnit_fields[4];
-extern const pb_field_t google_census_AggregationDescriptor_fields[4];
-extern const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2];
-extern const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2];
-extern const pb_field_t google_census_Distribution_fields[5];
-extern const pb_field_t google_census_Distribution_Range_fields[3];
-extern const pb_field_t google_census_IntervalStats_fields[2];
-extern const pb_field_t google_census_IntervalStats_Window_fields[4];
-extern const pb_field_t google_census_Tag_fields[3];
-extern const pb_field_t google_census_View_fields[6];
-extern const pb_field_t google_census_Aggregation_fields[7];
-extern const pb_field_t google_census_Metric_fields[5];
-
-/* Maximum encoded size of messages (where known) */
-#define google_census_Duration_size 22
-#define google_census_Timestamp_size 22
-#define google_census_Distribution_Range_size 18
-#define google_census_IntervalStats_Window_size 44
-#define google_census_Tag_size 516
-
-/* Message IDs (where set with "msgid" option) */
-#ifdef PB_MSGID
-
-#define CENSUS_MESSAGES \
-
-
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_GEN_CENSUS_PB_H */
diff --git a/src/core/ext/census/gen/trace_context.pb.c b/src/core/ext/census/gen/trace_context.pb.c
deleted file mode 100644
index b5c3d52..0000000
--- a/src/core/ext/census/gen/trace_context.pb.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-/* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.3.7-dev at Fri Jan 20 16:14:22 2017. */
-
-#include "src/core/ext/census/gen/trace_context.pb.h"
-
-/* @@protoc_insertion_point(includes) */
-#if PB_PROTO_HEADER_VERSION != 30
-#error Regenerate this file with the current version of nanopb generator.
-#endif
-
-
-
-const pb_field_t google_trace_TraceContext_fields[5] = {
- PB_FIELD( 1, FIXED64 , OPTIONAL, STATIC , FIRST, google_trace_TraceContext, trace_id_hi, trace_id_hi, 0),
- PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, trace_id_lo, trace_id_hi, 0),
- PB_FIELD( 3, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, span_id, trace_id_lo, 0),
- PB_FIELD( 4, FIXED32 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, span_options, span_id, 0),
- PB_LAST_FIELD
-};
-
-
-/* @@protoc_insertion_point(eof) */
diff --git a/src/core/ext/census/gen/trace_context.pb.h b/src/core/ext/census/gen/trace_context.pb.h
deleted file mode 100644
index 181925d..0000000
--- a/src/core/ext/census/gen/trace_context.pb.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-/* Automatically generated nanopb header */
-/* Generated by nanopb-0.3.7-dev at Fri Jan 20 16:14:22 2017. */
-
-#ifndef GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
-#define GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
-#include "third_party/nanopb/pb.h"
-
-/* @@protoc_insertion_point(includes) */
-#if PB_PROTO_HEADER_VERSION != 30
-#error Regenerate this file with the current version of nanopb generator.
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Struct definitions */
-typedef struct _google_trace_TraceContext {
- bool has_trace_id_hi;
- uint64_t trace_id_hi;
- bool has_trace_id_lo;
- uint64_t trace_id_lo;
- bool has_span_id;
- uint64_t span_id;
- bool has_span_options;
- uint32_t span_options;
-/* @@protoc_insertion_point(struct:google_trace_TraceContext) */
-} google_trace_TraceContext;
-
-/* Default values for struct fields */
-
-/* Initializer values for message structs */
-#define google_trace_TraceContext_init_default {false, 0, false, 0, false, 0, false, 0}
-#define google_trace_TraceContext_init_zero {false, 0, false, 0, false, 0, false, 0}
-
-/* Field tags (for use in manual encoding/decoding) */
-#define google_trace_TraceContext_trace_id_hi_tag 1
-#define google_trace_TraceContext_trace_id_lo_tag 2
-#define google_trace_TraceContext_span_id_tag 3
-#define google_trace_TraceContext_span_options_tag 4
-
-/* Struct field encoding specification for nanopb */
-extern const pb_field_t google_trace_TraceContext_fields[5];
-
-/* Maximum encoded size of messages (where known) */
-#define google_trace_TraceContext_size 32
-
-/* Message IDs (where set with "msgid" option) */
-#ifdef PB_MSGID
-
-#define TRACE_CONTEXT_MESSAGES \
-
-
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-/* @@protoc_insertion_point(eof) */
-
-#endif /* GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H */
diff --git a/src/core/ext/census/grpc_context.cc b/src/core/ext/census/grpc_context.cc
index 0bfba63..34eafca 100644
--- a/src/core/ext/census/grpc_context.cc
+++ b/src/core/ext/census/grpc_context.cc
@@ -24,9 +24,6 @@
void grpc_census_call_set_context(grpc_call *call, census_context *context) {
GRPC_API_TRACE("grpc_census_call_set_context(call=%p, census_context=%p)", 2,
(call, context));
- if (census_enabled() == CENSUS_FEATURE_NONE) {
- return;
- }
if (context != NULL) {
grpc_call_context_set(call, GRPC_CONTEXT_TRACING, context, NULL);
}
diff --git a/src/core/ext/census/grpc_filter.cc b/src/core/ext/census/grpc_filter.cc
deleted file mode 100644
index b37ab90..0000000
--- a/src/core/ext/census/grpc_filter.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/grpc_filter.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/census.h>
-#include <grpc/slice.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/time.h>
-
-#include "src/core/ext/census/census_interface.h"
-#include "src/core/ext/census/census_rpc_stats.h"
-#include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/transport/static_metadata.h"
-
-typedef struct call_data {
- census_op_id op_id;
- census_context *ctxt;
- gpr_timespec start_ts;
- int error;
-
- /* recv callback */
- grpc_metadata_batch *recv_initial_metadata;
- grpc_closure *on_done_recv;
- grpc_closure finish_recv;
-} call_data;
-
-typedef struct channel_data { uint8_t unused; } channel_data;
-
-static void extract_and_annotate_method_tag(grpc_metadata_batch *md,
- call_data *calld,
- channel_data *chand) {
- grpc_linked_mdelem *m;
- for (m = md->list.head; m != NULL; m = m->next) {
- if (grpc_slice_eq(GRPC_MDKEY(m->md), GRPC_MDSTR_PATH)) {
- /* Add method tag here */
- }
- }
-}
-
-static void client_mutate_op(grpc_call_element *elem,
- grpc_transport_stream_op_batch *op) {
- call_data *calld = (call_data *)elem->call_data;
- channel_data *chand = (channel_data *)elem->channel_data;
- if (op->send_initial_metadata) {
- extract_and_annotate_method_tag(
- op->payload->send_initial_metadata.send_initial_metadata, calld, chand);
- }
-}
-
-static void client_start_transport_op(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- grpc_transport_stream_op_batch *op) {
- client_mutate_op(elem, op);
- grpc_call_next_op(exec_ctx, elem, op);
-}
-
-static void server_on_done_recv(grpc_exec_ctx *exec_ctx, void *ptr,
- grpc_error *error) {
- GPR_TIMER_BEGIN("census-server:server_on_done_recv", 0);
- grpc_call_element *elem = (grpc_call_element *)ptr;
- call_data *calld = (call_data *)elem->call_data;
- channel_data *chand = (channel_data *)elem->channel_data;
- if (error == GRPC_ERROR_NONE) {
- extract_and_annotate_method_tag(calld->recv_initial_metadata, calld, chand);
- }
- calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error);
- GPR_TIMER_END("census-server:server_on_done_recv", 0);
-}
-
-static void server_mutate_op(grpc_call_element *elem,
- grpc_transport_stream_op_batch *op) {
- call_data *calld = (call_data *)elem->call_data;
- if (op->recv_initial_metadata) {
- /* substitute our callback for the op callback */
- calld->recv_initial_metadata =
- op->payload->recv_initial_metadata.recv_initial_metadata;
- calld->on_done_recv =
- op->payload->recv_initial_metadata.recv_initial_metadata_ready;
- op->payload->recv_initial_metadata.recv_initial_metadata_ready =
- &calld->finish_recv;
- }
-}
-
-static void server_start_transport_op(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- grpc_transport_stream_op_batch *op) {
- /* TODO(ctiller): this code fails. I don't know why. I expect it's
- incomplete, and someone should look at it soon.
-
- call_data *calld = elem->call_data;
- GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); */
- server_mutate_op(elem, op);
- grpc_call_next_op(exec_ctx, elem, op);
-}
-
-static grpc_error *client_init_call_elem(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- const grpc_call_element_args *args) {
- call_data *d = (call_data *)elem->call_data;
- GPR_ASSERT(d != NULL);
- memset(d, 0, sizeof(*d));
- d->start_ts = args->start_time;
- return GRPC_ERROR_NONE;
-}
-
-static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- const grpc_call_final_info *final_info,
- grpc_closure *ignored) {
- call_data *d = (call_data *)elem->call_data;
- GPR_ASSERT(d != NULL);
- /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */
-}
-
-static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- const grpc_call_element_args *args) {
- call_data *d = (call_data *)elem->call_data;
- GPR_ASSERT(d != NULL);
- memset(d, 0, sizeof(*d));
- d->start_ts = args->start_time;
- /* TODO(hongyu): call census_tracing_start_op here. */
- GRPC_CLOSURE_INIT(&d->finish_recv, server_on_done_recv, elem,
- grpc_schedule_on_exec_ctx);
- return GRPC_ERROR_NONE;
-}
-
-static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- const grpc_call_final_info *final_info,
- grpc_closure *ignored) {
- call_data *d = (call_data *)elem->call_data;
- GPR_ASSERT(d != NULL);
- /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
-}
-
-static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
- channel_data *chand = (channel_data *)elem->channel_data;
- GPR_ASSERT(chand != NULL);
- return GRPC_ERROR_NONE;
-}
-
-static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem) {
- channel_data *chand = (channel_data *)elem->channel_data;
- GPR_ASSERT(chand != NULL);
-}
-
-const grpc_channel_filter grpc_client_census_filter = {
- client_start_transport_op,
- grpc_channel_next_op,
- sizeof(call_data),
- client_init_call_elem,
- grpc_call_stack_ignore_set_pollset_or_pollset_set,
- client_destroy_call_elem,
- sizeof(channel_data),
- init_channel_elem,
- destroy_channel_elem,
- grpc_channel_next_get_info,
- "census-client"};
-
-const grpc_channel_filter grpc_server_census_filter = {
- server_start_transport_op,
- grpc_channel_next_op,
- sizeof(call_data),
- server_init_call_elem,
- grpc_call_stack_ignore_set_pollset_or_pollset_set,
- server_destroy_call_elem,
- sizeof(channel_data),
- init_channel_elem,
- destroy_channel_elem,
- grpc_channel_next_get_info,
- "census-server"};
diff --git a/src/core/ext/census/grpc_filter.h b/src/core/ext/census/grpc_filter.h
deleted file mode 100644
index 7940363..0000000
--- a/src/core/ext/census/grpc_filter.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_GRPC_FILTER_H
-#define GRPC_CORE_EXT_CENSUS_GRPC_FILTER_H
-
-#include "src/core/lib/channel/channel_stack.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Census filters: provides tracing and stats collection functionalities. It
- needs to reside right below the surface filter in the channel stack. */
-extern const grpc_channel_filter grpc_client_census_filter;
-extern const grpc_channel_filter grpc_server_census_filter;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_GRPC_FILTER_H */
diff --git a/src/core/ext/census/grpc_plugin.cc b/src/core/ext/census/grpc_plugin.cc
deleted file mode 100644
index 22b16c6..0000000
--- a/src/core/ext/census/grpc_plugin.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include <limits.h>
-#include <string.h>
-
-#include <grpc/census.h>
-
-#include "src/core/ext/census/grpc_filter.h"
-#include "src/core/lib/channel/channel_stack_builder.h"
-#include "src/core/lib/surface/channel_init.h"
-
-static bool is_census_enabled(const grpc_channel_args *a) {
- size_t i;
- if (a == NULL) return 0;
- for (i = 0; i < a->num_args; i++) {
- if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_CENSUS)) {
- return a->args[i].value.integer != 0 && census_enabled();
- }
- }
- return census_enabled() && !grpc_channel_args_want_minimal_stack(a);
-}
-
-static bool maybe_add_census_filter(grpc_exec_ctx *exec_ctx,
- grpc_channel_stack_builder *builder,
- void *arg) {
- const grpc_channel_args *args =
- grpc_channel_stack_builder_get_channel_arguments(builder);
- if (is_census_enabled(args)) {
- return grpc_channel_stack_builder_prepend_filter(
- builder, (const grpc_channel_filter *)arg, NULL, NULL);
- }
- return true;
-}
-
-extern "C" void census_grpc_plugin_init(void) {
- /* Only initialize census if no one else has and some features are
- * available. */
- if (census_enabled() == CENSUS_FEATURE_NONE &&
- census_supported() != CENSUS_FEATURE_NONE) {
- if (census_initialize(census_supported())) { /* enable all features. */
- gpr_log(GPR_ERROR, "Could not initialize census.");
- }
- }
- grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
- maybe_add_census_filter,
- (void *)&grpc_client_census_filter);
- grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
- maybe_add_census_filter,
- (void *)&grpc_server_census_filter);
-}
-
-extern "C" void census_grpc_plugin_shutdown(void) { census_shutdown(); }
diff --git a/src/core/ext/census/hash_table.cc b/src/core/ext/census/hash_table.cc
deleted file mode 100644
index 545b085..0000000
--- a/src/core/ext/census/hash_table.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/hash_table.h"
-
-#include <stddef.h>
-#include <stdio.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-
-#define CENSUS_HT_NUM_BUCKETS 1999
-
-/* A single hash table data entry */
-typedef struct ht_entry {
- census_ht_key key;
- void *data;
- struct ht_entry *next;
-} ht_entry;
-
-/* hash table bucket */
-typedef struct bucket {
- /* NULL if bucket is empty */
- ht_entry *next;
- /* -1 if all buckets are empty. */
- int32_t prev_non_empty_bucket;
- /* -1 if all buckets are empty. */
- int32_t next_non_empty_bucket;
-} bucket;
-
-struct unresizable_hash_table {
- /* Number of entries in the table */
- size_t size;
- /* Number of buckets */
- uint32_t num_buckets;
- /* Array of buckets initialized at creation time. Memory consumption is
- 16 bytes per bucket on a 64-bit platform. */
- bucket *buckets;
- /* Index of the first non-empty bucket. -1 iff size == 0. */
- int32_t first_non_empty_bucket;
- /* Index of the last non_empty bucket. -1 iff size == 0. */
- int32_t last_non_empty_bucket;
- /* Immutable options of this hash table, initialized at creation time. */
- census_ht_option options;
-};
-
-typedef struct entry_locator {
- int32_t bucket_idx;
- int is_first_in_chain;
- int found;
- ht_entry *prev_entry;
-} entry_locator;
-
-/* Asserts if option is not valid. */
-void check_options(const census_ht_option *option) {
- GPR_ASSERT(option != NULL);
- GPR_ASSERT(option->num_buckets > 0);
- GPR_ASSERT(option->key_type == CENSUS_HT_UINT64 ||
- option->key_type == CENSUS_HT_POINTER);
- if (option->key_type == CENSUS_HT_UINT64) {
- GPR_ASSERT(option->hash == NULL);
- } else if (option->key_type == CENSUS_HT_POINTER) {
- GPR_ASSERT(option->hash != NULL);
- GPR_ASSERT(option->compare_keys != NULL);
- }
-}
-
-#define REMOVE_NEXT(options, ptr) \
- do { \
- ht_entry *tmp = (ptr)->next; \
- (ptr)->next = tmp->next; \
- delete_entry(options, tmp); \
- } while (0)
-
-static void delete_entry(const census_ht_option *opt, ht_entry *p) {
- if (opt->delete_data != NULL) {
- opt->delete_data(p->data);
- }
- if (opt->delete_key != NULL) {
- opt->delete_key(p->key.ptr);
- }
- gpr_free(p);
-}
-
-static uint64_t hash(const census_ht_option *opt, census_ht_key key) {
- return opt->key_type == CENSUS_HT_UINT64 ? key.val : opt->hash(key.ptr);
-}
-
-census_ht *census_ht_create(const census_ht_option *option) {
- int i;
- census_ht *ret = NULL;
- check_options(option);
- ret = (census_ht *)gpr_malloc(sizeof(census_ht));
- ret->size = 0;
- ret->num_buckets = option->num_buckets;
- ret->buckets = (bucket *)gpr_malloc(sizeof(bucket) * ret->num_buckets);
- ret->options = *option;
- /* initialize each bucket */
- for (i = 0; i < ret->options.num_buckets; i++) {
- ret->buckets[i].prev_non_empty_bucket = -1;
- ret->buckets[i].next_non_empty_bucket = -1;
- ret->buckets[i].next = NULL;
- }
- return ret;
-}
-
-static int32_t find_bucket_idx(const census_ht *ht, census_ht_key key) {
- return hash(&ht->options, key) % ht->num_buckets;
-}
-
-static int keys_match(const census_ht_option *opt, const ht_entry *p,
- const census_ht_key key) {
- GPR_ASSERT(opt->key_type == CENSUS_HT_UINT64 ||
- opt->key_type == CENSUS_HT_POINTER);
- if (opt->key_type == CENSUS_HT_UINT64) return p->key.val == key.val;
- return !opt->compare_keys((p->key).ptr, key.ptr);
-}
-
-static entry_locator ht_find(const census_ht *ht, census_ht_key key) {
- entry_locator loc = {0, 0, 0, NULL};
- int32_t idx = 0;
- ht_entry *ptr = NULL;
- GPR_ASSERT(ht != NULL);
- idx = find_bucket_idx(ht, key);
- ptr = ht->buckets[idx].next;
- if (ptr == NULL) {
- /* bucket is empty */
- return loc;
- }
- if (keys_match(&ht->options, ptr, key)) {
- loc.bucket_idx = idx;
- loc.is_first_in_chain = 1;
- loc.found = 1;
- return loc;
- } else {
- for (; ptr->next != NULL; ptr = ptr->next) {
- if (keys_match(&ht->options, ptr->next, key)) {
- loc.bucket_idx = idx;
- loc.is_first_in_chain = 0;
- loc.found = 1;
- loc.prev_entry = ptr;
- return loc;
- }
- }
- }
- /* Could not find the key */
- return loc;
-}
-
-void *census_ht_find(const census_ht *ht, census_ht_key key) {
- entry_locator loc = ht_find(ht, key);
- if (loc.found == 0) {
- return NULL;
- }
- return loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next->data
- : loc.prev_entry->next->data;
-}
-
-void census_ht_insert(census_ht *ht, census_ht_key key, void *data) {
- int32_t idx = find_bucket_idx(ht, key);
- ht_entry *ptr = NULL;
- entry_locator loc = ht_find(ht, key);
- if (loc.found) {
- /* Replace old value with new value. */
- ptr = loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next
- : loc.prev_entry->next;
- if (ht->options.delete_data != NULL) {
- ht->options.delete_data(ptr->data);
- }
- ptr->data = data;
- return;
- }
-
- /* first entry in the table. */
- if (ht->size == 0) {
- ht->buckets[idx].next_non_empty_bucket = -1;
- ht->buckets[idx].prev_non_empty_bucket = -1;
- ht->first_non_empty_bucket = idx;
- ht->last_non_empty_bucket = idx;
- } else if (ht->buckets[idx].next == NULL) {
- /* first entry in the bucket. */
- ht->buckets[ht->last_non_empty_bucket].next_non_empty_bucket = idx;
- ht->buckets[idx].prev_non_empty_bucket = ht->last_non_empty_bucket;
- ht->buckets[idx].next_non_empty_bucket = -1;
- ht->last_non_empty_bucket = idx;
- }
- ptr = (ht_entry *)gpr_malloc(sizeof(ht_entry));
- ptr->key = key;
- ptr->data = data;
- ptr->next = ht->buckets[idx].next;
- ht->buckets[idx].next = ptr;
- ht->size++;
-}
-
-void census_ht_erase(census_ht *ht, census_ht_key key) {
- entry_locator loc = ht_find(ht, key);
- if (loc.found == 0) {
- /* noop if not found */
- return;
- }
- ht->size--;
- if (loc.is_first_in_chain) {
- bucket *b = &ht->buckets[loc.bucket_idx];
- GPR_ASSERT(b->next != NULL);
- /* The only entry in the bucket */
- if (b->next->next == NULL) {
- int prev = b->prev_non_empty_bucket;
- int next = b->next_non_empty_bucket;
- if (prev != -1) {
- ht->buckets[prev].next_non_empty_bucket = next;
- } else {
- ht->first_non_empty_bucket = next;
- }
- if (next != -1) {
- ht->buckets[next].prev_non_empty_bucket = prev;
- } else {
- ht->last_non_empty_bucket = prev;
- }
- }
- REMOVE_NEXT(&ht->options, b);
- } else {
- GPR_ASSERT(loc.prev_entry->next != NULL);
- REMOVE_NEXT(&ht->options, loc.prev_entry);
- }
-}
-
-/* Returns NULL if input table is empty. */
-census_ht_kv *census_ht_get_all_elements(const census_ht *ht, size_t *num) {
- census_ht_kv *ret = NULL;
- int i = 0;
- int32_t idx = -1;
- GPR_ASSERT(ht != NULL && num != NULL);
- *num = ht->size;
- if (*num == 0) {
- return NULL;
- }
-
- ret = (census_ht_kv *)gpr_malloc(sizeof(census_ht_kv) * ht->size);
- idx = ht->first_non_empty_bucket;
- while (idx >= 0) {
- ht_entry *ptr = ht->buckets[idx].next;
- for (; ptr != NULL; ptr = ptr->next) {
- ret[i].k = ptr->key;
- ret[i].v = ptr->data;
- i++;
- }
- idx = ht->buckets[idx].next_non_empty_bucket;
- }
- return ret;
-}
-
-static void ht_delete_entry_chain(const census_ht_option *options,
- ht_entry *first) {
- if (first == NULL) {
- return;
- }
- if (first->next != NULL) {
- ht_delete_entry_chain(options, first->next);
- }
- delete_entry(options, first);
-}
-
-void census_ht_destroy(census_ht *ht) {
- unsigned i;
- for (i = 0; i < ht->num_buckets; ++i) {
- ht_delete_entry_chain(&ht->options, ht->buckets[i].next);
- }
- gpr_free(ht->buckets);
- gpr_free(ht);
-}
-
-size_t census_ht_get_size(const census_ht *ht) { return ht->size; }
diff --git a/src/core/ext/census/hash_table.h b/src/core/ext/census/hash_table.h
deleted file mode 100644
index c3ed94e..0000000
--- a/src/core/ext/census/hash_table.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_HASH_TABLE_H
-#define GRPC_CORE_EXT_CENSUS_HASH_TABLE_H
-
-#include <stddef.h>
-
-#include <grpc/support/port_platform.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* A chain based hash table with fixed number of buckets.
- Your probably shouldn't use this code directly. It is implemented for the
- use case in census trace store and stats store, where number of entries in
- the table is in the scale of upto several thousands, entries are added and
- removed from the table very frequently (~100k/s), the frequency of find()
- operations is roughly several times of the frequency of insert() and erase()
- Comparing to find(), the insert(), erase() and get_all_entries() operations
- are much less freqent (<1/s).
-
- Per bucket memory overhead is about (8 + sizeof(intptr_t) bytes.
- Per entry memory overhead is about (8 + 2 * sizeof(intptr_t) bytes.
-
- All functions are not thread-safe. Synchronization will be provided in the
- upper layer (in trace store and stats store).
-*/
-
-/* Opaque hash table struct */
-typedef struct unresizable_hash_table census_ht;
-
-/* Currently, the hash_table can take two types of keys. (uint64 for trace
- store and const char* for stats store). */
-typedef union {
- uint64_t val;
- void *ptr;
-} census_ht_key;
-
-typedef enum census_ht_key_type {
- CENSUS_HT_UINT64 = 0,
- CENSUS_HT_POINTER = 1
-} census_ht_key_type;
-
-typedef struct census_ht_option {
- /* Type of hash key */
- census_ht_key_type key_type;
- /* Desired number of buckets, preferably a prime number */
- int32_t num_buckets;
- /* Fucntion to calculate uint64 hash value of the key. Only takes effect if
- key_type is POINTER. */
- uint64_t (*hash)(const void *);
- /* Function to compare two keys, returns 0 iff equal. Only takes effect if
- key_type is POINTER */
- int (*compare_keys)(const void *k1, const void *k2);
- /* Value deleter. NULL if no specialized delete function is needed. */
- void (*delete_data)(void *);
- /* Key deleter. NULL if table does not own the key. (e.g. key is part of the
- value or key is not owned by the table.) */
- void (*delete_key)(void *);
-} census_ht_option;
-
-/* Creates a hashtable with fixed number of buckets according to the settings
- specified in 'options' arg. Function pointers "hash" and "compare_keys" must
- be provided if key_type is POINTER. Asserts if fail to create. */
-census_ht *census_ht_create(const census_ht_option *options);
-
-/* Deletes hash table instance. Frees all dynamic memory owned by ht.*/
-void census_ht_destroy(census_ht *ht);
-
-/* Inserts the input key-val pair into hash_table. If an entry with the same key
- exists in the table, the corresponding value will be overwritten by the input
- val. */
-void census_ht_insert(census_ht *ht, census_ht_key key, void *val);
-
-/* Returns pointer to data, returns NULL if not found. */
-void *census_ht_find(const census_ht *ht, census_ht_key key);
-
-/* Erase hash table entry with input key. Noop if key is not found. */
-void census_ht_erase(census_ht *ht, census_ht_key key);
-
-typedef struct census_ht_kv {
- census_ht_key k;
- void *v;
-} census_ht_kv;
-
-/* Returns an array of pointers to all values in the hash table. Order of the
- elements can be arbitrary. Sets 'num' to the size of returned array. Caller
- owns returned array. */
-census_ht_kv *census_ht_get_all_elements(const census_ht *ht, size_t *num);
-
-/* Returns number of elements kept. */
-size_t census_ht_get_size(const census_ht *ht);
-
-/* Functor applied on each key-value pair while iterating through entries in the
- table. The functor should not mutate data. */
-typedef void (*census_ht_itr_cb)(census_ht_key key, const void *val_ptr,
- void *state);
-
-/* Iterates through all key-value pairs in the hash_table. The callback function
- should not invalidate data entries. */
-uint64_t census_ht_for_all(const census_ht *ht, census_ht_itr_cb);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_HASH_TABLE_H */
diff --git a/src/core/ext/census/initialize.cc b/src/core/ext/census/initialize.cc
deleted file mode 100644
index 165a122..0000000
--- a/src/core/ext/census/initialize.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/census.h>
-#include "src/core/ext/census/base_resources.h"
-#include "src/core/ext/census/resource.h"
-
-static int features_enabled = CENSUS_FEATURE_NONE;
-
-int census_initialize(int features) {
- if (features_enabled != CENSUS_FEATURE_NONE) {
- // Must have been a previous call to census_initialize; return error
- return -1;
- }
- features_enabled = features & CENSUS_FEATURE_ALL;
- if (features & CENSUS_FEATURE_STATS) {
- initialize_resources();
- define_base_resources();
- }
-
- return features_enabled;
-}
-
-void census_shutdown(void) {
- if (features_enabled & CENSUS_FEATURE_STATS) {
- shutdown_resources();
- }
- features_enabled = CENSUS_FEATURE_NONE;
-}
-
-int census_supported(void) {
- /* TODO(aveitch): improve this as we implement features... */
- return CENSUS_FEATURE_NONE;
-}
-
-int census_enabled(void) { return features_enabled; }
diff --git a/src/core/ext/census/intrusive_hash_map.cc b/src/core/ext/census/intrusive_hash_map.cc
deleted file mode 100644
index 7930486..0000000
--- a/src/core/ext/census/intrusive_hash_map.cc
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/intrusive_hash_map.h"
-#include <string.h>
-
-extern bool hm_index_compare(const hm_index *A, const hm_index *B);
-
-/* Simple hashing function that takes lower 32 bits. */
-static __inline uint32_t chunked_vector_hasher(uint64_t key) {
- return (uint32_t)key;
-}
-
-/* Vector chunks are 1MiB divided by pointer size. */
-static const size_t VECTOR_CHUNK_SIZE = (1 << 20) / sizeof(void *);
-
-/* Helper functions which return buckets from the chunked vector. */
-static __inline void **get_mutable_bucket(const chunked_vector *buckets,
- uint32_t index) {
- if (index < VECTOR_CHUNK_SIZE) {
- return &buckets->first_[index];
- }
- size_t rest_index = (index - VECTOR_CHUNK_SIZE) / VECTOR_CHUNK_SIZE;
- return &buckets->rest_[rest_index][index % VECTOR_CHUNK_SIZE];
-}
-
-static __inline void *get_bucket(const chunked_vector *buckets,
- uint32_t index) {
- if (index < VECTOR_CHUNK_SIZE) {
- return buckets->first_[index];
- }
- size_t rest_index = (index - VECTOR_CHUNK_SIZE) / VECTOR_CHUNK_SIZE;
- return buckets->rest_[rest_index][index % VECTOR_CHUNK_SIZE];
-}
-
-/* Helper function. */
-static __inline size_t RestSize(const chunked_vector *vec) {
- return (vec->size_ <= VECTOR_CHUNK_SIZE)
- ? 0
- : (vec->size_ - VECTOR_CHUNK_SIZE - 1) / VECTOR_CHUNK_SIZE + 1;
-}
-
-/* Initialize chunked vector to size of 0. */
-static void chunked_vector_init(chunked_vector *vec) {
- vec->size_ = 0;
- vec->first_ = NULL;
- vec->rest_ = NULL;
-}
-
-/* Clear chunked vector and free all memory that has been allocated then
- initialize chunked vector. */
-static void chunked_vector_clear(chunked_vector *vec) {
- if (vec->first_ != NULL) {
- gpr_free(vec->first_);
- }
- if (vec->rest_ != NULL) {
- size_t rest_size = RestSize(vec);
- for (size_t i = 0; i < rest_size; ++i) {
- if (vec->rest_[i] != NULL) {
- gpr_free(vec->rest_[i]);
- }
- }
- gpr_free(vec->rest_);
- }
- chunked_vector_init(vec);
-}
-
-/* Clear chunked vector and then resize it to n entries. Allow the first 1MB to
- be read w/o an extra cache miss. The rest of the elements are stored in an
- array of arrays to avoid large mallocs. */
-static void chunked_vector_reset(chunked_vector *vec, size_t n) {
- chunked_vector_clear(vec);
- vec->size_ = n;
- if (n <= VECTOR_CHUNK_SIZE) {
- vec->first_ = (void **)gpr_malloc(sizeof(void *) * n);
- memset(vec->first_, 0, sizeof(void *) * n);
- } else {
- vec->first_ = (void **)gpr_malloc(sizeof(void *) * VECTOR_CHUNK_SIZE);
- memset(vec->first_, 0, sizeof(void *) * VECTOR_CHUNK_SIZE);
- size_t rest_size = RestSize(vec);
- vec->rest_ = (void ***)gpr_malloc(sizeof(void **) * rest_size);
- memset(vec->rest_, 0, sizeof(void **) * rest_size);
- int i = 0;
- n -= VECTOR_CHUNK_SIZE;
- while (n > 0) {
- size_t this_size = GPR_MIN(n, VECTOR_CHUNK_SIZE);
- vec->rest_[i] = (void **)gpr_malloc(sizeof(void *) * this_size);
- memset(vec->rest_[i], 0, sizeof(void *) * this_size);
- n -= this_size;
- ++i;
- }
- }
-}
-
-void intrusive_hash_map_init(intrusive_hash_map *hash_map,
- uint32_t initial_log2_table_size) {
- hash_map->log2_num_buckets = initial_log2_table_size;
- hash_map->num_items = 0;
- uint32_t num_buckets = (uint32_t)1 << hash_map->log2_num_buckets;
- hash_map->extend_threshold = num_buckets >> 1;
- chunked_vector_init(&hash_map->buckets);
- chunked_vector_reset(&hash_map->buckets, num_buckets);
- hash_map->hash_mask = num_buckets - 1;
-}
-
-bool intrusive_hash_map_empty(const intrusive_hash_map *hash_map) {
- return hash_map->num_items == 0;
-}
-
-size_t intrusive_hash_map_size(const intrusive_hash_map *hash_map) {
- return hash_map->num_items;
-}
-
-void intrusive_hash_map_end(const intrusive_hash_map *hash_map, hm_index *idx) {
- idx->bucket_index = (uint32_t)hash_map->buckets.size_;
- GPR_ASSERT(idx->bucket_index <= UINT32_MAX);
- idx->item = NULL;
-}
-
-void intrusive_hash_map_next(const intrusive_hash_map *hash_map,
- hm_index *idx) {
- idx->item = idx->item->hash_link;
- while (idx->item == NULL) {
- idx->bucket_index++;
- if (idx->bucket_index >= hash_map->buckets.size_) {
- /* Reached end of table. */
- idx->item = NULL;
- return;
- }
- idx->item = (hm_item *)get_bucket(&hash_map->buckets, idx->bucket_index);
- }
-}
-
-void intrusive_hash_map_begin(const intrusive_hash_map *hash_map,
- hm_index *idx) {
- for (uint32_t i = 0; i < hash_map->buckets.size_; ++i) {
- if (get_bucket(&hash_map->buckets, i) != NULL) {
- idx->bucket_index = i;
- idx->item = (hm_item *)get_bucket(&hash_map->buckets, i);
- return;
- }
- }
- intrusive_hash_map_end(hash_map, idx);
-}
-
-hm_item *intrusive_hash_map_find(const intrusive_hash_map *hash_map,
- uint64_t key) {
- uint32_t index = chunked_vector_hasher(key) & hash_map->hash_mask;
-
- hm_item *p = (hm_item *)get_bucket(&hash_map->buckets, index);
- while (p != NULL) {
- if (key == p->key) {
- return p;
- }
- p = p->hash_link;
- }
- return NULL;
-}
-
-hm_item *intrusive_hash_map_erase(intrusive_hash_map *hash_map, uint64_t key) {
- uint32_t index = chunked_vector_hasher(key) & hash_map->hash_mask;
-
- hm_item **slot = (hm_item **)get_mutable_bucket(&hash_map->buckets, index);
- hm_item *p = *slot;
- if (p == NULL) {
- return NULL;
- }
-
- if (key == p->key) {
- *slot = p->hash_link;
- p->hash_link = NULL;
- hash_map->num_items--;
- return p;
- }
-
- hm_item *prev = p;
- p = p->hash_link;
-
- while (p) {
- if (key == p->key) {
- prev->hash_link = p->hash_link;
- p->hash_link = NULL;
- hash_map->num_items--;
- return p;
- }
- prev = p;
- p = p->hash_link;
- }
- return NULL;
-}
-
-/* Insert an hm_item* into the underlying chunked vector. hash_mask is
- * array_size-1. Returns true if it is a new hm_item and false if the hm_item
- * already existed.
- */
-static __inline bool intrusive_hash_map_internal_insert(chunked_vector *buckets,
- uint32_t hash_mask,
- hm_item *item) {
- const uint64_t key = item->key;
- uint32_t index = chunked_vector_hasher(key) & hash_mask;
- hm_item **slot = (hm_item **)get_mutable_bucket(buckets, index);
- hm_item *p = *slot;
- item->hash_link = p;
-
- /* Check to see if key already exists. */
- while (p) {
- if (p->key == key) {
- return false;
- }
- p = p->hash_link;
- }
-
- /* Otherwise add new entry. */
- *slot = item;
- return true;
-}
-
-/* Extend the allocated number of elements in the hash map by a factor of 2. */
-void intrusive_hash_map_extend(intrusive_hash_map *hash_map) {
- uint32_t new_log2_num_buckets = 1 + hash_map->log2_num_buckets;
- uint32_t new_num_buckets = (uint32_t)1 << new_log2_num_buckets;
- GPR_ASSERT(new_num_buckets <= UINT32_MAX && new_num_buckets > 0);
- chunked_vector new_buckets;
- chunked_vector_init(&new_buckets);
- chunked_vector_reset(&new_buckets, new_num_buckets);
- uint32_t new_hash_mask = new_num_buckets - 1;
-
- hm_index cur_idx;
- hm_index end_idx;
- intrusive_hash_map_end(hash_map, &end_idx);
- intrusive_hash_map_begin(hash_map, &cur_idx);
- while (!hm_index_compare(&cur_idx, &end_idx)) {
- hm_item *new_item = cur_idx.item;
- intrusive_hash_map_next(hash_map, &cur_idx);
- intrusive_hash_map_internal_insert(&new_buckets, new_hash_mask, new_item);
- }
-
- /* Set values for new chunked_vector. extend_threshold is set to half of
- * new_num_buckets. */
- hash_map->log2_num_buckets = new_log2_num_buckets;
- chunked_vector_clear(&hash_map->buckets);
- hash_map->buckets = new_buckets;
- hash_map->hash_mask = new_hash_mask;
- hash_map->extend_threshold = new_num_buckets >> 1;
-}
-
-/* Insert a hm_item. The hm_item must remain live until it is removed from the
- table. This object does not take the ownership of hm_item. The caller must
- remove this hm_item from the table and delete it before this table is
- deleted. If hm_item exists already num_items is not changed. */
-bool intrusive_hash_map_insert(intrusive_hash_map *hash_map, hm_item *item) {
- if (hash_map->num_items >= hash_map->extend_threshold) {
- intrusive_hash_map_extend(hash_map);
- }
- if (intrusive_hash_map_internal_insert(&hash_map->buckets,
- hash_map->hash_mask, item)) {
- hash_map->num_items++;
- return true;
- }
- return false;
-}
-
-void intrusive_hash_map_clear(intrusive_hash_map *hash_map,
- void (*free_object)(void *)) {
- hm_index cur;
- hm_index end;
- intrusive_hash_map_end(hash_map, &end);
- intrusive_hash_map_begin(hash_map, &cur);
-
- while (!hm_index_compare(&cur, &end)) {
- hm_index next = cur;
- intrusive_hash_map_next(hash_map, &next);
- if (cur.item != NULL) {
- hm_item *item = intrusive_hash_map_erase(hash_map, cur.item->key);
- (*free_object)((void *)item);
- gpr_free(item);
- }
- cur = next;
- }
-}
-
-void intrusive_hash_map_free(intrusive_hash_map *hash_map,
- void (*free_object)(void *)) {
- intrusive_hash_map_clear(hash_map, (*free_object));
- hash_map->num_items = 0;
- hash_map->extend_threshold = 0;
- hash_map->log2_num_buckets = 0;
- hash_map->hash_mask = 0;
- chunked_vector_clear(&hash_map->buckets);
-}
diff --git a/src/core/ext/census/intrusive_hash_map.h b/src/core/ext/census/intrusive_hash_map.h
deleted file mode 100644
index 2c7baa3..0000000
--- a/src/core/ext/census/intrusive_hash_map.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_H
-#define GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_H
-
-#include "src/core/ext/census/intrusive_hash_map_internal.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* intrusive_hash_map is a fast chained hash table. This hash map is faster than
- * a dense hash map when the application calls insert and erase more often than
- * find. When the workload is dominated by find() a dense hash map may be
- * faster.
- *
- * intrusive_hash_map uses an intrusive header placed within a user defined
- * struct. The header field IHM_key MUST be set to a valid value before
- * insertion into the hash map or undefined behavior may occur. The header field
- * IHM_hash_link MUST to be set to NULL initially.
- *
- * EXAMPLE USAGE:
- *
- * typedef struct string_item {
- * INTRUSIVE_HASH_MAP_HEADER;
- * // User data.
- * char *str_buf;
- * uint16_t len;
- * } string_item;
- *
- * static string_item *make_string_item(uint64_t key, const char *buf,
- * uint16_t len) {
- * string_item *item = (string_item *)gpr_malloc(sizeof(string_item));
- * item->IHM_key = key;
- * item->IHM_hash_link = NULL;
- * item->len = len;
- * item->str_buf = (char *)malloc(len);
- * memcpy(item->str_buf, buf, len);
- * return item;
- * }
- *
- * intrusive_hash_map hash_map;
- * intrusive_hash_map_init(&hash_map, 4);
- * string_item *new_item1 = make_string_item(10, "test1", 5);
- * bool ok = intrusive_hash_map_insert(&hash_map, (hm_item *)new_item1);
- *
- * string_item *item1 =
- * (string_item *)intrusive_hash_map_find(&hash_map, 10);
- */
-
-/* Hash map item. Stores key and a pointer to the actual object. A user defined
- * version of this can be passed in provided the first 2 entries (key and
- * hash_link) are the same. These entries must be first in the user defined
- * struct. Pointer to struct will need to be cast as (hm_item *) when passed to
- * hash map. This allows it to be intrusive. */
-typedef struct hm_item {
- uint64_t key;
- struct hm_item *hash_link;
- /* Optional user defined data after this. */
-} hm_item;
-
-/* Macro provided for ease of use. This must be first in the user defined
- * struct (i.e. uint64_t key and hm_item * must be the first two elements in
- * that order). */
-#define INTRUSIVE_HASH_MAP_HEADER \
- uint64_t IHM_key; \
- struct hm_item *IHM_hash_link
-
-/* Index struct which acts as a pseudo-iterator within the hash map. */
-typedef struct hm_index {
- uint32_t bucket_index; // hash map bucket index.
- hm_item *item; // Pointer to hm_item within the hash map.
-} hm_index;
-
-/* Returns true if two hm_indices point to the same object within the hash map
- * and false otherwise. */
-__inline bool hm_index_compare(const hm_index *A, const hm_index *B) {
- return (A->item == B->item && A->bucket_index == B->bucket_index);
-}
-
-/*
- * Helper functions for iterating over the hash map.
- */
-
-/* On return idx will contain an invalid index which is always equal to
- * hash_map->buckets.size_ */
-void intrusive_hash_map_end(const intrusive_hash_map *hash_map, hm_index *idx);
-
-/* Iterates index to the next valid entry in the hash map and stores the
- * index within idx. If end of table is reached, idx will contain the same
- * values as if intrusive_hash_map_end() was called. */
-void intrusive_hash_map_next(const intrusive_hash_map *hash_map, hm_index *idx);
-
-/* On return, idx will contain the index of the first non-null entry in the hash
- * map. If the hash map is empty, idx will contain the same values as if
- * intrusive_hash_map_end() was called. */
-void intrusive_hash_map_begin(const intrusive_hash_map *hash_map,
- hm_index *idx);
-
-/* Initialize intrusive hash map data structure. This must be called before
- * the hash map can be used. The initial size of an intrusive hash map will be
- * 2^initial_log2_map_size (valid range is [0, 31]). */
-void intrusive_hash_map_init(intrusive_hash_map *hash_map,
- uint32_t initial_log2_map_size);
-
-/* Returns true if the hash map is empty and false otherwise. */
-bool intrusive_hash_map_empty(const intrusive_hash_map *hash_map);
-
-/* Returns the number of elements currently in the hash map. */
-size_t intrusive_hash_map_size(const intrusive_hash_map *hash_map);
-
-/* Find a hm_item within the hash map by key. Returns NULL if item was not
- * found. */
-hm_item *intrusive_hash_map_find(const intrusive_hash_map *hash_map,
- uint64_t key);
-
-/* Erase the hm_item that corresponds with key. If the hm_item is found, return
- * the pointer to the hm_item. Else returns NULL. */
-hm_item *intrusive_hash_map_erase(intrusive_hash_map *hash_map, uint64_t key);
-
-/* Attempts to insert a new hm_item into the hash map. If an element with the
- * same key already exists, it will not insert the new item and return false.
- * Otherwise, it will insert the new item and return true. */
-bool intrusive_hash_map_insert(intrusive_hash_map *hash_map, hm_item *item);
-
-/* Clears entire contents of the hash map, but leaves internal data structure
- * untouched. Second argument takes a function pointer to a function that will
- * free the object designated by the user and pointed to by hash_map->value. */
-void intrusive_hash_map_clear(intrusive_hash_map *hash_map,
- void (*free_object)(void *));
-
-/* Erase all contents of hash map and free the memory. Hash map is invalid
- * after calling this function and cannot be used until it has been
- * reinitialized (intrusive_hash_map_init()). This function takes a function
- * pointer to a function that will free the object designated by the user and
- * pointed to by hash_map->value. */
-void intrusive_hash_map_free(intrusive_hash_map *hash_map,
- void (*free_object)(void *));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_H */
diff --git a/src/core/ext/census/intrusive_hash_map_internal.h b/src/core/ext/census/intrusive_hash_map_internal.h
deleted file mode 100644
index e9c81fc..0000000
--- a/src/core/ext/census/intrusive_hash_map_internal.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_INTERNAL_H
-#define GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_INTERNAL_H
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/useful.h>
-#include <stdbool.h>
-
-/* The chunked vector is a data structure that allocates buckets for use in the
- * hash map. ChunkedVector is logically equivalent to T*[N] (cast void* as
- * T*). It's internally implemented as an array of 1MB arrays to avoid
- * allocating large consecutive memory chunks. This is an internal data
- * structure that should never be accessed directly. */
-typedef struct chunked_vector {
- size_t size_;
- void **first_;
- void ***rest_;
-} chunked_vector;
-
-/* Core intrusive hash map data structure. All internal elements are managed by
- * functions and should not be altered manually. */
-typedef struct intrusive_hash_map {
- uint32_t num_items;
- uint32_t extend_threshold;
- uint32_t log2_num_buckets;
- uint32_t hash_mask;
- chunked_vector buckets;
-} intrusive_hash_map;
-
-#endif /* GRPC_CORE_EXT_CENSUS_INTRUSIVE_HASH_MAP_INTERNAL_H */
diff --git a/src/core/ext/census/mlog.cc b/src/core/ext/census/mlog.cc
deleted file mode 100644
index 4b8c846..0000000
--- a/src/core/ext/census/mlog.cc
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// Implements an efficient in-memory log, optimized for multiple writers and
-// a single reader. Available log space is divided up in blocks of
-// CENSUS_LOG_2_MAX_RECORD_SIZE bytes. A block can be in one of the following
-// three data structures:
-// - Free blocks (free_block_list)
-// - Blocks with unread data (dirty_block_list)
-// - Blocks currently attached to cores (core_local_blocks[])
-//
-// census_log_start_write() moves a block from core_local_blocks[] to the end of
-// dirty_block_list when block:
-// - is out-of-space OR
-// - has an incomplete record (an incomplete record occurs when a thread calls
-// census_log_start_write() and is context-switched before calling
-// census_log_end_write()
-// So, blocks in dirty_block_list are ordered, from oldest to newest, by the
-// time when block is detached from the core.
-//
-// census_log_read_next() first iterates over dirty_block_list and then
-// core_local_blocks[]. It moves completely read blocks from dirty_block_list
-// to free_block_list. Blocks in core_local_blocks[] are not freed, even when
-// completely read.
-//
-// If the log is configured to discard old records and free_block_list is empty,
-// census_log_start_write() iterates over dirty_block_list to allocate a
-// new block. It moves the oldest available block (no pending read/write) to
-// core_local_blocks[].
-//
-// core_local_block_struct is used to implement a map from core id to the block
-// associated with that core. This mapping is advisory. It is possible that the
-// block returned by this mapping is no longer associated with that core. This
-// mapping is updated, lazily, by census_log_start_write().
-//
-// Locking in block struct:
-//
-// Exclusive g_log.lock must be held before calling any functions operating on
-// block structs except census_log_start_write() and census_log_end_write().
-//
-// Writes to a block are serialized via writer_lock. census_log_start_write()
-// acquires this lock and census_log_end_write() releases it. On failure to
-// acquire the lock, writer allocates a new block for the current core and
-// updates core_local_block accordingly.
-//
-// Simultaneous read and write access is allowed. Readers can safely read up to
-// committed bytes (bytes_committed).
-//
-// reader_lock protects the block, currently being read, from getting recycled.
-// start_read() acquires reader_lock and end_read() releases the lock.
-//
-// Read/write access to a block is disabled via try_disable_access(). It returns
-// with both writer_lock and reader_lock held. These locks are subsequently
-// released by enable_access() to enable access to the block.
-//
-// A note on naming: Most function/struct names are prepended by cl_
-// (shorthand for census_log). Further, functions that manipulate structures
-// include the name of the structure, which will be passed as the first
-// argument. E.g. cl_block_initialize() will initialize a cl_block.
-
-#include "src/core/ext/census/mlog.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/atm.h>
-#include <grpc/support/cpu.h>
-#include <grpc/support/log.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/useful.h>
-#include <stdbool.h>
-#include <string.h>
-
-// End of platform specific code
-
-typedef struct census_log_block_list_struct {
- struct census_log_block_list_struct* next;
- struct census_log_block_list_struct* prev;
- struct census_log_block* block;
-} cl_block_list_struct;
-
-typedef struct census_log_block {
- // Pointer to underlying buffer.
- char* buffer;
- gpr_atm writer_lock;
- gpr_atm reader_lock;
- // Keeps completely written bytes. Declared atomic because accessed
- // simultaneously by reader and writer.
- gpr_atm bytes_committed;
- // Bytes already read.
- size_t bytes_read;
- // Links for list.
- cl_block_list_struct link;
-// We want this structure to be cacheline aligned. We assume the following
-// sizes for the various parts on 32/64bit systems:
-// type 32b size 64b size
-// char* 4 8
-// 3x gpr_atm 12 24
-// size_t 4 8
-// cl_block_list_struct 12 24
-// TOTAL 32 64
-//
-// Depending on the size of our cacheline and the architecture, we
-// selectively add char buffering to this structure. The size is checked
-// via assert in census_log_initialize().
-#if defined(GPR_ARCH_64)
-#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 64)
-#else
-#if defined(GPR_ARCH_32)
-#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 32)
-#else
-#error "Unknown architecture"
-#endif
-#endif
-#if CL_BLOCK_PAD_SIZE > 0
- char padding[CL_BLOCK_PAD_SIZE];
-#endif
-} cl_block;
-
-// A list of cl_blocks, doubly-linked through cl_block::link.
-typedef struct census_log_block_list {
- int32_t count; // Number of items in list.
- cl_block_list_struct ht; // head/tail of linked list.
-} cl_block_list;
-
-// Cacheline aligned block pointers to avoid false sharing. Block pointer must
-// be initialized via set_block(), before calling other functions
-typedef struct census_log_core_local_block {
- gpr_atm block;
-// Ensure cachline alignment: we assume sizeof(gpr_atm) == 4 or 8
-#if defined(GPR_ARCH_64)
-#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 8)
-#else
-#if defined(GPR_ARCH_32)
-#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 4)
-#else
-#error "Unknown architecture"
-#endif
-#endif
-#if CL_CORE_LOCAL_BLOCK_PAD_SIZE > 0
- char padding[CL_CORE_LOCAL_BLOCK_PAD_SIZE];
-#endif
-} cl_core_local_block;
-
-struct census_log {
- int discard_old_records;
- // Number of cores (aka hardware-contexts)
- unsigned num_cores;
- // number of CENSUS_LOG_2_MAX_RECORD_SIZE blocks in log
- uint32_t num_blocks;
- cl_block* blocks; // Block metadata.
- cl_core_local_block* core_local_blocks; // Keeps core to block mappings.
- gpr_mu lock;
- int initialized; // has log been initialized?
- // Keeps the state of the reader iterator. A value of 0 indicates that
- // iterator has reached the end. census_log_init_reader() resets the value
- // to num_core to restart iteration.
- uint32_t read_iterator_state;
- // Points to the block being read. If non-NULL, the block is locked for
- // reading(block_being_read_->reader_lock is held).
- cl_block* block_being_read;
- char* buffer;
- cl_block_list free_block_list;
- cl_block_list dirty_block_list;
- gpr_atm out_of_space_count;
-};
-
-// Single internal log.
-static struct census_log g_log;
-
-// Functions that operate on an atomic memory location used as a lock.
-
-// Returns non-zero if lock is acquired.
-static int cl_try_lock(gpr_atm* lock) { return gpr_atm_acq_cas(lock, 0, 1); }
-
-static void cl_unlock(gpr_atm* lock) { gpr_atm_rel_store(lock, 0); }
-
-// Functions that operate on cl_core_local_block's.
-
-static void cl_core_local_block_set_block(cl_core_local_block* clb,
- cl_block* block) {
- gpr_atm_rel_store(&clb->block, (gpr_atm)block);
-}
-
-static cl_block* cl_core_local_block_get_block(cl_core_local_block* clb) {
- return (cl_block*)gpr_atm_acq_load(&clb->block);
-}
-
-// Functions that operate on cl_block_list_struct's.
-
-static void cl_block_list_struct_initialize(cl_block_list_struct* bls,
- cl_block* block) {
- bls->next = bls->prev = bls;
- bls->block = block;
-}
-
-// Functions that operate on cl_block_list's.
-
-static void cl_block_list_initialize(cl_block_list* list) {
- list->count = 0;
- cl_block_list_struct_initialize(&list->ht, NULL);
-}
-
-// Returns head of *this, or NULL if empty.
-static cl_block* cl_block_list_head(cl_block_list* list) {
- return list->ht.next->block;
-}
-
-// Insert element *e after *pos.
-static void cl_block_list_insert(cl_block_list* list, cl_block_list_struct* pos,
- cl_block_list_struct* e) {
- list->count++;
- e->next = pos->next;
- e->prev = pos;
- e->next->prev = e;
- e->prev->next = e;
-}
-
-// Insert block at the head of the list
-static void cl_block_list_insert_at_head(cl_block_list* list, cl_block* block) {
- cl_block_list_insert(list, &list->ht, &block->link);
-}
-
-// Insert block at the tail of the list.
-static void cl_block_list_insert_at_tail(cl_block_list* list, cl_block* block) {
- cl_block_list_insert(list, list->ht.prev, &block->link);
-}
-
-// Removes block *b. Requires *b be in the list.
-static void cl_block_list_remove(cl_block_list* list, cl_block* b) {
- list->count--;
- b->link.next->prev = b->link.prev;
- b->link.prev->next = b->link.next;
-}
-
-// Functions that operate on cl_block's
-
-static void cl_block_initialize(cl_block* block, char* buffer) {
- block->buffer = buffer;
- gpr_atm_rel_store(&block->writer_lock, 0);
- gpr_atm_rel_store(&block->reader_lock, 0);
- gpr_atm_rel_store(&block->bytes_committed, 0);
- block->bytes_read = 0;
- cl_block_list_struct_initialize(&block->link, block);
-}
-
-// Guards against exposing partially written buffer to the reader.
-static void cl_block_set_bytes_committed(cl_block* block,
- size_t bytes_committed) {
- gpr_atm_rel_store(&block->bytes_committed, (gpr_atm)bytes_committed);
-}
-
-static size_t cl_block_get_bytes_committed(cl_block* block) {
- return (size_t)gpr_atm_acq_load(&block->bytes_committed);
-}
-
-// Tries to disable future read/write access to this block. Succeeds if:
-// - no in-progress write AND
-// - no in-progress read AND
-// - 'discard_data' set to true OR no unread data
-// On success, clears the block state and returns with writer_lock_ and
-// reader_lock_ held. These locks are released by a subsequent
-// cl_block_access_enable() call.
-static bool cl_block_try_disable_access(cl_block* block, int discard_data) {
- if (!cl_try_lock(&block->writer_lock)) {
- return false;
- }
- if (!cl_try_lock(&block->reader_lock)) {
- cl_unlock(&block->writer_lock);
- return false;
- }
- if (!discard_data &&
- (block->bytes_read != cl_block_get_bytes_committed(block))) {
- cl_unlock(&block->reader_lock);
- cl_unlock(&block->writer_lock);
- return false;
- }
- cl_block_set_bytes_committed(block, 0);
- block->bytes_read = 0;
- return true;
-}
-
-static void cl_block_enable_access(cl_block* block) {
- cl_unlock(&block->reader_lock);
- cl_unlock(&block->writer_lock);
-}
-
-// Returns with writer_lock held.
-static void* cl_block_start_write(cl_block* block, size_t size) {
- if (!cl_try_lock(&block->writer_lock)) {
- return NULL;
- }
- size_t bytes_committed = cl_block_get_bytes_committed(block);
- if (bytes_committed + size > CENSUS_LOG_MAX_RECORD_SIZE) {
- cl_unlock(&block->writer_lock);
- return NULL;
- }
- return block->buffer + bytes_committed;
-}
-
-// Releases writer_lock and increments committed bytes by 'bytes_written'.
-// 'bytes_written' must be <= 'size' specified in the corresponding
-// StartWrite() call. This function is thread-safe.
-static void cl_block_end_write(cl_block* block, size_t bytes_written) {
- cl_block_set_bytes_committed(
- block, cl_block_get_bytes_committed(block) + bytes_written);
- cl_unlock(&block->writer_lock);
-}
-
-// Returns a pointer to the first unread byte in buffer. The number of bytes
-// available are returned in 'bytes_available'. Acquires reader lock that is
-// released by a subsequent cl_block_end_read() call. Returns NULL if:
-// - read in progress
-// - no data available
-static void* cl_block_start_read(cl_block* block, size_t* bytes_available) {
- if (!cl_try_lock(&block->reader_lock)) {
- return NULL;
- }
- // bytes_committed may change from under us. Use bytes_available to update
- // bytes_read below.
- size_t bytes_committed = cl_block_get_bytes_committed(block);
- GPR_ASSERT(bytes_committed >= block->bytes_read);
- *bytes_available = bytes_committed - block->bytes_read;
- if (*bytes_available == 0) {
- cl_unlock(&block->reader_lock);
- return NULL;
- }
- void* record = block->buffer + block->bytes_read;
- block->bytes_read += *bytes_available;
- return record;
-}
-
-static void cl_block_end_read(cl_block* block) {
- cl_unlock(&block->reader_lock);
-}
-
-// Internal functions operating on g_log
-
-// Allocates a new free block (or recycles an available dirty block if log is
-// configured to discard old records). Returns NULL if out-of-space.
-static cl_block* cl_allocate_block(void) {
- cl_block* block = cl_block_list_head(&g_log.free_block_list);
- if (block != NULL) {
- cl_block_list_remove(&g_log.free_block_list, block);
- return block;
- }
- if (!g_log.discard_old_records) {
- // No free block and log is configured to keep old records.
- return NULL;
- }
- // Recycle dirty block. Start from the oldest.
- for (block = cl_block_list_head(&g_log.dirty_block_list); block != NULL;
- block = block->link.next->block) {
- if (cl_block_try_disable_access(block, 1 /* discard data */)) {
- cl_block_list_remove(&g_log.dirty_block_list, block);
- return block;
- }
- }
- return NULL;
-}
-
-// Allocates a new block and updates core id => block mapping. 'old_block'
-// points to the block that the caller thinks is attached to
-// 'core_id'. 'old_block' may be NULL. Returns true if:
-// - allocated a new block OR
-// - 'core_id' => 'old_block' mapping changed (another thread allocated a
-// block before lock was acquired).
-static bool cl_allocate_core_local_block(uint32_t core_id,
- cl_block* old_block) {
- // Now that we have the lock, check if core-local mapping has changed.
- cl_core_local_block* core_local_block = &g_log.core_local_blocks[core_id];
- cl_block* block = cl_core_local_block_get_block(core_local_block);
- if ((block != NULL) && (block != old_block)) {
- return true;
- }
- if (block != NULL) {
- cl_core_local_block_set_block(core_local_block, NULL);
- cl_block_list_insert_at_tail(&g_log.dirty_block_list, block);
- }
- block = cl_allocate_block();
- if (block == NULL) {
- return false;
- }
- cl_core_local_block_set_block(core_local_block, block);
- cl_block_enable_access(block);
- return true;
-}
-
-static cl_block* cl_get_block(void* record) {
- uintptr_t p = (uintptr_t)((char*)record - g_log.buffer);
- uintptr_t index = p >> CENSUS_LOG_2_MAX_RECORD_SIZE;
- return &g_log.blocks[index];
-}
-
-// Gets the next block to read and tries to free 'prev' block (if not NULL).
-// Returns NULL if reached the end.
-static cl_block* cl_next_block_to_read(cl_block* prev) {
- cl_block* block = NULL;
- if (g_log.read_iterator_state == g_log.num_cores) {
- // We are traversing dirty list; find the next dirty block.
- if (prev != NULL) {
- // Try to free the previous block if there is no unread data. This
- // block
- // may have unread data if previously incomplete record completed
- // between
- // read_next() calls.
- block = prev->link.next->block;
- if (cl_block_try_disable_access(prev, 0 /* do not discard data */)) {
- cl_block_list_remove(&g_log.dirty_block_list, prev);
- cl_block_list_insert_at_head(&g_log.free_block_list, prev);
- }
- } else {
- block = cl_block_list_head(&g_log.dirty_block_list);
- }
- if (block != NULL) {
- return block;
- }
- // We are done with the dirty list; moving on to core-local blocks.
- }
- while (g_log.read_iterator_state > 0) {
- g_log.read_iterator_state--;
- block = cl_core_local_block_get_block(
- &g_log.core_local_blocks[g_log.read_iterator_state]);
- if (block != NULL) {
- return block;
- }
- }
- return NULL;
-}
-
-#define CL_LOG_2_MB 20 // 2^20 = 1MB
-
-// External functions: primary stats_log interface
-void census_log_initialize(size_t size_in_mb, int discard_old_records) {
- // Check cacheline alignment.
- GPR_ASSERT(sizeof(cl_block) % GPR_CACHELINE_SIZE == 0);
- GPR_ASSERT(sizeof(cl_core_local_block) % GPR_CACHELINE_SIZE == 0);
- GPR_ASSERT(!g_log.initialized);
- g_log.discard_old_records = discard_old_records;
- g_log.num_cores = gpr_cpu_num_cores();
- // Ensure that we will not get any overflow in calaculating num_blocks
- GPR_ASSERT(CL_LOG_2_MB >= CENSUS_LOG_2_MAX_RECORD_SIZE);
- GPR_ASSERT(size_in_mb < 1000);
- // Ensure at least 2x as many blocks as there are cores.
- g_log.num_blocks =
- (uint32_t)GPR_MAX(2 * g_log.num_cores, (size_in_mb << CL_LOG_2_MB) >>
- CENSUS_LOG_2_MAX_RECORD_SIZE);
- gpr_mu_init(&g_log.lock);
- g_log.read_iterator_state = 0;
- g_log.block_being_read = NULL;
- g_log.core_local_blocks = (cl_core_local_block*)gpr_malloc_aligned(
- g_log.num_cores * sizeof(cl_core_local_block), GPR_CACHELINE_SIZE_LOG);
- memset(g_log.core_local_blocks, 0,
- g_log.num_cores * sizeof(cl_core_local_block));
- g_log.blocks = (cl_block*)gpr_malloc_aligned(
- g_log.num_blocks * sizeof(cl_block), GPR_CACHELINE_SIZE_LOG);
- memset(g_log.blocks, 0, g_log.num_blocks * sizeof(cl_block));
- g_log.buffer =
- (char*)gpr_malloc(g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE);
- memset(g_log.buffer, 0, g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE);
- cl_block_list_initialize(&g_log.free_block_list);
- cl_block_list_initialize(&g_log.dirty_block_list);
- for (uint32_t i = 0; i < g_log.num_blocks; ++i) {
- cl_block* block = g_log.blocks + i;
- cl_block_initialize(block, g_log.buffer + (CENSUS_LOG_MAX_RECORD_SIZE * i));
- cl_block_try_disable_access(block, 1 /* discard data */);
- cl_block_list_insert_at_tail(&g_log.free_block_list, block);
- }
- gpr_atm_rel_store(&g_log.out_of_space_count, 0);
- g_log.initialized = 1;
-}
-
-void census_log_shutdown(void) {
- GPR_ASSERT(g_log.initialized);
- gpr_mu_destroy(&g_log.lock);
- gpr_free_aligned(g_log.core_local_blocks);
- g_log.core_local_blocks = NULL;
- gpr_free_aligned(g_log.blocks);
- g_log.blocks = NULL;
- gpr_free(g_log.buffer);
- g_log.buffer = NULL;
- g_log.initialized = 0;
-}
-
-void* census_log_start_write(size_t size) {
- // Used to bound number of times block allocation is attempted.
- GPR_ASSERT(size > 0);
- GPR_ASSERT(g_log.initialized);
- if (size > CENSUS_LOG_MAX_RECORD_SIZE) {
- return NULL;
- }
- uint32_t attempts_remaining = g_log.num_blocks;
- uint32_t core_id = gpr_cpu_current_cpu();
- do {
- void* record = NULL;
- cl_block* block =
- cl_core_local_block_get_block(&g_log.core_local_blocks[core_id]);
- if (block && (record = cl_block_start_write(block, size))) {
- return record;
- }
- // Need to allocate a new block. We are here if:
- // - No block associated with the core OR
- // - Write in-progress on the block OR
- // - block is out of space
- gpr_mu_lock(&g_log.lock);
- bool allocated = cl_allocate_core_local_block(core_id, block);
- gpr_mu_unlock(&g_log.lock);
- if (!allocated) {
- gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
- return NULL;
- }
- } while (attempts_remaining--);
- // Give up.
- gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
- return NULL;
-}
-
-void census_log_end_write(void* record, size_t bytes_written) {
- GPR_ASSERT(g_log.initialized);
- cl_block_end_write(cl_get_block(record), bytes_written);
-}
-
-void census_log_init_reader(void) {
- GPR_ASSERT(g_log.initialized);
- gpr_mu_lock(&g_log.lock);
- // If a block is locked for reading unlock it.
- if (g_log.block_being_read != NULL) {
- cl_block_end_read(g_log.block_being_read);
- g_log.block_being_read = NULL;
- }
- g_log.read_iterator_state = g_log.num_cores;
- gpr_mu_unlock(&g_log.lock);
-}
-
-const void* census_log_read_next(size_t* bytes_available) {
- GPR_ASSERT(g_log.initialized);
- gpr_mu_lock(&g_log.lock);
- if (g_log.block_being_read != NULL) {
- cl_block_end_read(g_log.block_being_read);
- }
- do {
- g_log.block_being_read = cl_next_block_to_read(g_log.block_being_read);
- if (g_log.block_being_read != NULL) {
- void* record =
- cl_block_start_read(g_log.block_being_read, bytes_available);
- if (record != NULL) {
- gpr_mu_unlock(&g_log.lock);
- return record;
- }
- }
- } while (g_log.block_being_read != NULL);
- gpr_mu_unlock(&g_log.lock);
- return NULL;
-}
-
-size_t census_log_remaining_space(void) {
- GPR_ASSERT(g_log.initialized);
- size_t space = 0;
- gpr_mu_lock(&g_log.lock);
- if (g_log.discard_old_records) {
- // Remaining space is not meaningful; just return the entire log space.
- space = g_log.num_blocks << CENSUS_LOG_2_MAX_RECORD_SIZE;
- } else {
- GPR_ASSERT(g_log.free_block_list.count >= 0);
- space = (size_t)g_log.free_block_list.count * CENSUS_LOG_MAX_RECORD_SIZE;
- }
- gpr_mu_unlock(&g_log.lock);
- return space;
-}
-
-int64_t census_log_out_of_space_count(void) {
- GPR_ASSERT(g_log.initialized);
- return gpr_atm_acq_load(&g_log.out_of_space_count);
-}
diff --git a/src/core/ext/census/mlog.h b/src/core/ext/census/mlog.h
deleted file mode 100644
index 8f74ba2..0000000
--- a/src/core/ext/census/mlog.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/* A very fast in-memory log, optimized for multiple writers. */
-
-#ifndef GRPC_CORE_EXT_CENSUS_MLOG_H
-#define GRPC_CORE_EXT_CENSUS_MLOG_H
-
-#include <grpc/support/port_platform.h>
-#include <stddef.h>
-
-/* Maximum record size, in bytes. */
-#define CENSUS_LOG_2_MAX_RECORD_SIZE 14 /* 2^14 = 16KB */
-#define CENSUS_LOG_MAX_RECORD_SIZE (1 << CENSUS_LOG_2_MAX_RECORD_SIZE)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Initialize the statistics logging subsystem with the given log size. A log
- size of 0 will result in the smallest possible log for the platform
- (approximately CENSUS_LOG_MAX_RECORD_SIZE * gpr_cpu_num_cores()). If
- discard_old_records is non-zero, then new records will displace older ones
- when the log is full. This function must be called before any other
- census_log functions.
-*/
-void census_log_initialize(size_t size_in_mb, int discard_old_records);
-
-/* Shutdown the logging subsystem. Caller must ensure that:
- - no in progress or future call to any census_log functions
- - no incomplete records
-*/
-void census_log_shutdown(void);
-
-/* Allocates and returns a 'size' bytes record and marks it in use. A
- subsequent census_log_end_write() marks the record complete. The
- 'bytes_written' census_log_end_write() argument must be <=
- 'size'. Returns NULL if out-of-space AND:
- - log is configured to keep old records OR
- - all blocks are pinned by incomplete records.
-*/
-void* census_log_start_write(size_t size);
-
-void census_log_end_write(void* record, size_t bytes_written);
-
-void census_log_init_reader(void);
-
-/* census_log_read_next() iterates over blocks with data and for each block
- returns a pointer to the first unread byte. The number of bytes that can be
- read are returned in 'bytes_available'. Reader is expected to read all
- available data. Reading the data consumes it i.e. it cannot be read again.
- census_log_read_next() returns NULL if the end is reached i.e last block
- is read. census_log_init_reader() starts the iteration or aborts the
- current iteration.
-*/
-const void* census_log_read_next(size_t* bytes_available);
-
-/* Returns estimated remaining space across all blocks, in bytes. If log is
- configured to discard old records, returns total log space. Otherwise,
- returns space available in empty blocks (partially filled blocks are
- treated as full).
-*/
-size_t census_log_remaining_space(void);
-
-/* Returns the number of times grpc_stats_log_start_write() failed due to
- out-of-space. */
-int64_t census_log_out_of_space_count(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_MLOG_H */
diff --git a/src/core/ext/census/operation.cc b/src/core/ext/census/operation.cc
deleted file mode 100644
index be88ac7..0000000
--- a/src/core/ext/census/operation.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/census.h>
-
-/* TODO(aveitch): These are all placeholder implementations. */
-
-census_timestamp census_start_rpc_op_timestamp(void) {
- census_timestamp ct;
- /* TODO(aveitch): assumes gpr_timespec implementation of census_timestamp. */
- ct.ts = gpr_now(GPR_CLOCK_MONOTONIC);
- return ct;
-}
-
-census_context *census_start_client_rpc_op(
- const census_context *context, int64_t rpc_name_id,
- const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
- const census_timestamp *start_time) {
- return NULL;
-}
-
-census_context *census_start_server_rpc_op(
- const char *buffer, int64_t rpc_name_id,
- const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
- census_timestamp *start_time) {
- return NULL;
-}
-
-census_context *census_start_op(census_context *context, const char *family,
- const char *name, int trace_mask) {
- return NULL;
-}
-
-void census_end_op(census_context *context, int status) {}
diff --git a/src/core/ext/census/placeholders.cc b/src/core/ext/census/placeholders.cc
deleted file mode 100644
index bed9837..0000000
--- a/src/core/ext/census/placeholders.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/census.h>
-
-#include <grpc/support/log.h>
-
-/* Placeholders for the pending APIs */
-
-int census_get_trace_record(census_trace_record *trace_record) {
- (void)trace_record;
- abort();
-}
-
-void census_record_values(census_context *context, census_value *values,
- size_t nvalues) {
- (void)context;
- (void)values;
- (void)nvalues;
- abort();
-}
-
-void census_set_rpc_client_peer(census_context *context, const char *peer) {
- (void)context;
- (void)peer;
- abort();
-}
-
-void census_trace_scan_end() { abort(); }
-
-int census_trace_scan_start(int consume) {
- (void)consume;
- abort();
-}
diff --git a/src/core/ext/census/resource.cc b/src/core/ext/census/resource.cc
deleted file mode 100644
index 44a8872..0000000
--- a/src/core/ext/census/resource.cc
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/resource.h"
-#include "third_party/nanopb/pb_decode.h"
-
-#include <grpc/census.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/sync.h>
-
-#include <stdbool.h>
-#include <string.h>
-
-// Protect local resource data structures.
-static gpr_mu resource_lock;
-
-// Deleteing and creating resources are relatively rare events, and should not
-// be done in the critical path of performance sensitive code. We record
-// current resource id's used in a simple array, and just search it each time
-// we need to assign a new id, or look up a resource.
-static resource **resources = NULL;
-
-// Number of entries in *resources
-static size_t n_resources = 0;
-
-// Number of defined resources
-static size_t n_defined_resources = 0;
-
-void initialize_resources(void) {
- gpr_mu_init(&resource_lock);
- gpr_mu_lock(&resource_lock);
- GPR_ASSERT(resources == NULL && n_resources == 0 && n_defined_resources == 0);
- gpr_mu_unlock(&resource_lock);
-}
-
-// Delete a resource given it's ID. The ID must be a valid resource ID. Must be
-// called with resource_lock held.
-static void delete_resource_locked(size_t rid) {
- GPR_ASSERT(resources[rid] != NULL);
- gpr_free(resources[rid]->name);
- gpr_free(resources[rid]->description);
- gpr_free(resources[rid]->numerators);
- gpr_free(resources[rid]->denominators);
- gpr_free(resources[rid]);
- resources[rid] = NULL;
- n_defined_resources--;
-}
-
-void shutdown_resources(void) {
- gpr_mu_lock(&resource_lock);
- for (size_t i = 0; i < n_resources; i++) {
- if (resources[i] != NULL) {
- delete_resource_locked(i);
- }
- }
- GPR_ASSERT(n_defined_resources == 0);
- gpr_free(resources);
- resources = NULL;
- n_resources = 0;
- gpr_mu_unlock(&resource_lock);
-}
-
-// Check the contents of string fields in a resource proto.
-static bool validate_string(pb_istream_t *stream, const pb_field_t *field,
- void **arg) {
- resource *vresource = (resource *)*arg;
- switch (field->tag) {
- case google_census_Resource_name_tag:
- // Name must have at least one character
- if (stream->bytes_left == 0) {
- gpr_log(GPR_INFO, "Zero-length Resource name.");
- return false;
- }
- vresource->name = (char *)gpr_malloc(stream->bytes_left + 1);
- vresource->name[stream->bytes_left] = '\0';
- if (!pb_read(stream, (uint8_t *)vresource->name, stream->bytes_left)) {
- return false;
- }
- // Can't have same name as an existing resource.
- for (size_t i = 0; i < n_resources; i++) {
- resource *compare = resources[i];
- if (compare == vresource || compare == NULL) continue;
- if (strcmp(compare->name, vresource->name) == 0) {
- gpr_log(GPR_INFO, "Duplicate Resource name %s.", vresource->name);
- return false;
- }
- }
- break;
- case google_census_Resource_description_tag:
- if (stream->bytes_left == 0) {
- return true;
- }
- vresource->description = (char *)gpr_malloc(stream->bytes_left + 1);
- vresource->description[stream->bytes_left] = '\0';
- if (!pb_read(stream, (uint8_t *)vresource->description,
- stream->bytes_left)) {
- return false;
- }
- break;
- default:
- // No other string fields in Resource. Print warning and skip.
- gpr_log(GPR_INFO, "Unknown string field type in Resource protobuf.");
- if (!pb_read(stream, NULL, stream->bytes_left)) {
- return false;
- }
- break;
- }
- return true;
-}
-
-// Decode numerators/denominators in a stream. The `count` and `bup`
-// (BasicUnit pointer) are pointers to the approriate fields in a resource
-// struct.
-static bool validate_units_helper(pb_istream_t *stream, int *count,
- google_census_Resource_BasicUnit **bup) {
- while (stream->bytes_left) {
- (*count)++;
- // Have to allocate a new array of values. Normal case is 0 or 1, so
- // this should normally not be an issue.
- google_census_Resource_BasicUnit *new_bup =
- (google_census_Resource_BasicUnit *)gpr_malloc(
- (size_t)*count * sizeof(google_census_Resource_BasicUnit));
- if (*count != 1) {
- memcpy(new_bup, *bup,
- (size_t)(*count - 1) * sizeof(google_census_Resource_BasicUnit));
- gpr_free(*bup);
- }
- *bup = new_bup;
- uint64_t value;
- if (!pb_decode_varint(stream, &value)) {
- return false;
- }
- *(*bup + *count - 1) = (google_census_Resource_BasicUnit)value;
- }
- return true;
-}
-
-// Validate units field of a Resource proto.
-static bool validate_units(pb_istream_t *stream, const pb_field_t *field,
- void **arg) {
- resource *vresource = (resource *)(*arg);
- switch (field->tag) {
- case google_census_Resource_MeasurementUnit_numerator_tag:
- return validate_units_helper(stream, &vresource->n_numerators,
- &vresource->numerators);
- break;
- case google_census_Resource_MeasurementUnit_denominator_tag:
- return validate_units_helper(stream, &vresource->n_denominators,
- &vresource->denominators);
- break;
- default:
- gpr_log(GPR_ERROR, "Unknown field type.");
- return false;
- break;
- }
- return true;
-}
-
-// Validate the contents of a Resource proto. `id` is the intended resource id.
-static bool validate_resource_pb(const uint8_t *resource_pb,
- size_t resource_pb_size, size_t id) {
- GPR_ASSERT(id < n_resources);
- if (resource_pb == NULL) {
- return false;
- }
- google_census_Resource vresource;
- vresource.name.funcs.decode = &validate_string;
- vresource.name.arg = resources[id];
- vresource.description.funcs.decode = &validate_string;
- vresource.description.arg = resources[id];
- vresource.unit.numerator.funcs.decode = &validate_units;
- vresource.unit.numerator.arg = resources[id];
- vresource.unit.denominator.funcs.decode = &validate_units;
- vresource.unit.denominator.arg = resources[id];
-
- pb_istream_t stream =
- pb_istream_from_buffer((uint8_t *)resource_pb, resource_pb_size);
- if (!pb_decode(&stream, google_census_Resource_fields, &vresource)) {
- return false;
- }
- // A Resource must have a name, a unit, with at least one numerator.
- return (resources[id]->name != NULL && vresource.has_unit &&
- resources[id]->n_numerators > 0);
-}
-
-// Allocate a blank resource, and return associated ID. Must be called with
-// resource_lock held.
-size_t allocate_resource(void) {
- // use next_id to optimize expected placement of next new resource.
- static size_t next_id = 0;
- size_t id = n_resources; // resource ID - initialize to invalid value.
- // Expand resources if needed.
- if (n_resources == n_defined_resources) {
- size_t new_n_resources = n_resources ? n_resources * 2 : 2;
- resource **new_resources =
- (resource **)gpr_malloc(new_n_resources * sizeof(resource *));
- if (n_resources != 0) {
- memcpy(new_resources, resources, n_resources * sizeof(resource *));
- }
- memset(new_resources + n_resources, 0,
- (new_n_resources - n_resources) * sizeof(resource *));
- gpr_free(resources);
- resources = new_resources;
- n_resources = new_n_resources;
- id = n_defined_resources;
- } else {
- GPR_ASSERT(n_defined_resources < n_resources);
- // Find a free id.
- for (size_t base = 0; base < n_resources; base++) {
- id = (next_id + base) % n_resources;
- if (resources[id] == NULL) break;
- }
- }
- GPR_ASSERT(id < n_resources && resources[id] == NULL);
- resources[id] = (resource *)gpr_malloc(sizeof(resource));
- memset(resources[id], 0, sizeof(resource));
- n_defined_resources++;
- next_id = (id + 1) % n_resources;
- return id;
-}
-
-int32_t census_define_resource(const uint8_t *resource_pb,
- size_t resource_pb_size) {
- if (resource_pb == NULL) {
- return -1;
- }
- gpr_mu_lock(&resource_lock);
- size_t id = allocate_resource();
- // Validate pb, extract name.
- if (!validate_resource_pb(resource_pb, resource_pb_size, id)) {
- delete_resource_locked(id);
- gpr_mu_unlock(&resource_lock);
- return -1;
- }
- gpr_mu_unlock(&resource_lock);
- return (int32_t)id;
-}
-
-void census_delete_resource(int32_t rid) {
- gpr_mu_lock(&resource_lock);
- if (rid >= 0 && (size_t)rid < n_resources && resources[rid] != NULL) {
- delete_resource_locked((size_t)rid);
- }
- gpr_mu_unlock(&resource_lock);
-}
-
-int32_t census_resource_id(const char *name) {
- gpr_mu_lock(&resource_lock);
- for (int32_t id = 0; (size_t)id < n_resources; id++) {
- if (resources[id] != NULL && strcmp(resources[id]->name, name) == 0) {
- gpr_mu_unlock(&resource_lock);
- return id;
- }
- }
- gpr_mu_unlock(&resource_lock);
- return -1;
-}
-
-int32_t define_resource(const resource *base) {
- GPR_ASSERT(base != NULL && base->name != NULL && base->n_numerators > 0 &&
- base->numerators != NULL);
- gpr_mu_lock(&resource_lock);
- size_t id = allocate_resource();
- size_t len = strlen(base->name) + 1;
- resources[id]->name = (char *)gpr_malloc(len);
- memcpy(resources[id]->name, base->name, len);
- if (base->description) {
- len = strlen(base->description) + 1;
- resources[id]->description = (char *)gpr_malloc(len);
- memcpy(resources[id]->description, base->description, len);
- }
- resources[id]->prefix = base->prefix;
- resources[id]->n_numerators = base->n_numerators;
- len = (size_t)base->n_numerators * sizeof(*base->numerators);
- resources[id]->numerators =
- (google_census_Resource_BasicUnit *)gpr_malloc(len);
- memcpy(resources[id]->numerators, base->numerators, len);
- resources[id]->n_denominators = base->n_denominators;
- if (base->n_denominators != 0) {
- len = (size_t)base->n_denominators * sizeof(*base->denominators);
- resources[id]->denominators =
- (google_census_Resource_BasicUnit *)gpr_malloc(len);
- memcpy(resources[id]->denominators, base->denominators, len);
- }
- gpr_mu_unlock(&resource_lock);
- return (int32_t)id;
-}
diff --git a/src/core/ext/census/resource.h b/src/core/ext/census/resource.h
deleted file mode 100644
index 56aaaaf..0000000
--- a/src/core/ext/census/resource.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/* Census-internal resource definition and manipluation functions. */
-#ifndef GRPC_CORE_EXT_CENSUS_RESOURCE_H
-#define GRPC_CORE_EXT_CENSUS_RESOURCE_H
-
-#include <grpc/grpc.h>
-#include "src/core/ext/census/gen/census.pb.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Internal representation of a resource. */
-typedef struct {
- char *name;
- char *description;
- int32_t prefix;
- int n_numerators;
- google_census_Resource_BasicUnit *numerators;
- int n_denominators;
- google_census_Resource_BasicUnit *denominators;
-} resource;
-
-/* Initialize and shutdown the resources subsystem. */
-void initialize_resources(void);
-void shutdown_resources(void);
-
-/* Add a new resource, given a proposed resource structure. Returns the
- resource ID, or -ve on failure.
- TODO(aveitch): this function exists to support addition of the base
- resources. It should be removed when we have the ability to add resources
- from configuration files. */
-int32_t define_resource(const resource *base);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_RESOURCE_H */
diff --git a/src/core/ext/census/rpc_metric_id.h b/src/core/ext/census/rpc_metric_id.h
deleted file mode 100644
index ea493d7..0000000
--- a/src/core/ext/census/rpc_metric_id.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_RPC_METRIC_ID_H
-#define GRPC_CORE_EXT_CENSUS_RPC_METRIC_ID_H
-
-/* Metric ID's used for RPC measurements. */
-/* Count of client requests sent. */
-#define CENSUS_METRIC_RPC_CLIENT_REQUESTS ((uint32_t)0)
-/* Count of server requests sent. */
-#define CENSUS_METRIC_RPC_SERVER_REQUESTS ((uint32_t)1)
-/* Client error counts. */
-#define CENSUS_METRIC_RPC_CLIENT_ERRORS ((uint32_t)2)
-/* Server error counts. */
-#define CENSUS_METRIC_RPC_SERVER_ERRORS ((uint32_t)3)
-/* Client side request latency. */
-#define CENSUS_METRIC_RPC_CLIENT_LATENCY ((uint32_t)4)
-/* Server side request latency. */
-#define CENSUS_METRIC_RPC_SERVER_LATENCY ((uint32_t)5)
-
-#endif /* GRPC_CORE_EXT_CENSUS_RPC_METRIC_ID_H */
diff --git a/src/core/ext/census/trace_context.cc b/src/core/ext/census/trace_context.cc
deleted file mode 100644
index af92ae6..0000000
--- a/src/core/ext/census/trace_context.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/trace_context.h"
-
-#include <grpc/census.h>
-#include <grpc/support/log.h>
-#include <stdbool.h>
-
-#include "third_party/nanopb/pb_decode.h"
-#include "third_party/nanopb/pb_encode.h"
-
-// This function assumes the TraceContext is valid.
-size_t encode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
- const size_t buf_size) {
- // Create a stream that will write to our buffer.
- pb_ostream_t stream = pb_ostream_from_buffer(buffer, buf_size);
-
- // encode message
- bool status = pb_encode(&stream, google_trace_TraceContext_fields, ctxt);
-
- if (!status) {
- gpr_log(GPR_DEBUG, "TraceContext encoding failed: %s",
- PB_GET_ERROR(&stream));
- return 0;
- }
-
- return stream.bytes_written;
-}
-
-bool decode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
- const size_t nbytes) {
- // Create a stream that reads nbytes from the buffer.
- pb_istream_t stream = pb_istream_from_buffer(buffer, nbytes);
-
- // decode message
- bool status = pb_decode(&stream, google_trace_TraceContext_fields, ctxt);
-
- if (!status) {
- gpr_log(GPR_DEBUG, "TraceContext decoding failed: %s",
- PB_GET_ERROR(&stream));
- return false;
- }
-
- // check fields
- if (!ctxt->has_trace_id_hi || !ctxt->has_trace_id_lo) {
- gpr_log(GPR_DEBUG, "Invalid TraceContext: missing trace_id");
- return false;
- }
- if (!ctxt->has_span_id) {
- gpr_log(GPR_DEBUG, "Invalid TraceContext: missing span_id");
- return false;
- }
-
- return true;
-}
diff --git a/src/core/ext/census/trace_context.h b/src/core/ext/census/trace_context.h
deleted file mode 100644
index 2b828ba..0000000
--- a/src/core/ext/census/trace_context.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/* Functions for manipulating trace contexts as defined in
- src/proto/census/trace.proto */
-#ifndef GRPC_CORE_EXT_CENSUS_TRACE_CONTEXT_H
-#define GRPC_CORE_EXT_CENSUS_TRACE_CONTEXT_H
-
-#include "src/core/ext/census/gen/trace_context.pb.h"
-
-/* Span option flags. */
-#define SPAN_OPTIONS_IS_SAMPLED 0x01
-
-/* Maximum number of bytes required to encode a TraceContext (31)
-1 byte for trace_id field
-1 byte for trace_id length
-1 byte for trace_id.hi field
-8 bytes for trace_id.hi (uint64_t)
-1 byte for trace_id.lo field
-8 bytes for trace_id.lo (uint64_t)
-1 byte for span_id field
-8 bytes for span_id (uint64_t)
-1 byte for is_sampled field
-1 byte for is_sampled (bool) */
-#define TRACE_MAX_CONTEXT_SIZE 31
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Encode a trace context (ctxt) into proto format to the buffer provided. The
-size of buffer must be at least TRACE_MAX_CONTEXT_SIZE. On success, returns the
-number of bytes successfully encoded into buffer. On failure, returns 0. */
-size_t encode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
- const size_t buf_size);
-
-/* Decode a proto-encoded TraceContext from the provided buffer into the
-TraceContext structure (ctxt). The function expects to be supplied the number
-of bytes to be read from buffer (nbytes). This function will also validate that
-the TraceContext has a span_id and a trace_id, and will return false if either
-of these do not exist. On success, returns true and false otherwise. */
-bool decode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
- const size_t nbytes);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_TRACE_CONTEXT_H */
diff --git a/src/core/ext/census/trace_label.h b/src/core/ext/census/trace_label.h
deleted file mode 100644
index 97ce399..0000000
--- a/src/core/ext/census/trace_label.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H
-#define GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H
-
-#include "src/core/ext/census/trace_string.h"
-
-/* Trace label (key/value pair) stores a label name and the label value. The
- value can be one of trace_string/int64_t/bool. */
-typedef struct trace_label {
- trace_string key;
- enum label_type {
- /* Unknown value for debugging/error purposes */
- LABEL_UNKNOWN = 0,
- /* A string value */
- LABEL_STRING = 1,
- /* An integer value. */
- LABEL_INT = 2,
- /* A boolean value. */
- LABEL_BOOL = 3,
- } value_type;
-
- union value {
- trace_string label_str;
- int64_t label_int;
- bool label_bool;
- } value;
-} trace_label;
-
-#endif /* GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H */
diff --git a/src/core/ext/census/trace_propagation.h b/src/core/ext/census/trace_propagation.h
deleted file mode 100644
index e05fd23..0000000
--- a/src/core/ext/census/trace_propagation.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H
-#define GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H
-
-#include "src/core/ext/census/tracing.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Encoding and decoding functions for receiving and sending trace contexts
- over the wire. Only RPC libraries should be calling these
- functions. These functions return the number of bytes encoded/decoded
- (0 if a failure has occurred). buf_size indicates the size of the
- input/output buffer. trace_span_context is a struct that includes the
- trace ID, span ID, and a set of option flags (is_sampled, etc.). */
-
-/* Converts a span context to a binary byte buffer. */
-size_t trace_span_context_to_binary(const trace_span_context *ctxt,
- uint8_t *buf, size_t buf_size);
-
-/* Reads a binary byte buffer and populates a span context structure. */
-size_t binary_to_trace_span_context(const uint8_t *buf, size_t buf_size,
- trace_span_context *ctxt);
-
-/* Converts a span context to an http metadata compatible string. */
-size_t trace_span_context_to_http_format(const trace_span_context *ctxt,
- char *buf, size_t buf_size);
-
-/* Reads an http metadata compatible string and populates a span context
- structure. */
-size_t http_format_to_trace_span_context(const char *buf, size_t buf_size,
- trace_span_context *ctxt);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H */
diff --git a/src/core/ext/census/trace_status.h b/src/core/ext/census/trace_status.h
deleted file mode 100644
index dd83d3f..0000000
--- a/src/core/ext/census/trace_status.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H
-#define GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H
-
-#include "src/core/ext/census/trace_string.h"
-
-/* Stores a status code and status message for a trace. */
-typedef struct trace_status {
- int64_t errorCode;
- trace_string errorMessage;
-} trace_status;
-
-#endif /* GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H */
diff --git a/src/core/ext/census/trace_string.h b/src/core/ext/census/trace_string.h
deleted file mode 100644
index e4da3f5..0000000
--- a/src/core/ext/census/trace_string.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_TRACE_STRING_H
-#define GRPC_CORE_EXT_CENSUS_TRACE_STRING_H
-
-#include <grpc/slice.h>
-
-/* String struct for tracing messages. Since this is a C API, we do not have
- access to a string class. This is intended for use by higher level
- languages which wrap around the C API, as most of them have a string class.
- This will also be more efficient when copying, as we have an explicitly
- specified length. Also, grpc_slice has reference counting which allows for
- interning. */
-typedef struct trace_string {
- char *string;
- size_t length;
-} trace_string;
-
-#endif /* GRPC_CORE_EXT_CENSUS_TRACE_STRING_H */
diff --git a/src/core/ext/census/tracing.cc b/src/core/ext/census/tracing.cc
deleted file mode 100644
index 823c681..0000000
--- a/src/core/ext/census/tracing.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/tracing.h"
-
-#include <grpc/census.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include "src/core/ext/census/mlog.h"
-
-void trace_start_span(const trace_span_context *span_ctxt,
- const trace_string name, const start_span_options *opts,
- trace_span_context *new_span_ctxt,
- bool has_remote_parent) {
- // Noop implementation.
-}
-
-void trace_add_span_annotation(const trace_string description,
- const trace_label *labels, const size_t n_labels,
- trace_span_context *span_ctxt) {
- // Noop implementation.
-}
-
-void trace_add_span_network_event_annotation(const trace_string description,
- const trace_label *labels,
- const size_t n_labels,
- const gpr_timespec timestamp,
- bool sent, uint64_t id,
- trace_span_context *span_ctxt) {
- // Noop implementation.
-}
-
-void trace_add_span_labels(const trace_label *labels, const size_t n_labels,
- trace_span_context *span_ctxt) {
- // Noop implementation.
-}
-
-void trace_end_span(const trace_status *status, trace_span_context *span_ctxt) {
- // Noop implementation.
-}
diff --git a/src/core/ext/census/tracing.h b/src/core/ext/census/tracing.h
deleted file mode 100644
index 0690de8..0000000
--- a/src/core/ext/census/tracing.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_TRACING_H
-#define GRPC_CORE_EXT_CENSUS_TRACING_H
-
-#include <grpc/support/time.h>
-#include <stdbool.h>
-#include "src/core/ext/census/trace_context.h"
-#include "src/core/ext/census/trace_label.h"
-#include "src/core/ext/census/trace_status.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This is the low level tracing API that other languages will interface with.
- This is not intended to be accessed by the end-user, therefore it has been
- designed with performance in mind rather than ease of use. */
-
-/* The tracing level. */
-enum TraceLevel {
- /* Annotations on this context will be silently discarded. */
- NO_TRACING = 0,
- /* Annotations will not be saved to a persistent store. They will be
- available via local APIs only. This setting is not propagated to child
- spans. */
- TRANSIENT_TRACING = 1,
- /* Annotations are recorded for the entire distributed trace and they are
- saved to a persistent store. This setting is propagated to child spans. */
- PERSISTENT_TRACING = 2,
-};
-
-typedef struct trace_span_context {
- /* Trace span context stores Span ID, Trace ID, and option flags. */
- /* Trace ID is 128 bits split into 2 64-bit chunks (hi and lo). */
- uint64_t trace_id_hi;
- uint64_t trace_id_lo;
- /* Span ID is 64 bits. */
- uint64_t span_id;
- /* Span-options is 32-bit value which contains flag options. */
- uint32_t span_options;
-} trace_span_context;
-
-typedef struct start_span_options {
- /* If set, this will override the Span.local_start_time for the Span. */
- gpr_timespec local_start_timestamp;
-
- /* Linked spans can be used to identify spans that are linked to this span in
- a different trace. This can be used (for example) in batching operations,
- where a single batch handler processes multiple requests from different
- traces. If set, points to a list of Spans are linked to the created Span.*/
- trace_span_context *linked_spans;
- /* The number of linked spans. */
- size_t n_linked_spans;
-} start_span_options;
-
-/* Create a new child Span (or root if parent is NULL), with parent being the
- designated Span. The child span will have the provided name and starting
- span options (optional). The bool has_remote_parent marks whether the
- context refers to a remote parent span or not. */
-void trace_start_span(const trace_span_context *span_ctxt,
- const trace_string name, const start_span_options *opts,
- trace_span_context *new_span_ctxt,
- bool has_remote_parent);
-
-/* Add a new Annotation to the Span. Annotations consist of a description
- (trace_string) and a set of n labels (trace_label). This can be populated
- with arbitrary user data. */
-void trace_add_span_annotation(const trace_string description,
- const trace_label *labels, const size_t n_labels,
- trace_span_context *span_ctxt);
-
-/* Add a new NetworkEvent annotation to a Span. This function is only intended
- to be used by RPC systems (either client or server), not by higher level
- applications. The timestamp type will be system-defined, the sent argument
- designates whether this is a network send event (client request, server
- reply)or receive (server request, client reply). The id argument corresponds
- to Span.Annotation.NetworkEvent.id from the data model, and serves to uniquely
- identify each network message. */
-void trace_add_span_network_event(const trace_string description,
- const trace_label *labels,
- const size_t n_labels,
- const gpr_timespec timestamp, bool sent,
- uint64_t id, trace_span_context *span_ctxt);
-
-/* Add a set of labels to the Span. These will correspond to the field
-Span.labels in the data model. */
-void trace_add_span_labels(const trace_label *labels, const size_t n_labels,
- trace_span_context *span_ctxt);
-
-/* Mark the end of Span Execution with the given status. Only the timing of the
-first EndSpan call for a given Span will be recorded, and implementations are
-free to ignore all further calls using the Span. EndSpanOptions can
-optionally be NULL. */
-void trace_end_span(const trace_status *status, trace_span_context *span_ctxt);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_TRACING_H */
diff --git a/src/core/ext/census/window_stats.cc b/src/core/ext/census/window_stats.cc
deleted file mode 100644
index 0058e4b..0000000
--- a/src/core/ext/census/window_stats.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/window_stats.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/time.h>
-#include <grpc/support/useful.h>
-#include <math.h>
-#include <stddef.h>
-#include <string.h>
-
-/* typedefs make typing long names easier. Use cws (for census_window_stats) */
-typedef census_window_stats_stat_info cws_stat_info;
-typedef struct census_window_stats_sum cws_sum;
-
-/* Each interval is composed of a number of buckets, which hold a count of
- entries and a single statistic */
-typedef struct census_window_stats_bucket {
- int64_t count;
- void *statistic;
-} cws_bucket;
-
-/* Each interval has a set of buckets, and the variables needed to keep
- track of their current state */
-typedef struct census_window_stats_interval_stats {
- /* The buckets. There will be 'granularity' + 1 of these. */
- cws_bucket *buckets;
- /* Index of the bucket containing the smallest time interval. */
- int bottom_bucket;
- /* The smallest time storable in the current window. */
- int64_t bottom;
- /* The largest time storable in the current window + 1ns */
- int64_t top;
- /* The width of each bucket in ns. */
- int64_t width;
-} cws_interval_stats;
-
-typedef struct census_window_stats {
- /* Number of intervals. */
- int nintervals;
- /* Number of buckets in each interval. 'granularity' + 1. */
- int nbuckets;
- /* Record of stat_info. */
- cws_stat_info stat_info;
- /* Stats for each interval. */
- cws_interval_stats *interval_stats;
- /* The time the newset stat was recorded. */
- int64_t newest_time;
-} window_stats;
-
-/* Calculate an actual bucket index from a logical index 'IDX'. Other
- parameters supply information on the interval struct and overall stats. */
-#define BUCKET_IDX(IS, IDX, WSTATS) \
- ((IS->bottom_bucket + (IDX)) % WSTATS->nbuckets)
-
-/* The maximum seconds value we can have in a valid timespec. More than this
- will result in overflow in timespec_to_ns(). This works out to ~292 years.
- TODO: consider using doubles instead of int64. */
-static int64_t max_seconds = (GPR_INT64_MAX - GPR_NS_PER_SEC) / GPR_NS_PER_SEC;
-
-static int64_t timespec_to_ns(const gpr_timespec ts) {
- if (ts.tv_sec > max_seconds) {
- return GPR_INT64_MAX - 1;
- }
- return ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec;
-}
-
-static void cws_initialize_statistic(void *statistic,
- const cws_stat_info *stat_info) {
- if (stat_info->stat_initialize == NULL) {
- memset(statistic, 0, stat_info->stat_size);
- } else {
- stat_info->stat_initialize(statistic);
- }
-}
-
-/* Create and initialize a statistic */
-static void *cws_create_statistic(const cws_stat_info *stat_info) {
- void *stat = gpr_malloc(stat_info->stat_size);
- cws_initialize_statistic(stat, stat_info);
- return stat;
-}
-
-window_stats *census_window_stats_create(int nintervals,
- const gpr_timespec intervals[],
- int granularity,
- const cws_stat_info *stat_info) {
- window_stats *ret;
- int i;
- /* validate inputs */
- GPR_ASSERT(nintervals > 0 && granularity > 2 && intervals != NULL &&
- stat_info != NULL);
- for (i = 0; i < nintervals; i++) {
- int64_t ns = timespec_to_ns(intervals[i]);
- GPR_ASSERT(intervals[i].tv_sec >= 0 && intervals[i].tv_nsec >= 0 &&
- intervals[i].tv_nsec < GPR_NS_PER_SEC && ns >= 100 &&
- granularity * 10 <= ns);
- }
- /* Allocate and initialize relevant data structures */
- ret = (window_stats *)gpr_malloc(sizeof(window_stats));
- ret->nintervals = nintervals;
- ret->nbuckets = granularity + 1;
- ret->stat_info = *stat_info;
- ret->interval_stats =
- (cws_interval_stats *)gpr_malloc(nintervals * sizeof(cws_interval_stats));
- for (i = 0; i < nintervals; i++) {
- int64_t size_ns = timespec_to_ns(intervals[i]);
- cws_interval_stats *is = ret->interval_stats + i;
- cws_bucket *buckets = is->buckets =
- (cws_bucket *)gpr_malloc(ret->nbuckets * sizeof(cws_bucket));
- int b;
- for (b = 0; b < ret->nbuckets; b++) {
- buckets[b].statistic = cws_create_statistic(stat_info);
- buckets[b].count = 0;
- }
- is->bottom_bucket = 0;
- is->bottom = 0;
- is->width = size_ns / granularity;
- /* Check for possible overflow issues, and maximize interval size if the
- user requested something large enough. */
- if ((GPR_INT64_MAX - is->width) > size_ns) {
- is->top = size_ns + is->width;
- } else {
- is->top = GPR_INT64_MAX;
- is->width = GPR_INT64_MAX / (granularity + 1);
- }
- /* If size doesn't divide evenly, we can have a width slightly too small;
- better to have it slightly large. */
- if ((size_ns - (granularity + 1) * is->width) > 0) {
- is->width += 1;
- }
- }
- ret->newest_time = 0;
- return ret;
-}
-
-/* When we try adding a measurement above the current interval range, we
- need to "shift" the buckets sufficiently to cover the new range. */
-static void cws_shift_buckets(const window_stats *wstats,
- cws_interval_stats *is, int64_t when_ns) {
- int i;
- /* number of bucket time widths to "shift" */
- int shift;
- /* number of buckets to clear */
- int nclear;
- GPR_ASSERT(when_ns >= is->top);
- /* number of bucket time widths to "shift" */
- shift = ((when_ns - is->top) / is->width) + 1;
- /* number of buckets to clear - limited by actual number of buckets */
- nclear = GPR_MIN(shift, wstats->nbuckets);
- for (i = 0; i < nclear; i++) {
- int b = BUCKET_IDX(is, i, wstats);
- is->buckets[b].count = 0;
- cws_initialize_statistic(is->buckets[b].statistic, &wstats->stat_info);
- }
- /* adjust top/bottom times and current bottom bucket */
- is->bottom_bucket = BUCKET_IDX(is, shift, wstats);
- is->top += shift * is->width;
- is->bottom += shift * is->width;
-}
-
-void census_window_stats_add(window_stats *wstats, const gpr_timespec when,
- const void *stat_value) {
- int i;
- int64_t when_ns = timespec_to_ns(when);
- GPR_ASSERT(wstats->interval_stats != NULL);
- for (i = 0; i < wstats->nintervals; i++) {
- cws_interval_stats *is = wstats->interval_stats + i;
- cws_bucket *bucket;
- if (when_ns < is->bottom) { /* Below smallest time in interval: drop */
- continue;
- }
- if (when_ns >= is->top) { /* above limit: shift buckets */
- cws_shift_buckets(wstats, is, when_ns);
- }
- /* Add the stat. */
- GPR_ASSERT(is->bottom <= when_ns && when_ns < is->top);
- bucket = is->buckets +
- BUCKET_IDX(is, (when_ns - is->bottom) / is->width, wstats);
- bucket->count++;
- wstats->stat_info.stat_add(bucket->statistic, stat_value);
- }
- if (when_ns > wstats->newest_time) {
- wstats->newest_time = when_ns;
- }
-}
-
-/* Add a specific bucket contents to an accumulating total. */
-static void cws_add_bucket_to_sum(cws_sum *sum, const cws_bucket *bucket,
- const cws_stat_info *stat_info) {
- sum->count += bucket->count;
- stat_info->stat_add(sum->statistic, bucket->statistic);
-}
-
-/* Add a proportion to an accumulating sum. */
-static void cws_add_proportion_to_sum(double p, cws_sum *sum,
- const cws_bucket *bucket,
- const cws_stat_info *stat_info) {
- sum->count += p * bucket->count;
- stat_info->stat_add_proportion(p, sum->statistic, bucket->statistic);
-}
-
-void census_window_stats_get_sums(const window_stats *wstats,
- const gpr_timespec when, cws_sum sums[]) {
- int i;
- int64_t when_ns = timespec_to_ns(when);
- GPR_ASSERT(wstats->interval_stats != NULL);
- for (i = 0; i < wstats->nintervals; i++) {
- int when_bucket;
- int new_bucket;
- double last_proportion = 1.0;
- double bottom_proportion;
- cws_interval_stats *is = wstats->interval_stats + i;
- cws_sum *sum = sums + i;
- sum->count = 0;
- cws_initialize_statistic(sum->statistic, &wstats->stat_info);
- if (when_ns < is->bottom) {
- continue;
- }
- if (when_ns >= is->top) {
- cws_shift_buckets(wstats, is, when_ns);
- }
- /* Calculating the appropriate amount of which buckets to use can get
- complicated. Essentially there are two cases:
- 1) if the "top" bucket (new_bucket, where the newest additions to the
- stats recorded are entered) corresponds to 'when', then we need
- to take a proportion of it - (if when < newest_time) or the full
- thing. We also (possibly) need to take a corresponding
- proportion of the bottom bucket.
- 2) Other cases, we just take a straight proportion.
- */
- when_bucket = (when_ns - is->bottom) / is->width;
- new_bucket = (wstats->newest_time - is->bottom) / is->width;
- if (new_bucket == when_bucket) {
- int64_t bottom_bucket_time = is->bottom + when_bucket * is->width;
- if (when_ns < wstats->newest_time) {
- last_proportion = (double)(when_ns - bottom_bucket_time) /
- (double)(wstats->newest_time - bottom_bucket_time);
- bottom_proportion =
- (double)(is->width - (when_ns - bottom_bucket_time)) / is->width;
- } else {
- bottom_proportion =
- (double)(is->width - (wstats->newest_time - bottom_bucket_time)) /
- is->width;
- }
- } else {
- last_proportion =
- (double)(when_ns + 1 - is->bottom - when_bucket * is->width) /
- is->width;
- bottom_proportion = 1.0 - last_proportion;
- }
- cws_add_proportion_to_sum(last_proportion, sum,
- is->buckets + BUCKET_IDX(is, when_bucket, wstats),
- &wstats->stat_info);
- if (when_bucket != 0) { /* last bucket isn't also bottom bucket */
- int b;
- /* Add all of "bottom" bucket if we are looking at a subset of the
- full interval, or a proportion if we are adding full interval. */
- cws_add_proportion_to_sum(
- (when_bucket == wstats->nbuckets - 1 ? bottom_proportion : 1.0), sum,
- is->buckets + is->bottom_bucket, &wstats->stat_info);
- /* Add all the remaining buckets (everything but top and bottom). */
- for (b = 1; b < when_bucket; b++) {
- cws_add_bucket_to_sum(sum, is->buckets + BUCKET_IDX(is, b, wstats),
- &wstats->stat_info);
- }
- }
- }
-}
-
-void census_window_stats_destroy(window_stats *wstats) {
- int i;
- GPR_ASSERT(wstats->interval_stats != NULL);
- for (i = 0; i < wstats->nintervals; i++) {
- int b;
- for (b = 0; b < wstats->nbuckets; b++) {
- gpr_free(wstats->interval_stats[i].buckets[b].statistic);
- }
- gpr_free(wstats->interval_stats[i].buckets);
- }
- gpr_free(wstats->interval_stats);
- /* Ensure any use-after free triggers assert. */
- wstats->interval_stats = NULL;
- gpr_free(wstats);
-}
diff --git a/src/core/ext/census/window_stats.h b/src/core/ext/census/window_stats.h
deleted file mode 100644
index 2a1d6d0..0000000
--- a/src/core/ext/census/window_stats.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CENSUS_WINDOW_STATS_H
-#define GRPC_CORE_EXT_CENSUS_WINDOW_STATS_H
-
-#include <grpc/support/time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Keep rolling sums of a user-defined statistic (containing a number of
- measurements) over a a number of time intervals ("windows"). For example,
- you can use a window_stats object to answer questions such as
- "Approximately how many RPCs/s did I receive over the past minute, and
- approximately how many bytes did I send out over that period?".
-
- The type of data to record, and the time intervals to keep are specified
- when creating the object via a call to census_window_stats_create().
-
- A window's interval is divided into one or more "buckets"; the interval
- must be divisible by the number of buckets. Internally, these buckets
- control the granularity of window_stats' measurements. Increasing the
- number of buckets lets the object respond more quickly to changes in the
- overall rate of data added into the object, at the cost of additional
- memory usage.
-
- Here's some code which keeps one minute/hour measurements for two values
- (latency in seconds and bytes transferred), with each interval divided into
- 4 buckets.
-
- typedef struct my_stat {
- double latency;
- int bytes;
- } my_stat;
-
- void add_my_stat(void* base, const void* addme) {
- my_stat* b = (my_stat*)base;
- const my_stat* a = (const my_stat*)addme;
- b->latency += a->latency;
- b->bytes += a->bytes;
- }
-
- void add_proportion_my_stat(double p, void* base, const void* addme) {
- (my_stat*)result->latency += p * (const my_stat*)base->latency;
- (my_stat*)result->bytes += p * (const my_stat*)base->bytes;
- }
-
- #define kNumIntervals 2
- #define kMinInterval 0
- #define kHourInterval 1
- #define kNumBuckets 4
-
- const struct census_window_stats_stat_info kMyStatInfo
- = { sizeof(my_stat), NULL, add_my_stat, add_proportion_my_stat };
- gpr_timespec intervals[kNumIntervals] = {{60, 0}, {3600, 0}};
- my_stat stat;
- my_stat sums[kNumIntervals];
- census_window_stats_sums result[kNumIntervals];
- struct census_window_stats* stats
- = census_window_stats_create(kNumIntervals, intervals, kNumBuckets,
- &kMyStatInfo);
- // Record a new event, taking 15.3ms, transferring 1784 bytes.
- stat.latency = 0.153;
- stat.bytes = 1784;
- census_window_stats_add(stats, gpr_now(GPR_CLOCK_REALTIME), &stat);
- // Get sums and print them out
- result[kMinInterval].statistic = &sums[kMinInterval];
- result[kHourInterval].statistic = &sums[kHourInterval];
- census_window_stats_get_sums(stats, gpr_now(GPR_CLOCK_REALTIME), result);
- printf("%d events/min, average time %gs, average bytes %g\n",
- result[kMinInterval].count,
- (my_stat*)result[kMinInterval].statistic->latency /
- result[kMinInterval].count,
- (my_stat*)result[kMinInterval].statistic->bytes /
- result[kMinInterval].count
- );
- printf("%d events/hr, average time %gs, average bytes %g\n",
- result[kHourInterval].count,
- (my_stat*)result[kHourInterval].statistic->latency /
- result[kHourInterval].count,
- (my_stat*)result[kHourInterval].statistic->bytes /
- result[kHourInterval].count
- );
-*/
-
-/* Opaque structure for representing window_stats object */
-struct census_window_stats;
-
-/* Information provided by API user on the information they want to record */
-typedef struct census_window_stats_stat_info {
- /* Number of bytes in user-defined object. */
- size_t stat_size;
- /* Function to initialize a user-defined statistics object. If this is set
- * to NULL, then the object will be zero-initialized. */
- void (*stat_initialize)(void *stat);
- /* Function to add one user-defined statistics object ('addme') to 'base' */
- void (*stat_add)(void *base, const void *addme);
- /* As for previous function, but only add a proportion 'p'. This API will
- currently only use 'p' values in the range [0,1], but other values are
- possible in the future, and should be supported. */
- void (*stat_add_proportion)(double p, void *base, const void *addme);
-} census_window_stats_stat_info;
-
-/* Create a new window_stats object. 'nintervals' is the number of
- 'intervals', and must be >=1. 'granularity' is the number of buckets, with
- a larger number using more memory, but providing greater accuracy of
- results. 'granularity should be > 2. We also require that each interval be
- at least 10 * 'granularity' nanoseconds in size. 'stat_info' contains
- information about the statistic to be gathered. Intervals greater than ~192
- years will be treated as essentially infinite in size. This function will
- GPR_ASSERT() if the object cannot be created or any of the parameters have
- invalid values. This function is thread-safe. */
-struct census_window_stats *census_window_stats_create(
- int nintervals, const gpr_timespec intervals[], int granularity,
- const census_window_stats_stat_info *stat_info);
-
-/* Add a new measurement (in 'stat_value'), as of a given time ('when').
- This function is thread-compatible. */
-void census_window_stats_add(struct census_window_stats *wstats,
- const gpr_timespec when, const void *stat_value);
-
-/* Structure used to record a single intervals sum for a given statistic */
-typedef struct census_window_stats_sum {
- /* Total count of samples. Note that because some internal interpolation
- is performed, the count of samples returned for each interval may not be an
- integral value. */
- double count;
- /* Sum for statistic */
- void *statistic;
-} census_window_stats_sums;
-
-/* Retrieve a set of all values stored in a window_stats object 'wstats'. The
- number of 'sums' MUST be the same as the number 'nintervals' used in
- census_window_stats_create(). This function is thread-compatible. */
-void census_window_stats_get_sums(const struct census_window_stats *wstats,
- const gpr_timespec when,
- struct census_window_stats_sum sums[]);
-
-/* Destroy a window_stats object. Once this function has been called, the
- object will no longer be usable from any of the above functions (and
- calling them will most likely result in a NULL-pointer dereference or
- assertion failure). This function is thread-compatible. */
-void census_window_stats_destroy(struct census_window_stats *wstats);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_EXT_CENSUS_WINDOW_STATS_H */
diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc
new file mode 100644
index 0000000..466bf86
--- /dev/null
+++ b/src/core/ext/filters/client_channel/backup_poller.cc
@@ -0,0 +1,158 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/ext/filters/client_channel/backup_poller.h"
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/pollset.h"
+#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/support/env.h"
+#include "src/core/lib/support/string.h"
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/surface/completion_queue.h"
+
+#define DEFAULT_POLL_INTERVAL_MS 5000
+
+typedef struct backup_poller {
+ grpc_timer polling_timer;
+ grpc_closure run_poller_closure;
+ grpc_closure shutdown_closure;
+ gpr_mu* pollset_mu;
+ grpc_pollset* pollset; // guarded by pollset_mu
+ bool shutting_down; // guarded by pollset_mu
+ gpr_refcount refs;
+ gpr_refcount shutdown_refs;
+} backup_poller;
+
+static gpr_once g_once = GPR_ONCE_INIT;
+static gpr_mu g_poller_mu;
+static backup_poller* g_poller = NULL; // guarded by g_poller_mu
+// g_poll_interval_ms is set only once at the first time
+// grpc_client_channel_start_backup_polling() is called, after that it is
+// treated as const.
+static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS;
+
+static void init_globals() {
+ gpr_mu_init(&g_poller_mu);
+ char* env = gpr_getenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS");
+ if (env != NULL) {
+ int poll_interval_ms = gpr_parse_nonnegative_int(env);
+ if (poll_interval_ms == -1) {
+ gpr_log(GPR_ERROR,
+ "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %s, "
+ "default value %d will be used.",
+ env, g_poll_interval_ms);
+ } else {
+ g_poll_interval_ms = poll_interval_ms;
+ }
+ }
+ gpr_free(env);
+}
+
+static void backup_poller_shutdown_unref(grpc_exec_ctx* exec_ctx,
+ backup_poller* p) {
+ if (gpr_unref(&p->shutdown_refs)) {
+ grpc_pollset_destroy(exec_ctx, p->pollset);
+ gpr_free(p->pollset);
+ gpr_free(p);
+ }
+}
+
+static void done_poller(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
+ backup_poller_shutdown_unref(exec_ctx, (backup_poller*)arg);
+}
+
+static void g_poller_unref(grpc_exec_ctx* exec_ctx) {
+ if (gpr_unref(&g_poller->refs)) {
+ gpr_mu_lock(&g_poller_mu);
+ backup_poller* p = g_poller;
+ g_poller = NULL;
+ gpr_mu_unlock(&g_poller_mu);
+ gpr_mu_lock(p->pollset_mu);
+ p->shutting_down = true;
+ grpc_pollset_shutdown(exec_ctx, p->pollset,
+ GRPC_CLOSURE_INIT(&p->shutdown_closure, done_poller,
+ p, grpc_schedule_on_exec_ctx));
+ gpr_mu_unlock(p->pollset_mu);
+ grpc_timer_cancel(exec_ctx, &p->polling_timer);
+ }
+}
+
+static void run_poller(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
+ backup_poller* p = (backup_poller*)arg;
+ if (error != GRPC_ERROR_NONE) {
+ if (error != GRPC_ERROR_CANCELLED) {
+ GRPC_LOG_IF_ERROR("run_poller", GRPC_ERROR_REF(error));
+ }
+ backup_poller_shutdown_unref(exec_ctx, p);
+ return;
+ }
+ gpr_mu_lock(p->pollset_mu);
+ if (p->shutting_down) {
+ gpr_mu_unlock(p->pollset_mu);
+ backup_poller_shutdown_unref(exec_ctx, p);
+ return;
+ }
+ grpc_error* err = grpc_pollset_work(exec_ctx, p->pollset, NULL,
+ grpc_exec_ctx_now(exec_ctx));
+ gpr_mu_unlock(p->pollset_mu);
+ GRPC_LOG_IF_ERROR("Run client channel backup poller", err);
+ grpc_timer_init(exec_ctx, &p->polling_timer,
+ grpc_exec_ctx_now(exec_ctx) + g_poll_interval_ms,
+ &p->run_poller_closure);
+}
+
+void grpc_client_channel_start_backup_polling(
+ grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties) {
+ gpr_once_init(&g_once, init_globals);
+ if (g_poll_interval_ms == 0) {
+ return;
+ }
+ gpr_mu_lock(&g_poller_mu);
+ if (g_poller == NULL) {
+ g_poller = (backup_poller*)gpr_zalloc(sizeof(backup_poller));
+ g_poller->pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size());
+ g_poller->shutting_down = false;
+ grpc_pollset_init(g_poller->pollset, &g_poller->pollset_mu);
+ gpr_ref_init(&g_poller->refs, 0);
+ // one for timer cancellation, one for pollset shutdown
+ gpr_ref_init(&g_poller->shutdown_refs, 2);
+ GRPC_CLOSURE_INIT(&g_poller->run_poller_closure, run_poller, g_poller,
+ grpc_schedule_on_exec_ctx);
+ grpc_timer_init(exec_ctx, &g_poller->polling_timer,
+ grpc_exec_ctx_now(exec_ctx) + g_poll_interval_ms,
+ &g_poller->run_poller_closure);
+ }
+ gpr_ref(&g_poller->refs);
+ gpr_mu_unlock(&g_poller_mu);
+ grpc_pollset_set_add_pollset(exec_ctx, interested_parties, g_poller->pollset);
+}
+
+void grpc_client_channel_stop_backup_polling(
+ grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties) {
+ if (g_poll_interval_ms == 0) {
+ return;
+ }
+ grpc_pollset_set_del_pollset(exec_ctx, interested_parties, g_poller->pollset);
+ g_poller_unref(exec_ctx);
+}
diff --git a/src/core/ext/filters/client_channel/backup_poller.h b/src/core/ext/filters/client_channel/backup_poller.h
new file mode 100644
index 0000000..e993d50
--- /dev/null
+++ b/src/core/ext/filters/client_channel/backup_poller.h
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_BACKUP_POLLER_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_BACKUP_POLLER_H
+
+#include <grpc/grpc.h>
+#include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+/* Start polling \a interested_parties periodically in the timer thread */
+void grpc_client_channel_start_backup_polling(
+ grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties);
+
+/* Stop polling \a interested_parties */
+void grpc_client_channel_stop_backup_polling(
+ grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties);
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_BACKUP_POLLER_H */
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index ea5e076..00c51ba 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -31,6 +31,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
+#include "src/core/ext/filters/client_channel/backup_poller.h"
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
@@ -712,6 +713,7 @@
chand->interested_parties = grpc_pollset_set_create();
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_channel");
+ grpc_client_channel_start_backup_polling(exec_ctx, chand->interested_parties);
// Record client channel factory.
const grpc_arg *arg = grpc_channel_args_find(args->channel_args,
GRPC_ARG_CLIENT_CHANNEL_FACTORY);
@@ -790,6 +792,7 @@
if (chand->method_params_table != NULL) {
grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
}
+ grpc_client_channel_stop_backup_polling(exec_ctx, chand->interested_parties);
grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
grpc_pollset_set_destroy(exec_ctx, chand->interested_parties);
GRPC_COMBINER_UNREF(exec_ctx, chand->combiner, "client_channel");
@@ -898,7 +901,7 @@
call_data *calld = (call_data *)elem->call_data;
if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: failing %" PRIdPTR " pending batches: %s",
+ "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s",
elem->channel_data, calld, calld->waiting_for_pick_batches_count,
grpc_error_string(error));
}
@@ -940,7 +943,7 @@
channel_data *chand = (channel_data *)elem->channel_data;
call_data *calld = (call_data *)elem->call_data;
if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: sending %" PRIdPTR
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: sending %" PRIuPTR
" pending batches to subchannel_call=%p",
chand, calld, calld->waiting_for_pick_batches_count,
calld->subchannel_call);
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
index d6bdc13..85e76e6 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
@@ -611,7 +611,6 @@
case GRPC_CHANNEL_SHUTDOWN:
GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE);
break;
- case GRPC_CHANNEL_INIT:
case GRPC_CHANNEL_IDLE:
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_READY:
@@ -1790,7 +1789,6 @@
// embedded RR policy. Note that the current RR policy, if any, will stay in
// effect until an update from the new lb_call is received.
switch (glb_policy->lb_channel_connectivity) {
- case GRPC_CHANNEL_INIT:
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
/* resub. */
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index 56c261b..f0c66c68 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -20,6 +20,7 @@
#include <grpc/support/alloc.h>
+#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
@@ -42,103 +43,73 @@
/** base policy: must be first */
grpc_lb_policy base;
/** all our subchannels */
- grpc_subchannel **subchannels;
- grpc_subchannel **new_subchannels;
- size_t num_subchannels;
- size_t num_new_subchannels;
-
- grpc_closure connectivity_changed;
-
- /** remaining members are protected by the combiner */
-
- /** the selected channel */
- grpc_connected_subchannel *selected;
-
- /** the subchannel key for \a selected, or NULL if \a selected not set */
- const grpc_subchannel_key *selected_key;
-
+ grpc_lb_subchannel_list *subchannel_list;
+ /** latest pending subchannel list */
+ grpc_lb_subchannel_list *latest_pending_subchannel_list;
+ /** selected subchannel in \a subchannel_list */
+ grpc_lb_subchannel_data *selected;
/** have we started picking? */
bool started_picking;
/** are we shut down? */
bool shutdown;
- /** are we updating the selected subchannel? */
- bool updating_selected;
- /** are we updating the subchannel candidates? */
- bool updating_subchannels;
- /** args from the latest update received while already updating, or NULL */
- grpc_lb_policy_args *pending_update_args;
- /** which subchannel are we watching? */
- size_t checking_subchannel;
- /** what is the connectivity of that channel? */
- grpc_connectivity_state checking_connectivity;
/** list of picks that are waiting on connectivity */
pending_pick *pending_picks;
-
/** our connectivity state tracker */
grpc_connectivity_state_tracker state_tracker;
} pick_first_lb_policy;
static void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
+ GPR_ASSERT(p->subchannel_list == NULL);
+ GPR_ASSERT(p->latest_pending_subchannel_list == NULL);
GPR_ASSERT(p->pending_picks == NULL);
- for (size_t i = 0; i < p->num_subchannels; i++) {
- GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i], "pick_first_destroy");
- }
- if (p->selected != NULL) {
- GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, p->selected,
- "picked_first_destroy");
- }
grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker);
- grpc_subchannel_index_unref();
- if (p->pending_update_args != NULL) {
- grpc_channel_args_destroy(exec_ctx, p->pending_update_args->args);
- gpr_free(p->pending_update_args);
- }
- gpr_free(p->subchannels);
- gpr_free(p->new_subchannels);
gpr_free(p);
+ grpc_subchannel_index_unref();
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_DEBUG, "Pick First %p destroyed.", (void *)p);
}
}
-static void fail_pending_picks_for_shutdown(grpc_exec_ctx *exec_ctx,
- pick_first_lb_policy *p) {
+static void shutdown_locked(grpc_exec_ctx *exec_ctx, pick_first_lb_policy *p,
+ grpc_error *error) {
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG, "Pick First %p Shutting down", p);
+ }
+ p->shutdown = true;
pending_pick *pp;
while ((pp = p->pending_picks) != NULL) {
p->pending_picks = pp->next;
*pp->target = NULL;
- GRPC_CLOSURE_SCHED(
- exec_ctx, pp->on_complete,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"));
+ GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_REF(error));
gpr_free(pp);
}
+ grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
+ GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
+ "shutdown");
+ if (p->subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
+ "pf_shutdown");
+ p->subchannel_list = NULL;
+ }
+ if (p->latest_pending_subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->latest_pending_subchannel_list, "pf_shutdown");
+ p->latest_pending_subchannel_list = NULL;
+ }
+ GRPC_ERROR_UNREF(error);
}
static void pf_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- p->shutdown = true;
- fail_pending_picks_for_shutdown(exec_ctx, p);
- grpc_connectivity_state_set(
- exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"), "shutdown");
- /* cancel subscription */
- if (p->selected != NULL) {
- grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, p->selected, NULL, NULL, &p->connectivity_changed);
- } else if (p->num_subchannels > 0 && p->started_picking) {
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL,
- &p->connectivity_changed);
- }
+ shutdown_locked(exec_ctx, (pick_first_lb_policy *)pol,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"));
}
static void pf_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
grpc_connected_subchannel **target,
grpc_error *error) {
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- pending_pick *pp;
- pp = p->pending_picks;
+ pending_pick *pp = p->pending_picks;
p->pending_picks = NULL;
while (pp != NULL) {
pending_pick *next = pp->next;
@@ -162,8 +133,7 @@
uint32_t initial_metadata_flags_eq,
grpc_error *error) {
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- pending_pick *pp;
- pp = p->pending_picks;
+ pending_pick *pp = p->pending_picks;
p->pending_picks = NULL;
while (pp != NULL) {
pending_pick *next = pp->next;
@@ -185,15 +155,12 @@
static void start_picking_locked(grpc_exec_ctx *exec_ctx,
pick_first_lb_policy *p) {
p->started_picking = true;
- if (p->subchannels != NULL) {
- GPR_ASSERT(p->num_subchannels > 0);
- p->checking_subchannel = 0;
- p->checking_connectivity = GRPC_CHANNEL_IDLE;
- GRPC_LB_POLICY_WEAK_REF(&p->base, "pick_first_connectivity");
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
+ if (p->subchannel_list != NULL && p->subchannel_list->num_subchannels > 0) {
+ p->subchannel_list->checking_subchannel = 0;
+ grpc_lb_subchannel_list_ref_for_connectivity_watch(
+ p->subchannel_list, "connectivity_watch+start_picking");
+ grpc_lb_subchannel_data_start_connectivity_watch(
+ exec_ctx, &p->subchannel_list->subchannels[0]);
}
}
@@ -210,19 +177,17 @@
grpc_call_context_element *context, void **user_data,
grpc_closure *on_complete) {
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- pending_pick *pp;
-
- /* Check atomically for a selected channel */
+ // If we have a selected subchannel already, return synchronously.
if (p->selected != NULL) {
- *target = GRPC_CONNECTED_SUBCHANNEL_REF(p->selected, "picked");
+ *target = GRPC_CONNECTED_SUBCHANNEL_REF(p->selected->connected_subchannel,
+ "picked");
return 1;
}
-
- /* No subchannel selected yet, so try again */
+ // No subchannel selected yet, so handle asynchronously.
if (!p->started_picking) {
start_picking_locked(exec_ctx, p);
}
- pp = (pending_pick *)gpr_malloc(sizeof(*pp));
+ pending_pick *pp = (pending_pick *)gpr_malloc(sizeof(*pp));
pp->next = p->pending_picks;
pp->target = target;
pp->initial_metadata_flags = pick_args->initial_metadata_flags;
@@ -231,19 +196,15 @@
return 0;
}
-static void destroy_subchannels_locked(grpc_exec_ctx *exec_ctx,
- pick_first_lb_policy *p) {
- size_t num_subchannels = p->num_subchannels;
- grpc_subchannel **subchannels = p->subchannels;
-
- p->num_subchannels = 0;
- p->subchannels = NULL;
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "destroy_subchannels");
-
- for (size_t i = 0; i < num_subchannels; i++) {
- GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannels[i], "pick_first");
+static void destroy_unselected_subchannels_locked(grpc_exec_ctx *exec_ctx,
+ pick_first_lb_policy *p) {
+ for (size_t i = 0; i < p->subchannel_list->num_subchannels; ++i) {
+ grpc_lb_subchannel_data *sd = &p->subchannel_list->subchannels[i];
+ if (p->selected != sd) {
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
+ "selected_different_subchannel");
+ }
}
- gpr_free(subchannels);
}
static grpc_connectivity_state pf_check_connectivity_locked(
@@ -265,46 +226,24 @@
grpc_closure *closure) {
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
if (p->selected) {
- grpc_connected_subchannel_ping(exec_ctx, p->selected, closure);
+ grpc_connected_subchannel_ping(exec_ctx, p->selected->connected_subchannel,
+ closure);
} else {
GRPC_CLOSURE_SCHED(exec_ctx, closure,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
}
}
-/* unsubscribe all subchannels */
-static void stop_connectivity_watchers(grpc_exec_ctx *exec_ctx,
- pick_first_lb_policy *p) {
- if (p->num_subchannels > 0) {
- GPR_ASSERT(p->selected == NULL);
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(GPR_DEBUG, "Pick First %p unsubscribing from subchannel %p",
- (void *)p, (void *)p->subchannels[p->checking_subchannel]);
- }
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL,
- &p->connectivity_changed);
- p->updating_subchannels = true;
- } else if (p->selected != NULL) {
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(GPR_DEBUG,
- "Pick First %p unsubscribing from selected subchannel %p",
- (void *)p, (void *)p->selected);
- }
- grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, p->selected, NULL, NULL, &p->connectivity_changed);
- p->updating_selected = true;
- }
-}
+static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error);
-/* true upon success */
static void pf_update_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
const grpc_lb_policy_args *args) {
pick_first_lb_policy *p = (pick_first_lb_policy *)policy;
const grpc_arg *arg =
grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
if (arg == NULL || arg->type != GRPC_ARG_POINTER) {
- if (p->subchannels == NULL) {
+ if (p->subchannel_list == NULL) {
// If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
@@ -321,270 +260,222 @@
}
const grpc_lb_addresses *addresses =
(const grpc_lb_addresses *)arg->value.pointer.p;
- if (addresses->num_addresses == 0) {
- // Empty update. Unsubscribe from all current subchannels and put the
- // channel in TRANSIENT_FAILURE.
- grpc_connectivity_state_set(
- exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
- "pf_update_empty");
- stop_connectivity_watchers(exec_ctx, p);
- return;
- }
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO, "Pick First %p received update with %lu addresses",
(void *)p, (unsigned long)addresses->num_addresses);
}
- grpc_subchannel_args *sc_args = (grpc_subchannel_args *)gpr_zalloc(
- sizeof(*sc_args) * addresses->num_addresses);
- /* We remove the following keys in order for subchannel keys belonging to
- * subchannels point to the same address to match. */
- static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
- GRPC_ARG_LB_ADDRESSES};
- size_t sc_args_count = 0;
-
- /* Create list of subchannel args for new addresses in \a args. */
- for (size_t i = 0; i < addresses->num_addresses; i++) {
- // If there were any balancer, we would have chosen grpclb policy instead.
- GPR_ASSERT(!addresses->addresses[i].is_balancer);
- if (addresses->addresses[i].user_data != NULL) {
- gpr_log(GPR_ERROR,
- "This LB policy doesn't support user data. It will be ignored");
+ grpc_lb_subchannel_list *subchannel_list = grpc_lb_subchannel_list_create(
+ exec_ctx, &p->base, &grpc_lb_pick_first_trace, addresses, args,
+ pf_connectivity_changed_locked);
+ if (subchannel_list->num_subchannels == 0) {
+ // Empty update or no valid subchannels. Unsubscribe from all current
+ // subchannels and put the channel in TRANSIENT_FAILURE.
+ grpc_connectivity_state_set(
+ exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
+ "pf_update_empty");
+ if (p->subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
+ "sl_shutdown_empty_update");
}
- grpc_arg addr_arg =
- grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
- grpc_channel_args *new_args = grpc_channel_args_copy_and_add_and_remove(
- args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg,
- 1);
- gpr_free(addr_arg.value.string);
- sc_args[sc_args_count++].args = new_args;
+ p->subchannel_list = subchannel_list; // Empty list.
+ p->selected = NULL;
+ return;
}
-
- /* Check if p->selected is amongst them. If so, we are done. */
- if (p->selected != NULL) {
- GPR_ASSERT(p->selected_key != NULL);
- for (size_t i = 0; i < sc_args_count; i++) {
- grpc_subchannel_key *ith_sc_key = grpc_subchannel_key_create(&sc_args[i]);
- const bool found_selected =
- grpc_subchannel_key_compare(p->selected_key, ith_sc_key) == 0;
- grpc_subchannel_key_destroy(exec_ctx, ith_sc_key);
- if (found_selected) {
+ if (p->selected == NULL) {
+ // We don't yet have a selected subchannel, so replace the current
+ // subchannel list immediately.
+ if (p->subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
+ "pf_update_before_selected");
+ }
+ p->subchannel_list = subchannel_list;
+ } else {
+ // We do have a selected subchannel.
+ // Check if it's present in the new list. If so, we're done.
+ for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
+ grpc_lb_subchannel_data *sd = &subchannel_list->subchannels[i];
+ if (sd->subchannel == p->selected->subchannel) {
// The currently selected subchannel is in the update: we are done.
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
- "Pick First %p found already selected subchannel %p amongst "
- "updates. Update done.",
- (void *)p, (void *)p->selected);
+ "Pick First %p found already selected subchannel %p "
+ "at update index %" PRIuPTR " of %" PRIuPTR "; update done",
+ p, p->selected->subchannel, i,
+ subchannel_list->num_subchannels);
}
- for (size_t j = 0; j < sc_args_count; j++) {
- grpc_channel_args_destroy(exec_ctx,
- (grpc_channel_args *)sc_args[j].args);
+ grpc_lb_subchannel_list_ref_for_connectivity_watch(
+ subchannel_list, "connectivity_watch+replace_selected");
+ grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
+ if (p->subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->subchannel_list, "pf_update_includes_selected");
}
- gpr_free(sc_args);
+ p->subchannel_list = subchannel_list;
+ if (p->selected->connected_subchannel != NULL) {
+ sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+ p->selected->connected_subchannel, "pf_update_includes_selected");
+ }
+ p->selected = sd;
+ destroy_unselected_subchannels_locked(exec_ctx, p);
+ // If there was a previously pending update (which may or may
+ // not have contained the currently selected subchannel), drop
+ // it, so that it doesn't override what we've done here.
+ if (p->latest_pending_subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->latest_pending_subchannel_list,
+ "pf_update_includes_selected+outdated");
+ p->latest_pending_subchannel_list = NULL;
+ }
return;
}
}
- }
- // We only check for already running updates here because if the previous
- // steps were successful, the update can be considered done without any
- // interference (ie, no callbacks were scheduled).
- if (p->updating_selected || p->updating_subchannels) {
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(GPR_INFO,
- "Update already in progress for pick first %p. Deferring update.",
- (void *)p);
+ // Not keeping the previous selected subchannel, so set the latest
+ // pending subchannel list to the new subchannel list. We will wait
+ // for it to report READY before swapping it into the current
+ // subchannel list.
+ if (p->latest_pending_subchannel_list != NULL) {
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG,
+ "Pick First %p Shutting down latest pending subchannel list "
+ "%p, about to be replaced by newer latest %p",
+ (void *)p, (void *)p->latest_pending_subchannel_list,
+ (void *)subchannel_list);
+ }
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->latest_pending_subchannel_list,
+ "sl_outdated_dont_smash");
}
- if (p->pending_update_args != NULL) {
- grpc_channel_args_destroy(exec_ctx, p->pending_update_args->args);
- gpr_free(p->pending_update_args);
- }
- p->pending_update_args =
- (grpc_lb_policy_args *)gpr_zalloc(sizeof(*p->pending_update_args));
- p->pending_update_args->client_channel_factory =
- args->client_channel_factory;
- p->pending_update_args->args = grpc_channel_args_copy(args->args);
- p->pending_update_args->combiner = args->combiner;
- return;
+ p->latest_pending_subchannel_list = subchannel_list;
}
- /* Create the subchannels for the new subchannel args/addresses. */
- grpc_subchannel **new_subchannels =
- (grpc_subchannel **)gpr_zalloc(sizeof(*new_subchannels) * sc_args_count);
- size_t num_new_subchannels = 0;
- for (size_t i = 0; i < sc_args_count; i++) {
- grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
- exec_ctx, args->client_channel_factory, &sc_args[i]);
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- char *address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
- gpr_log(GPR_INFO,
- "Pick First %p created subchannel %p for address uri %s",
- (void *)p, (void *)subchannel, address_uri);
- gpr_free(address_uri);
- }
- grpc_channel_args_destroy(exec_ctx, (grpc_channel_args *)sc_args[i].args);
- if (subchannel != NULL) new_subchannels[num_new_subchannels++] = subchannel;
- }
- gpr_free(sc_args);
- if (num_new_subchannels == 0) {
- gpr_free(new_subchannels);
- // Empty update. Unsubscribe from all current subchannels and put the
- // channel in TRANSIENT_FAILURE.
- grpc_connectivity_state_set(
- exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("No valid addresses in update"),
- "pf_update_no_valid_addresses");
- stop_connectivity_watchers(exec_ctx, p);
- return;
- }
-
- /* Destroy the current subchannels. Repurpose pf_shutdown/destroy. */
- stop_connectivity_watchers(exec_ctx, p);
-
- /* Save new subchannels. The switch over will happen in
- * pf_connectivity_changed_locked */
- if (p->updating_selected || p->updating_subchannels) {
- p->num_new_subchannels = num_new_subchannels;
- p->new_subchannels = new_subchannels;
- } else { /* nothing is updating. Get things moving from here */
- p->num_subchannels = num_new_subchannels;
- p->subchannels = new_subchannels;
- p->new_subchannels = NULL;
- p->num_new_subchannels = 0;
- if (p->started_picking) {
- p->checking_subchannel = 0;
- p->checking_connectivity = GRPC_CHANNEL_IDLE;
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
- }
+ // If we've started picking, start trying to connect to the first
+ // subchannel in the new list.
+ if (p->started_picking) {
+ grpc_lb_subchannel_list_ref_for_connectivity_watch(
+ subchannel_list, "connectivity_watch+update");
+ grpc_lb_subchannel_data_start_connectivity_watch(
+ exec_ctx, &subchannel_list->subchannels[0]);
}
}
static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)arg;
- grpc_subchannel *selected_subchannel;
- pending_pick *pp;
-
+ grpc_lb_subchannel_data *sd = (grpc_lb_subchannel_data *)arg;
+ pick_first_lb_policy *p = (pick_first_lb_policy *)sd->subchannel_list->policy;
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(
- GPR_DEBUG,
- "Pick First %p connectivity changed. Updating selected: %d; Updating "
- "subchannels: %d; Checking %lu index (%lu total); State: %d; ",
- (void *)p, p->updating_selected, p->updating_subchannels,
- (unsigned long)p->checking_subchannel,
- (unsigned long)p->num_subchannels, p->checking_connectivity);
+ gpr_log(GPR_DEBUG,
+ "Pick First %p connectivity changed for subchannel %p (%" PRIuPTR
+ " of %" PRIuPTR
+ "), subchannel_list %p: state=%s p->shutdown=%d "
+ "sd->subchannel_list->shutting_down=%d error=%s",
+ (void *)p, (void *)sd->subchannel,
+ sd->subchannel_list->checking_subchannel,
+ sd->subchannel_list->num_subchannels, (void *)sd->subchannel_list,
+ grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe),
+ p->shutdown, sd->subchannel_list->shutting_down,
+ grpc_error_string(error));
}
- bool restart = false;
- if (p->updating_selected && error != GRPC_ERROR_NONE) {
- /* Captured the unsubscription for p->selected */
- GPR_ASSERT(p->selected != NULL);
- GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, p->selected,
- "pf_update_connectivity");
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(GPR_DEBUG, "Pick First %p unreffing selected subchannel %p",
- (void *)p, (void *)p->selected);
- }
- p->updating_selected = false;
- if (p->num_new_subchannels == 0) {
+ // If the policy is shutting down, unref and return.
+ if (p->shutdown) {
+ grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "pf_shutdown");
+ grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ exec_ctx, sd->subchannel_list, "pf_shutdown");
+ return;
+ }
+ // If the subchannel list is shutting down, stop watching.
+ if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
+ grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "pf_sl_shutdown");
+ grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ exec_ctx, sd->subchannel_list, "pf_sl_shutdown");
+ return;
+ }
+ // If we're still here, the notification must be for a subchannel in
+ // either the current or latest pending subchannel lists.
+ GPR_ASSERT(sd->subchannel_list == p->subchannel_list ||
+ sd->subchannel_list == p->latest_pending_subchannel_list);
+ // Update state.
+ sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
+ // Handle updates for the currently selected subchannel.
+ if (p->selected == sd) {
+ // If the new state is anything other than READY and there is a
+ // pending update, switch to the pending update.
+ if (sd->curr_connectivity_state != GRPC_CHANNEL_READY &&
+ p->latest_pending_subchannel_list != NULL) {
p->selected = NULL;
- return;
- }
- restart = true;
- }
- if (p->updating_subchannels && error != GRPC_ERROR_NONE) {
- /* Captured the unsubscription for the checking subchannel */
- GPR_ASSERT(p->selected == NULL);
- for (size_t i = 0; i < p->num_subchannels; i++) {
- GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i],
- "pf_update_connectivity");
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(GPR_DEBUG, "Pick First %p unreffing subchannel %p", (void *)p,
- (void *)p->subchannels[i]);
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->subchannel_list, "selected_not_ready+switch_to_update");
+ p->subchannel_list = p->latest_pending_subchannel_list;
+ p->latest_pending_subchannel_list = NULL;
+ grpc_connectivity_state_set(
+ exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ GRPC_ERROR_REF(error), "selected_not_ready+switch_to_update");
+ } else {
+ if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+ /* if the selected channel goes bad, we're done */
+ sd->curr_connectivity_state = GRPC_CHANNEL_SHUTDOWN;
+ }
+ grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
+ sd->curr_connectivity_state,
+ GRPC_ERROR_REF(error), "selected_changed");
+ if (sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
+ // Renew notification.
+ grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
+ } else {
+ grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
+ grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ exec_ctx, sd->subchannel_list, "pf_selected_shutdown");
+ shutdown_locked(exec_ctx, p, GRPC_ERROR_REF(error));
}
}
- gpr_free(p->subchannels);
- p->subchannels = NULL;
- p->num_subchannels = 0;
- p->updating_subchannels = false;
- if (p->num_new_subchannels == 0) return;
- restart = true;
- }
- if (restart) {
- p->selected = NULL;
- p->selected_key = NULL;
- GPR_ASSERT(p->new_subchannels != NULL);
- GPR_ASSERT(p->num_new_subchannels > 0);
- p->num_subchannels = p->num_new_subchannels;
- p->subchannels = p->new_subchannels;
- p->num_new_subchannels = 0;
- p->new_subchannels = NULL;
- if (p->started_picking) {
- /* If we were picking, continue to do so over the new subchannels,
- * starting from the 0th index. */
- p->checking_subchannel = 0;
- p->checking_connectivity = GRPC_CHANNEL_IDLE;
- /* reuses the weak ref from start_picking_locked */
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
- }
- if (p->pending_update_args != NULL) {
- const grpc_lb_policy_args *args = p->pending_update_args;
- p->pending_update_args = NULL;
- pf_update_locked(exec_ctx, &p->base, args);
- }
return;
}
- GRPC_ERROR_REF(error);
- if (p->shutdown) {
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity");
- GRPC_ERROR_UNREF(error);
- return;
- } else if (p->selected != NULL) {
- if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- /* if the selected channel goes bad, we're done */
- p->checking_connectivity = GRPC_CHANNEL_SHUTDOWN;
- }
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- p->checking_connectivity, GRPC_ERROR_REF(error),
- "selected_changed");
- if (p->checking_connectivity != GRPC_CHANNEL_SHUTDOWN) {
- grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, p->selected, p->base.interested_parties,
- &p->checking_connectivity, &p->connectivity_changed);
- } else {
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity");
- }
- } else {
- loop:
- switch (p->checking_connectivity) {
- case GRPC_CHANNEL_INIT:
- GPR_UNREACHABLE_CODE(return );
- case GRPC_CHANNEL_READY:
+ // If we get here, there are two possible cases:
+ // 1. We do not currently have a selected subchannel, and the update is
+ // for a subchannel in p->subchannel_list that we're trying to
+ // connect to. The goal here is to find a subchannel that we can
+ // select.
+ // 2. We do currently have a selected subchannel, and the update is
+ // for a subchannel in p->latest_pending_subchannel_list. The
+ // goal here is to find a subchannel from the update that we can
+ // select in place of the current one.
+ if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
+ sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+ grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
+ }
+ while (true) {
+ switch (sd->curr_connectivity_state) {
+ case GRPC_CHANNEL_READY: {
+ // Case 2. Promote p->latest_pending_subchannel_list to
+ // p->subchannel_list.
+ if (sd->subchannel_list == p->latest_pending_subchannel_list) {
+ GPR_ASSERT(p->subchannel_list != NULL);
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->subchannel_list, "finish_update");
+ p->subchannel_list = p->latest_pending_subchannel_list;
+ p->latest_pending_subchannel_list = NULL;
+ }
+ // Cases 1 and 2.
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
"connecting_ready");
- selected_subchannel = p->subchannels[p->checking_subchannel];
- p->selected = GRPC_CONNECTED_SUBCHANNEL_REF(
- grpc_subchannel_get_connected_subchannel(selected_subchannel),
- "picked_first");
-
+ sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+ grpc_subchannel_get_connected_subchannel(sd->subchannel),
+ "connected");
+ p->selected = sd;
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(GPR_INFO,
- "Pick First %p selected subchannel %p (connected %p)",
- (void *)p, (void *)selected_subchannel, (void *)p->selected);
+ gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", (void *)p,
+ (void *)sd->subchannel);
}
- p->selected_key = grpc_subchannel_get_key(selected_subchannel);
- /* drop the pick list: we are connected now */
- GRPC_LB_POLICY_WEAK_REF(&p->base, "destroy_subchannels");
- destroy_subchannels_locked(exec_ctx, p);
- /* update any calls that were waiting for a pick */
+ // Drop all other subchannels, since we are now connected.
+ destroy_unselected_subchannels_locked(exec_ctx, p);
+ // Update any calls that were waiting for a pick.
+ pending_pick *pp;
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
- *pp->target = GRPC_CONNECTED_SUBCHANNEL_REF(p->selected, "picked");
+ *pp->target = GRPC_CONNECTED_SUBCHANNEL_REF(
+ p->selected->connected_subchannel, "picked");
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO,
"Servicing pending pick with selected subchannel %p",
@@ -593,71 +484,86 @@
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
}
- grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, p->selected, p->base.interested_parties,
- &p->checking_connectivity, &p->connectivity_changed);
- break;
- case GRPC_CHANNEL_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
- */
+ // Renew notification.
+ grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
+ return;
+ }
+ case GRPC_CHANNEL_TRANSIENT_FAILURE: {
+ do {
+ sd->subchannel_list->checking_subchannel =
+ (sd->subchannel_list->checking_subchannel + 1) %
+ sd->subchannel_list->num_subchannels;
+ sd = &sd->subchannel_list
+ ->subchannels[sd->subchannel_list->checking_subchannel];
+ } while (sd->subchannel == NULL);
+ // Case 1: Only set state to TRANSIENT_FAILURE if we've tried
+ // all subchannels.
+ if (sd->subchannel_list->checking_subchannel == 0 &&
+ sd->subchannel_list == p->subchannel_list) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connecting_transient_failure");
}
+ sd->curr_connectivity_state =
+ grpc_subchannel_check_connectivity(sd->subchannel, &error);
GRPC_ERROR_UNREF(error);
- p->checking_connectivity = grpc_subchannel_check_connectivity(
- p->subchannels[p->checking_subchannel], &error);
- if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
- } else {
- goto loop;
+ if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+ // Reuses the connectivity refs from the previous watch.
+ grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
+ return;
}
- break;
+ break; // Go back to top of loop.
+ }
case GRPC_CHANNEL_CONNECTING:
- case GRPC_CHANNEL_IDLE:
- grpc_connectivity_state_set(
- exec_ctx, &p->state_tracker, GRPC_CHANNEL_CONNECTING,
- GRPC_ERROR_REF(error), "connecting_changed");
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
- break;
- case GRPC_CHANNEL_SHUTDOWN:
- p->num_subchannels--;
- GPR_SWAP(grpc_subchannel *, p->subchannels[p->checking_subchannel],
- p->subchannels[p->num_subchannels]);
- GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[p->num_subchannels],
- "pick_first");
- if (p->num_subchannels == 0) {
+ case GRPC_CHANNEL_IDLE: {
+ // Only update connectivity state in case 1.
+ if (sd->subchannel_list == p->subchannel_list) {
grpc_connectivity_state_set(
- exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Pick first exhausted channels", &error, 1),
- "no_more_channels");
- fail_pending_picks_for_shutdown(exec_ctx, p);
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base,
- "pick_first_connectivity");
- } else {
+ exec_ctx, &p->state_tracker, GRPC_CHANNEL_CONNECTING,
+ GRPC_ERROR_REF(error), "connecting_changed");
+ }
+ // Renew notification.
+ grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
+ return;
+ }
+ case GRPC_CHANNEL_SHUTDOWN: {
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
+ "pf_candidate_shutdown");
+ // Advance to next subchannel and check its state.
+ grpc_lb_subchannel_data *original_sd = sd;
+ do {
+ sd->subchannel_list->checking_subchannel =
+ (sd->subchannel_list->checking_subchannel + 1) %
+ sd->subchannel_list->num_subchannels;
+ sd = &sd->subchannel_list
+ ->subchannels[sd->subchannel_list->checking_subchannel];
+ } while (sd->subchannel == NULL && sd != original_sd);
+ if (sd == original_sd) {
+ grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ exec_ctx, sd->subchannel_list, "pf_candidate_shutdown");
+ shutdown_locked(exec_ctx, p,
+ GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+ "Pick first exhausted channels", &error, 1));
+ return;
+ }
+ if (sd->subchannel_list == p->subchannel_list) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "subchannel_failed");
- p->checking_subchannel %= p->num_subchannels;
- GRPC_ERROR_UNREF(error);
- p->checking_connectivity = grpc_subchannel_check_connectivity(
- p->subchannels[p->checking_subchannel], &error);
- goto loop;
}
+ sd->curr_connectivity_state =
+ grpc_subchannel_check_connectivity(sd->subchannel, &error);
+ GRPC_ERROR_UNREF(error);
+ if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+ // Reuses the connectivity refs from the previous watch.
+ grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
+ return;
+ }
+ // For any other state, go back to top of loop.
+ // We will reuse the connectivity refs from the previous watch.
+ }
}
}
-
- GRPC_ERROR_UNREF(error);
}
static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = {
@@ -687,8 +593,6 @@
pf_update_locked(exec_ctx, &p->base, args);
grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable, args->combiner);
grpc_subchannel_index_ref();
- GRPC_CLOSURE_INIT(&p->connectivity_changed, pf_connectivity_changed_locked, p,
- grpc_combiner_scheduler(args->combiner));
return &p->base;
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index de163f6..8f29c80 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -28,6 +28,7 @@
#include <grpc/support/alloc.h>
+#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
@@ -64,12 +65,11 @@
grpc_closure *on_complete;
} pending_pick;
-typedef struct rr_subchannel_list rr_subchannel_list;
typedef struct round_robin_lb_policy {
/** base policy: must be first */
grpc_lb_policy base;
- rr_subchannel_list *subchannel_list;
+ grpc_lb_subchannel_list *subchannel_list;
/** have we started picking? */
bool started_picking;
@@ -89,157 +89,9 @@
* lists if they equal \a latest_pending_subchannel_list. In other words,
* racing callbacks that reference outdated subchannel lists won't perform any
* update. */
- rr_subchannel_list *latest_pending_subchannel_list;
+ grpc_lb_subchannel_list *latest_pending_subchannel_list;
} round_robin_lb_policy;
-typedef struct {
- /** backpointer to owning subchannel list */
- rr_subchannel_list *subchannel_list;
- /** subchannel itself */
- grpc_subchannel *subchannel;
- /** notification that connectivity has changed on subchannel */
- grpc_closure connectivity_changed_closure;
- /** last observed connectivity. Not updated by
- * \a grpc_subchannel_notify_on_state_change. Used to determine the previous
- * state while processing the new state in \a rr_connectivity_changed */
- grpc_connectivity_state prev_connectivity_state;
- /** current connectivity state. Updated by \a
- * grpc_subchannel_notify_on_state_change */
- grpc_connectivity_state curr_connectivity_state;
- /** connectivity state to be updated by the watcher, not guarded by
- * the combiner. Will be moved to curr_connectivity_state inside of
- * the combiner by rr_connectivity_changed_locked(). */
- grpc_connectivity_state pending_connectivity_state_unsafe;
- /** the subchannel's target user data */
- void *user_data;
- /** vtable to operate over \a user_data */
- const grpc_lb_user_data_vtable *user_data_vtable;
-} subchannel_data;
-
-struct rr_subchannel_list {
- /** backpointer to owning policy */
- round_robin_lb_policy *policy;
-
- /** all our subchannels */
- size_t num_subchannels;
- subchannel_data *subchannels;
-
- /** how many subchannels are in state READY */
- size_t num_ready;
- /** how many subchannels are in state TRANSIENT_FAILURE */
- size_t num_transient_failures;
- /** how many subchannels are in state SHUTDOWN */
- size_t num_shutdown;
- /** how many subchannels are in state IDLE */
- size_t num_idle;
-
- /** There will be one ref for each entry in subchannels for which there is a
- * pending connectivity state watcher callback. */
- gpr_refcount refcount;
-
- /** Is this list shutting down? This may be true due to the shutdown of the
- * policy itself or because a newer update has arrived while this one hadn't
- * finished processing. */
- bool shutting_down;
-};
-
-static rr_subchannel_list *rr_subchannel_list_create(round_robin_lb_policy *p,
- size_t num_subchannels) {
- rr_subchannel_list *subchannel_list =
- (rr_subchannel_list *)gpr_zalloc(sizeof(*subchannel_list));
- subchannel_list->policy = p;
- subchannel_list->subchannels =
- (subchannel_data *)gpr_zalloc(sizeof(subchannel_data) * num_subchannels);
- subchannel_list->num_subchannels = num_subchannels;
- gpr_ref_init(&subchannel_list->refcount, 1);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- gpr_log(GPR_INFO, "[RR %p] Created subchannel list %p for %lu subchannels",
- (void *)p, (void *)subchannel_list, (unsigned long)num_subchannels);
- }
- return subchannel_list;
-}
-
-static void rr_subchannel_list_destroy(grpc_exec_ctx *exec_ctx,
- rr_subchannel_list *subchannel_list) {
- GPR_ASSERT(subchannel_list->shutting_down);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- gpr_log(GPR_INFO, "[RR %p] Destroying subchannel_list %p",
- (void *)subchannel_list->policy, (void *)subchannel_list);
- }
- for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
- subchannel_data *sd = &subchannel_list->subchannels[i];
- if (sd->subchannel != NULL) {
- GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel,
- "rr_subchannel_list_destroy");
- }
- sd->subchannel = NULL;
- if (sd->user_data != NULL) {
- GPR_ASSERT(sd->user_data_vtable != NULL);
- sd->user_data_vtable->destroy(exec_ctx, sd->user_data);
- sd->user_data = NULL;
- }
- }
- gpr_free(subchannel_list->subchannels);
- gpr_free(subchannel_list);
-}
-
-static void rr_subchannel_list_ref(rr_subchannel_list *subchannel_list,
- const char *reason) {
- gpr_ref_non_zero(&subchannel_list->refcount);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
- gpr_log(GPR_INFO, "[RR %p] subchannel_list %p REF %lu->%lu (%s)",
- (void *)subchannel_list->policy, (void *)subchannel_list,
- (unsigned long)(count - 1), (unsigned long)count, reason);
- }
-}
-
-static void rr_subchannel_list_unref(grpc_exec_ctx *exec_ctx,
- rr_subchannel_list *subchannel_list,
- const char *reason) {
- const bool done = gpr_unref(&subchannel_list->refcount);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
- gpr_log(GPR_INFO, "[RR %p] subchannel_list %p UNREF %lu->%lu (%s)",
- (void *)subchannel_list->policy, (void *)subchannel_list,
- (unsigned long)(count + 1), (unsigned long)count, reason);
- }
- if (done) {
- rr_subchannel_list_destroy(exec_ctx, subchannel_list);
- }
-}
-
-/** Mark \a subchannel_list as discarded. Unsubscribes all its subchannels. The
- * watcher's callback will ultimately unref \a subchannel_list. */
-static void rr_subchannel_list_shutdown_and_unref(
- grpc_exec_ctx *exec_ctx, rr_subchannel_list *subchannel_list,
- const char *reason) {
- GPR_ASSERT(!subchannel_list->shutting_down);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- gpr_log(GPR_DEBUG, "[RR %p] Shutting down subchannel_list %p (%s)",
- (void *)subchannel_list->policy, (void *)subchannel_list, reason);
- }
- GPR_ASSERT(!subchannel_list->shutting_down);
- subchannel_list->shutting_down = true;
- for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
- subchannel_data *sd = &subchannel_list->subchannels[i];
- if (sd->subchannel != NULL) { // if subchannel isn't shutdown, unsubscribe.
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- gpr_log(
- GPR_DEBUG,
- "[RR %p] Unsubscribing from subchannel %p as part of shutting down "
- "subchannel_list %p",
- (void *)subchannel_list->policy, (void *)sd->subchannel,
- (void *)subchannel_list);
- }
- grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL,
- NULL,
- &sd->connectivity_changed_closure);
- }
- }
- rr_subchannel_list_unref(exec_ctx, subchannel_list, reason);
-}
-
/** Returns the index into p->subchannel_list->subchannels of the next
* subchannel in READY state, or p->subchannel_list->num_subchannels if no
* subchannel is READY.
@@ -299,8 +151,8 @@
"[RR %p] setting last_ready_subchannel_index=%lu (SC %p, CSC %p)",
(void *)p, (unsigned long)last_ready_index,
(void *)p->subchannel_list->subchannels[last_ready_index].subchannel,
- (void *)grpc_subchannel_get_connected_subchannel(
- p->subchannel_list->subchannels[last_ready_index].subchannel));
+ (void *)p->subchannel_list->subchannels[last_ready_index]
+ .connected_subchannel);
}
}
@@ -310,47 +162,47 @@
gpr_log(GPR_DEBUG, "[RR %p] Destroying Round Robin policy at %p",
(void *)pol, (void *)pol);
}
+ GPR_ASSERT(p->subchannel_list == NULL);
+ GPR_ASSERT(p->latest_pending_subchannel_list == NULL);
grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker);
grpc_subchannel_index_unref();
gpr_free(p);
}
-static void fail_pending_picks_for_shutdown(grpc_exec_ctx *exec_ctx,
- round_robin_lb_policy *p) {
+static void shutdown_locked(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p,
+ grpc_error *error) {
+ if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ gpr_log(GPR_DEBUG, "[RR %p] Shutting down", p);
+ }
+ p->shutdown = true;
pending_pick *pp;
while ((pp = p->pending_picks) != NULL) {
p->pending_picks = pp->next;
*pp->target = NULL;
- GRPC_CLOSURE_SCHED(
- exec_ctx, pp->on_complete,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"));
+ GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_REF(error));
gpr_free(pp);
}
+ grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
+ GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
+ "rr_shutdown");
+ if (p->subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
+ "sl_shutdown_rr_shutdown");
+ p->subchannel_list = NULL;
+ }
+ if (p->latest_pending_subchannel_list != NULL) {
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->latest_pending_subchannel_list,
+ "sl_shutdown_pending_rr_shutdown");
+ p->latest_pending_subchannel_list = NULL;
+ }
+ GRPC_ERROR_UNREF(error);
}
static void rr_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- gpr_log(GPR_DEBUG, "[RR %p] Shutting down Round Robin policy at %p",
- (void *)pol, (void *)pol);
- }
- p->shutdown = true;
- fail_pending_picks_for_shutdown(exec_ctx, p);
- grpc_connectivity_state_set(
- exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"), "rr_shutdown");
- const bool latest_is_current =
- p->subchannel_list == p->latest_pending_subchannel_list;
- rr_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
- "sl_shutdown_rr_shutdown");
- p->subchannel_list = NULL;
- if (!latest_is_current && p->latest_pending_subchannel_list != NULL &&
- !p->latest_pending_subchannel_list->shutting_down) {
- rr_subchannel_list_shutdown_and_unref(exec_ctx,
- p->latest_pending_subchannel_list,
- "sl_shutdown_pending_rr_shutdown");
- p->latest_pending_subchannel_list = NULL;
- }
+ shutdown_locked(exec_ctx, p,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"));
}
static void rr_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
@@ -405,13 +257,10 @@
round_robin_lb_policy *p) {
p->started_picking = true;
for (size_t i = 0; i < p->subchannel_list->num_subchannels; i++) {
- subchannel_data *sd = &p->subchannel_list->subchannels[i];
- GRPC_LB_POLICY_WEAK_REF(&p->base, "start_picking_locked");
- rr_subchannel_list_ref(sd->subchannel_list, "started_picking");
- grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, p->base.interested_parties,
- &sd->pending_connectivity_state_unsafe,
- &sd->connectivity_changed_closure);
+ grpc_lb_subchannel_list_ref_for_connectivity_watch(p->subchannel_list,
+ "connectivity_watch");
+ grpc_lb_subchannel_data_start_connectivity_watch(
+ exec_ctx, &p->subchannel_list->subchannels[i]);
}
}
@@ -436,10 +285,10 @@
const size_t next_ready_index = get_next_ready_subchannel_index_locked(p);
if (next_ready_index < p->subchannel_list->num_subchannels) {
/* readily available, report right away */
- subchannel_data *sd = &p->subchannel_list->subchannels[next_ready_index];
- *target = GRPC_CONNECTED_SUBCHANNEL_REF(
- grpc_subchannel_get_connected_subchannel(sd->subchannel),
- "rr_picked");
+ grpc_lb_subchannel_data *sd =
+ &p->subchannel_list->subchannels[next_ready_index];
+ *target =
+ GRPC_CONNECTED_SUBCHANNEL_REF(sd->connected_subchannel, "rr_picked");
if (user_data != NULL) {
*user_data = sd->user_data;
}
@@ -470,8 +319,8 @@
return 0;
}
-static void update_state_counters_locked(subchannel_data *sd) {
- rr_subchannel_list *subchannel_list = sd->subchannel_list;
+static void update_state_counters_locked(grpc_lb_subchannel_data *sd) {
+ grpc_lb_subchannel_list *subchannel_list = sd->subchannel_list;
if (sd->prev_connectivity_state == GRPC_CHANNEL_READY) {
GPR_ASSERT(subchannel_list->num_ready > 0);
--subchannel_list->num_ready;
@@ -485,6 +334,7 @@
GPR_ASSERT(subchannel_list->num_idle > 0);
--subchannel_list->num_idle;
}
+ sd->prev_connectivity_state = sd->curr_connectivity_state;
if (sd->curr_connectivity_state == GRPC_CHANNEL_READY) {
++subchannel_list->num_ready;
} else if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
@@ -497,12 +347,12 @@
}
/** Sets the policy's connectivity status based on that of the passed-in \a sd
- * (the subchannel_data associted with the updated subchannel) and the
+ * (the grpc_lb_subchannel_data associted with the updated subchannel) and the
* subchannel list \a sd belongs to (sd->subchannel_list). \a error will only be
* used upon policy transition to TRANSIENT_FAILURE or SHUTDOWN. Returns the
* connectivity status set. */
static grpc_connectivity_state update_lb_connectivity_status_locked(
- grpc_exec_ctx *exec_ctx, subchannel_data *sd, grpc_error *error) {
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd, grpc_error *error) {
/* In priority order. The first rule to match terminates the search (ie, if we
* are on rule n, all previous rules were unfulfilled).
*
@@ -524,8 +374,8 @@
* CHECK: p->num_idle == p->subchannel_list->num_subchannels.
*/
grpc_connectivity_state new_state = sd->curr_connectivity_state;
- rr_subchannel_list *subchannel_list = sd->subchannel_list;
- round_robin_lb_policy *p = subchannel_list->policy;
+ grpc_lb_subchannel_list *subchannel_list = sd->subchannel_list;
+ round_robin_lb_policy *p = (round_robin_lb_policy *)subchannel_list->policy;
if (subchannel_list->num_ready > 0) { /* 1) READY */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "rr_ready");
@@ -561,8 +411,9 @@
static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
- subchannel_data *sd = (subchannel_data *)arg;
- round_robin_lb_policy *p = sd->subchannel_list->policy;
+ grpc_lb_subchannel_data *sd = (grpc_lb_subchannel_data *)arg;
+ round_robin_lb_policy *p =
+ (round_robin_lb_policy *)sd->subchannel_list->policy;
if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
gpr_log(
GPR_DEBUG,
@@ -577,65 +428,50 @@
}
// If the policy is shutting down, unref and return.
if (p->shutdown) {
- rr_subchannel_list_unref(exec_ctx, sd->subchannel_list,
- "pol_shutdown+started_picking");
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pol_shutdown");
+ grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "rr_shutdown");
+ grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ exec_ctx, sd->subchannel_list, "rr_shutdown");
return;
}
- if (sd->subchannel_list->shutting_down && error == GRPC_ERROR_CANCELLED) {
- // the subchannel list associated with sd has been discarded. This callback
- // corresponds to the unsubscription. The unrefs correspond to the picking
- // ref (start_picking_locked or update_started_picking).
- rr_subchannel_list_unref(exec_ctx, sd->subchannel_list,
- "sl_shutdown+started_picking");
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "sl_shutdown+picking");
+ // If the subchannel list is shutting down, stop watching.
+ if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
+ grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "rr_sl_shutdown");
+ grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ exec_ctx, sd->subchannel_list, "rr_sl_shutdown");
return;
}
- // Dispose of outdated subchannel lists.
- if (sd->subchannel_list != p->subchannel_list &&
- sd->subchannel_list != p->latest_pending_subchannel_list) {
- const char *reason = NULL;
- if (sd->subchannel_list->shutting_down) {
- reason = "sl_outdated_straggler";
- rr_subchannel_list_unref(exec_ctx, sd->subchannel_list, reason);
- } else {
- reason = "sl_outdated";
- rr_subchannel_list_shutdown_and_unref(exec_ctx, sd->subchannel_list,
- reason);
- }
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, reason);
- return;
- }
+ // If we're still here, the notification must be for a subchannel in
+ // either the current or latest pending subchannel lists.
+ GPR_ASSERT(sd->subchannel_list == p->subchannel_list ||
+ sd->subchannel_list == p->latest_pending_subchannel_list);
// Now that we're inside the combiner, copy the pending connectivity
// state (which was set by the connectivity state watcher) to
// curr_connectivity_state, which is what we use inside of the combiner.
sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
// Update state counters and determine new overall state.
update_state_counters_locked(sd);
- sd->prev_connectivity_state = sd->curr_connectivity_state;
const grpc_connectivity_state new_policy_connectivity_state =
update_lb_connectivity_status_locked(exec_ctx, sd, GRPC_ERROR_REF(error));
// If the sd's new state is SHUTDOWN, unref the subchannel, and if the new
// policy's state is SHUTDOWN, clean up.
if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
- GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "rr_subchannel_shutdown");
- sd->subchannel = NULL;
- if (sd->user_data != NULL) {
- GPR_ASSERT(sd->user_data_vtable != NULL);
- sd->user_data_vtable->destroy(exec_ctx, sd->user_data);
- sd->user_data = NULL;
- }
+ grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
+ "rr_connectivity_shutdown");
+ grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ exec_ctx, sd->subchannel_list, "rr_connectivity_shutdown");
if (new_policy_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
- // The policy is shutting down. Fail all of the pending picks.
- fail_pending_picks_for_shutdown(exec_ctx, p);
+ shutdown_locked(exec_ctx, p, GRPC_ERROR_REF(error));
}
- rr_subchannel_list_unref(exec_ctx, sd->subchannel_list,
- "sd_shutdown+started_picking");
- // unref the "rr_connectivity_update" weak ref from start_picking.
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base,
- "rr_connectivity_sd_shutdown");
} else { // sd not in SHUTDOWN
if (sd->curr_connectivity_state == GRPC_CHANNEL_READY) {
+ if (sd->connected_subchannel == NULL) {
+ sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+ grpc_subchannel_get_connected_subchannel(sd->subchannel),
+ "connected");
+ }
if (sd->subchannel_list != p->subchannel_list) {
// promote sd->subchannel_list to p->subchannel_list.
// sd->subchannel_list must be equal to
@@ -656,8 +492,8 @@
}
if (p->subchannel_list != NULL) {
// dispose of the current subchannel_list
- rr_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
- "sl_phase_out_shutdown");
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->subchannel_list, "sl_phase_out_shutdown");
}
p->subchannel_list = p->latest_pending_subchannel_list;
p->latest_pending_subchannel_list = NULL;
@@ -667,7 +503,7 @@
* p->pending_picks. This preemtively replicates rr_pick()'s actions. */
const size_t next_ready_index = get_next_ready_subchannel_index_locked(p);
GPR_ASSERT(next_ready_index < p->subchannel_list->num_subchannels);
- subchannel_data *selected =
+ grpc_lb_subchannel_data *selected =
&p->subchannel_list->subchannels[next_ready_index];
if (p->pending_picks != NULL) {
// if the selected subchannel is going to be used for the pending
@@ -678,8 +514,7 @@
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = GRPC_CONNECTED_SUBCHANNEL_REF(
- grpc_subchannel_get_connected_subchannel(selected->subchannel),
- "rr_picked");
+ selected->connected_subchannel, "rr_picked");
if (pp->user_data != NULL) {
*pp->user_data = selected->user_data;
}
@@ -694,12 +529,8 @@
gpr_free(pp);
}
}
- /* renew notification: reuses the "rr_connectivity_update" weak ref on the
- * policy as well as the sd->subchannel_list ref. */
- grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, p->base.interested_parties,
- &sd->pending_connectivity_state_unsafe,
- &sd->connectivity_changed_closure);
+ // Renew notification.
+ grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
}
}
@@ -723,13 +554,12 @@
round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
const size_t next_ready_index = get_next_ready_subchannel_index_locked(p);
if (next_ready_index < p->subchannel_list->num_subchannels) {
- subchannel_data *selected =
+ grpc_lb_subchannel_data *selected =
&p->subchannel_list->subchannels[next_ready_index];
grpc_connected_subchannel *target = GRPC_CONNECTED_SUBCHANNEL_REF(
- grpc_subchannel_get_connected_subchannel(selected->subchannel),
- "rr_picked");
+ selected->connected_subchannel, "rr_ping");
grpc_connected_subchannel_ping(exec_ctx, target, closure);
- GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_picked");
+ GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_ping");
} else {
GRPC_CLOSURE_SCHED(exec_ctx, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Round Robin not connected"));
@@ -742,130 +572,68 @@
const grpc_arg *arg =
grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
if (arg == NULL || arg->type != GRPC_ARG_POINTER) {
+ gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", p);
+ // If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
+ // Otherwise, keep using the current subchannel list (ignore this update).
if (p->subchannel_list == NULL) {
- // If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"),
"rr_update_missing");
- } else {
- // otherwise, keep using the current subchannel list (ignore this update).
- gpr_log(GPR_ERROR,
- "[RR %p] No valid LB addresses channel arg for update, ignoring.",
- (void *)p);
}
return;
}
grpc_lb_addresses *addresses = (grpc_lb_addresses *)arg->value.pointer.p;
- rr_subchannel_list *subchannel_list =
- rr_subchannel_list_create(p, addresses->num_addresses);
- if (addresses->num_addresses == 0) {
+ if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ gpr_log(GPR_DEBUG, "[RR %p] received update with %" PRIuPTR " addresses", p,
+ addresses->num_addresses);
+ }
+ grpc_lb_subchannel_list *subchannel_list = grpc_lb_subchannel_list_create(
+ exec_ctx, &p->base, &grpc_lb_round_robin_trace, addresses, args,
+ rr_connectivity_changed_locked);
+ if (subchannel_list->num_subchannels == 0) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
"rr_update_empty");
if (p->subchannel_list != NULL) {
- rr_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
- "sl_shutdown_empty_update");
+ grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
+ "sl_shutdown_empty_update");
}
p->subchannel_list = subchannel_list; // empty list
return;
}
- size_t subchannel_index = 0;
- if (p->latest_pending_subchannel_list != NULL && p->started_picking) {
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- gpr_log(GPR_DEBUG,
- "[RR %p] Shutting down latest pending subchannel list %p, about "
- "to be replaced by newer latest %p",
- (void *)p, (void *)p->latest_pending_subchannel_list,
- (void *)subchannel_list);
+ if (p->started_picking) {
+ if (p->latest_pending_subchannel_list != NULL) {
+ if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ gpr_log(GPR_DEBUG,
+ "[RR %p] Shutting down latest pending subchannel list %p, "
+ "about to be replaced by newer latest %p",
+ (void *)p, (void *)p->latest_pending_subchannel_list,
+ (void *)subchannel_list);
+ }
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->latest_pending_subchannel_list, "sl_outdated");
}
- rr_subchannel_list_shutdown_and_unref(
- exec_ctx, p->latest_pending_subchannel_list, "sl_outdated_dont_smash");
- }
- p->latest_pending_subchannel_list = subchannel_list;
- grpc_subchannel_args sc_args;
- /* We need to remove the LB addresses in order to be able to compare the
- * subchannel keys of subchannels from a different batch of addresses. */
- static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
- GRPC_ARG_LB_ADDRESSES};
- /* Create subchannels for addresses in the update. */
- for (size_t i = 0; i < addresses->num_addresses; i++) {
- // If there were any balancer, we would have chosen grpclb policy instead.
- GPR_ASSERT(!addresses->addresses[i].is_balancer);
- memset(&sc_args, 0, sizeof(grpc_subchannel_args));
- grpc_arg addr_arg =
- grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
- grpc_channel_args *new_args = grpc_channel_args_copy_and_add_and_remove(
- args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg,
- 1);
- gpr_free(addr_arg.value.string);
- sc_args.args = new_args;
- grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
- exec_ctx, args->client_channel_factory, &sc_args);
- grpc_channel_args_destroy(exec_ctx, new_args);
- grpc_error *error;
- // Get the connectivity state of the subchannel. Already existing ones may
- // be in a state other than INIT.
- const grpc_connectivity_state subchannel_connectivity_state =
- grpc_subchannel_check_connectivity(subchannel, &error);
- if (error != GRPC_ERROR_NONE) {
- // The subchannel is in error (e.g. shutting down). Ignore it.
- GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannel, "new_sc_connectivity_error");
- GRPC_ERROR_UNREF(error);
- continue;
- }
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
- char *address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
- gpr_log(
- GPR_DEBUG,
- "[RR %p] index %lu: Created subchannel %p for address uri %s into "
- "subchannel_list %p. Connectivity state %s",
- (void *)p, (unsigned long)subchannel_index, (void *)subchannel,
- address_uri, (void *)subchannel_list,
- grpc_connectivity_state_name(subchannel_connectivity_state));
- gpr_free(address_uri);
- }
- subchannel_data *sd = &subchannel_list->subchannels[subchannel_index++];
- sd->subchannel_list = subchannel_list;
- sd->subchannel = subchannel;
- GRPC_CLOSURE_INIT(&sd->connectivity_changed_closure,
- rr_connectivity_changed_locked, sd,
- grpc_combiner_scheduler(args->combiner));
- /* use some sentinel value outside of the range of
- * grpc_connectivity_state to signal an undefined previous state. We
- * won't be referring to this value again and it'll be overwritten after
- * the first call to rr_connectivity_changed_locked */
- sd->prev_connectivity_state = GRPC_CHANNEL_INIT;
- sd->curr_connectivity_state = subchannel_connectivity_state;
- sd->user_data_vtable = addresses->user_data_vtable;
- if (sd->user_data_vtable != NULL) {
- sd->user_data =
- sd->user_data_vtable->copy(addresses->addresses[i].user_data);
- }
- if (p->started_picking) {
- rr_subchannel_list_ref(sd->subchannel_list, "update_started_picking");
- GRPC_LB_POLICY_WEAK_REF(&p->base, "rr_connectivity_update");
- /* 2. Watch every new subchannel. A subchannel list becomes active the
+ p->latest_pending_subchannel_list = subchannel_list;
+ for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
+ /* Watch every new subchannel. A subchannel list becomes active the
* moment one of its subchannels is READY. At that moment, we swap
* p->subchannel_list for sd->subchannel_list, provided the subchannel
* list is still valid (ie, isn't shutting down) */
- grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, p->base.interested_parties,
- &sd->pending_connectivity_state_unsafe,
- &sd->connectivity_changed_closure);
+ grpc_lb_subchannel_list_ref_for_connectivity_watch(subchannel_list,
+ "connectivity_watch");
+ grpc_lb_subchannel_data_start_connectivity_watch(
+ exec_ctx, &subchannel_list->subchannels[i]);
}
- }
- if (!p->started_picking) {
+ } else {
// The policy isn't picking yet. Save the update for later, disposing of
// previous version if any.
if (p->subchannel_list != NULL) {
- rr_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
- "rr_update_before_started_picking");
+ grpc_lb_subchannel_list_shutdown_and_unref(
+ exec_ctx, p->subchannel_list, "rr_update_before_started_picking");
}
p->subchannel_list = subchannel_list;
- p->latest_pending_subchannel_list = NULL;
}
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
new file mode 100644
index 0000000..08ea4f4
--- /dev/null
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
@@ -0,0 +1,265 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+
+#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/combiner.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/transport/connectivity_state.h"
+
+void grpc_lb_subchannel_data_unref_subchannel(grpc_exec_ctx *exec_ctx,
+ grpc_lb_subchannel_data *sd,
+ const char *reason) {
+ if (sd->subchannel != NULL) {
+ if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ gpr_log(
+ GPR_DEBUG, "[%s %p] subchannel list %p index %" PRIuPTR
+ " of %" PRIuPTR " (subchannel %p): unreffing subchannel",
+ sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list, (size_t)(sd - sd->subchannel_list->subchannels),
+ sd->subchannel_list->num_subchannels, sd->subchannel);
+ }
+ GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, reason);
+ sd->subchannel = NULL;
+ if (sd->connected_subchannel != NULL) {
+ GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, sd->connected_subchannel,
+ reason);
+ sd->connected_subchannel = NULL;
+ }
+ if (sd->user_data != NULL) {
+ GPR_ASSERT(sd->user_data_vtable != NULL);
+ sd->user_data_vtable->destroy(exec_ctx, sd->user_data);
+ sd->user_data = NULL;
+ }
+ }
+}
+
+void grpc_lb_subchannel_data_start_connectivity_watch(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd) {
+ if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ gpr_log(GPR_DEBUG,
+ "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): requesting connectivity change notification",
+ sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list,
+ (size_t)(sd - sd->subchannel_list->subchannels),
+ sd->subchannel_list->num_subchannels, sd->subchannel);
+ }
+ sd->connectivity_notification_pending = true;
+ grpc_subchannel_notify_on_state_change(
+ exec_ctx, sd->subchannel, sd->subchannel_list->policy->interested_parties,
+ &sd->pending_connectivity_state_unsafe,
+ &sd->connectivity_changed_closure);
+}
+
+void grpc_lb_subchannel_data_stop_connectivity_watch(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd) {
+ if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ gpr_log(
+ GPR_DEBUG, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): stopping connectivity watch",
+ sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list, (size_t)(sd - sd->subchannel_list->subchannels),
+ sd->subchannel_list->num_subchannels, sd->subchannel);
+ }
+ GPR_ASSERT(sd->connectivity_notification_pending);
+ sd->connectivity_notification_pending = false;
+}
+
+grpc_lb_subchannel_list *grpc_lb_subchannel_list_create(
+ grpc_exec_ctx *exec_ctx, grpc_lb_policy *p, grpc_tracer_flag *tracer,
+ const grpc_lb_addresses *addresses, const grpc_lb_policy_args *args,
+ grpc_iomgr_cb_func connectivity_changed_cb) {
+ grpc_lb_subchannel_list *subchannel_list =
+ (grpc_lb_subchannel_list *)gpr_zalloc(sizeof(*subchannel_list));
+ if (GRPC_TRACER_ON(*tracer)) {
+ gpr_log(GPR_DEBUG,
+ "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
+ tracer->name, p, subchannel_list, addresses->num_addresses);
+ }
+ subchannel_list->policy = p;
+ subchannel_list->tracer = tracer;
+ gpr_ref_init(&subchannel_list->refcount, 1);
+ subchannel_list->subchannels = (grpc_lb_subchannel_data *)gpr_zalloc(
+ sizeof(grpc_lb_subchannel_data) * addresses->num_addresses);
+ // We need to remove the LB addresses in order to be able to compare the
+ // subchannel keys of subchannels from a different batch of addresses.
+ static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
+ GRPC_ARG_LB_ADDRESSES};
+ // Create a subchannel for each address.
+ grpc_subchannel_args sc_args;
+ size_t subchannel_index = 0;
+ for (size_t i = 0; i < addresses->num_addresses; i++) {
+ // If there were any balancer, we would have chosen grpclb policy instead.
+ GPR_ASSERT(!addresses->addresses[i].is_balancer);
+ memset(&sc_args, 0, sizeof(grpc_subchannel_args));
+ grpc_arg addr_arg =
+ grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
+ grpc_channel_args *new_args = grpc_channel_args_copy_and_add_and_remove(
+ args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg,
+ 1);
+ gpr_free(addr_arg.value.string);
+ sc_args.args = new_args;
+ grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
+ exec_ctx, args->client_channel_factory, &sc_args);
+ grpc_channel_args_destroy(exec_ctx, new_args);
+ if (subchannel == NULL) {
+ // Subchannel could not be created.
+ if (GRPC_TRACER_ON(*tracer)) {
+ char *address_uri =
+ grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ gpr_log(GPR_DEBUG,
+ "[%s %p] could not create subchannel for address uri %s, "
+ "ignoring",
+ tracer->name, subchannel_list->policy, address_uri);
+ gpr_free(address_uri);
+ }
+ continue;
+ }
+ if (GRPC_TRACER_ON(*tracer)) {
+ char *address_uri =
+ grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ gpr_log(GPR_DEBUG, "[%s %p] subchannel list %p index %" PRIuPTR
+ ": Created subchannel %p for address uri %s",
+ tracer->name, p, subchannel_list, subchannel_index, subchannel,
+ address_uri);
+ gpr_free(address_uri);
+ }
+ grpc_lb_subchannel_data *sd =
+ &subchannel_list->subchannels[subchannel_index++];
+ sd->subchannel_list = subchannel_list;
+ sd->subchannel = subchannel;
+ GRPC_CLOSURE_INIT(&sd->connectivity_changed_closure,
+ connectivity_changed_cb, sd,
+ grpc_combiner_scheduler(args->combiner));
+ // We assume that the current state is IDLE. If not, we'll get a
+ // callback telling us that.
+ sd->prev_connectivity_state = GRPC_CHANNEL_IDLE;
+ sd->curr_connectivity_state = GRPC_CHANNEL_IDLE;
+ sd->pending_connectivity_state_unsafe = GRPC_CHANNEL_IDLE;
+ sd->user_data_vtable = addresses->user_data_vtable;
+ if (sd->user_data_vtable != NULL) {
+ sd->user_data =
+ sd->user_data_vtable->copy(addresses->addresses[i].user_data);
+ }
+ }
+ subchannel_list->num_subchannels = subchannel_index;
+ subchannel_list->num_idle = subchannel_index;
+ return subchannel_list;
+}
+
+static void subchannel_list_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_lb_subchannel_list *subchannel_list) {
+ if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ gpr_log(GPR_DEBUG, "[%s %p] Destroying subchannel_list %p",
+ subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list);
+ }
+ for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
+ grpc_lb_subchannel_data *sd = &subchannel_list->subchannels[i];
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
+ "subchannel_list_destroy");
+ }
+ gpr_free(subchannel_list->subchannels);
+ gpr_free(subchannel_list);
+}
+
+void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list *subchannel_list,
+ const char *reason) {
+ gpr_ref_non_zero(&subchannel_list->refcount);
+ if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
+ gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p REF %lu->%lu (%s)",
+ subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list, (unsigned long)(count - 1), (unsigned long)count,
+ reason);
+ }
+}
+
+void grpc_lb_subchannel_list_unref(grpc_exec_ctx *exec_ctx,
+ grpc_lb_subchannel_list *subchannel_list,
+ const char *reason) {
+ const bool done = gpr_unref(&subchannel_list->refcount);
+ if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
+ gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p UNREF %lu->%lu (%s)",
+ subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list, (unsigned long)(count + 1), (unsigned long)count,
+ reason);
+ }
+ if (done) {
+ subchannel_list_destroy(exec_ctx, subchannel_list);
+ }
+}
+
+void grpc_lb_subchannel_list_ref_for_connectivity_watch(
+ grpc_lb_subchannel_list *subchannel_list, const char *reason) {
+ GRPC_LB_POLICY_WEAK_REF(subchannel_list->policy, reason);
+ grpc_lb_subchannel_list_ref(subchannel_list, reason);
+}
+
+void grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_list *subchannel_list,
+ const char *reason) {
+ GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, subchannel_list->policy, reason);
+ grpc_lb_subchannel_list_unref(exec_ctx, subchannel_list, reason);
+}
+
+static void subchannel_data_cancel_connectivity_watch(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd, const char *reason) {
+ if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ gpr_log(
+ GPR_DEBUG, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
+ " (subchannel %p): canceling connectivity watch (%s)",
+ sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list, (size_t)(sd - sd->subchannel_list->subchannels),
+ sd->subchannel_list->num_subchannels, sd->subchannel, reason);
+ }
+ grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL, NULL,
+ &sd->connectivity_changed_closure);
+}
+
+void grpc_lb_subchannel_list_shutdown_and_unref(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_list *subchannel_list,
+ const char *reason) {
+ if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ gpr_log(GPR_DEBUG, "[%s %p] Shutting down subchannel_list %p (%s)",
+ subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list, reason);
+ }
+ GPR_ASSERT(!subchannel_list->shutting_down);
+ subchannel_list->shutting_down = true;
+ for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
+ grpc_lb_subchannel_data *sd = &subchannel_list->subchannels[i];
+ // If there's a pending notification for this subchannel, cancel it;
+ // the callback is responsible for unreffing the subchannel.
+ // Otherwise, unref the subchannel directly.
+ if (sd->connectivity_notification_pending) {
+ subchannel_data_cancel_connectivity_watch(exec_ctx, sd, reason);
+ } else if (sd->subchannel != NULL) {
+ grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, reason);
+ }
+ }
+ grpc_lb_subchannel_list_unref(exec_ctx, subchannel_list, reason);
+}
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
new file mode 100644
index 0000000..9d59842
--- /dev/null
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@@ -0,0 +1,153 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H
+
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/subchannel.h"
+#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/transport/connectivity_state.h"
+
+// TODO(roth): This code is intended to be shared between pick_first and
+// round_robin. However, the interface needs more work to provide clean
+// encapsulation. For example, the structs here have some fields that are
+// only used in one of the two (e.g., the state counters in
+// grpc_lb_subchannel_list and the prev_connectivity_state field in
+// grpc_lb_subchannel_data are only used in round_robin, and the
+// checking_subchannel field in grpc_lb_subchannel_list is only used by
+// pick_first). Also, there is probably some code duplication between the
+// connectivity state notification callback code in both pick_first and
+// round_robin that could be refactored and moved here. In a future PR,
+// need to clean this up.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct grpc_lb_subchannel_list grpc_lb_subchannel_list;
+
+typedef struct {
+ /** backpointer to owning subchannel list */
+ grpc_lb_subchannel_list *subchannel_list;
+ /** subchannel itself */
+ grpc_subchannel *subchannel;
+ grpc_connected_subchannel *connected_subchannel;
+ /** Is a connectivity notification pending? */
+ bool connectivity_notification_pending;
+ /** notification that connectivity has changed on subchannel */
+ grpc_closure connectivity_changed_closure;
+ /** previous and current connectivity states. Updated by \a
+ * \a connectivity_changed_closure based on
+ * \a pending_connectivity_state_unsafe. */
+ grpc_connectivity_state prev_connectivity_state;
+ grpc_connectivity_state curr_connectivity_state;
+ /** connectivity state to be updated by
+ * grpc_subchannel_notify_on_state_change(), not guarded by
+ * the combiner. To be copied to \a curr_connectivity_state by
+ * \a connectivity_changed_closure. */
+ grpc_connectivity_state pending_connectivity_state_unsafe;
+ /** the subchannel's target user data */
+ void *user_data;
+ /** vtable to operate over \a user_data */
+ const grpc_lb_user_data_vtable *user_data_vtable;
+} grpc_lb_subchannel_data;
+
+/// Unrefs the subchannel contained in sd.
+void grpc_lb_subchannel_data_unref_subchannel(grpc_exec_ctx *exec_ctx,
+ grpc_lb_subchannel_data *sd,
+ const char *reason);
+
+/// Starts watching the connectivity state of the subchannel.
+/// The connectivity_changed_cb callback must invoke either
+/// grpc_lb_subchannel_data_stop_connectivity_watch() or again call
+/// grpc_lb_subchannel_data_start_connectivity_watch().
+void grpc_lb_subchannel_data_start_connectivity_watch(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd);
+
+/// Stops watching the connectivity state of the subchannel.
+void grpc_lb_subchannel_data_stop_connectivity_watch(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_data *sd);
+
+struct grpc_lb_subchannel_list {
+ /** backpointer to owning policy */
+ grpc_lb_policy *policy;
+
+ grpc_tracer_flag *tracer;
+
+ /** all our subchannels */
+ size_t num_subchannels;
+ grpc_lb_subchannel_data *subchannels;
+
+ /** Index into subchannels of the one we're currently checking.
+ * Used when connecting to subchannels serially instead of in parallel. */
+ // TODO(roth): When we have time, we can probably make this go away
+ // and compute the index dynamically by subtracting
+ // subchannel_list->subchannels from the subchannel_data pointer.
+ size_t checking_subchannel;
+
+ /** how many subchannels are in state READY */
+ size_t num_ready;
+ /** how many subchannels are in state TRANSIENT_FAILURE */
+ size_t num_transient_failures;
+ /** how many subchannels are in state SHUTDOWN */
+ size_t num_shutdown;
+ /** how many subchannels are in state IDLE */
+ size_t num_idle;
+
+ /** There will be one ref for each entry in subchannels for which there is a
+ * pending connectivity state watcher callback. */
+ gpr_refcount refcount;
+
+ /** Is this list shutting down? This may be true due to the shutdown of the
+ * policy itself or because a newer update has arrived while this one hadn't
+ * finished processing. */
+ bool shutting_down;
+};
+
+grpc_lb_subchannel_list *grpc_lb_subchannel_list_create(
+ grpc_exec_ctx *exec_ctx, grpc_lb_policy *p, grpc_tracer_flag *tracer,
+ const grpc_lb_addresses *addresses, const grpc_lb_policy_args *args,
+ grpc_iomgr_cb_func connectivity_changed_cb);
+
+void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list *subchannel_list,
+ const char *reason);
+
+void grpc_lb_subchannel_list_unref(grpc_exec_ctx *exec_ctx,
+ grpc_lb_subchannel_list *subchannel_list,
+ const char *reason);
+
+/// Takes and releases refs needed for a connectivity notification.
+/// This includes a ref to subchannel_list and a weak ref to the LB policy.
+void grpc_lb_subchannel_list_ref_for_connectivity_watch(
+ grpc_lb_subchannel_list *subchannel_list, const char *reason);
+void grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_list *subchannel_list,
+ const char *reason);
+
+/// Mark subchannel_list as discarded. Unsubscribes all its subchannels. The
+/// connectivity state notification callback will ultimately unref it.
+void grpc_lb_subchannel_list_shutdown_and_unref(
+ grpc_exec_ctx *exec_ctx, grpc_lb_subchannel_list *subchannel_list,
+ const char *reason);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H */
diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h
index 46b29f1..1cd73f3 100644
--- a/src/core/ext/filters/client_channel/subchannel.h
+++ b/src/core/ext/filters/client_channel/subchannel.h
@@ -127,8 +127,8 @@
grpc_connectivity_state grpc_subchannel_check_connectivity(
grpc_subchannel *channel, grpc_error **error);
-/** call notify when the connectivity state of a channel changes from *state.
- Updates *state with the new state of the channel */
+/** Calls notify when the connectivity state of a channel becomes different
+ from *state. Updates *state with the new state of the channel. */
void grpc_subchannel_notify_on_state_change(
grpc_exec_ctx *exec_ctx, grpc_subchannel *channel,
grpc_pollset_set *interested_parties, grpc_connectivity_state *state,
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h
index d5107d4..7dd348e 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.h
+++ b/src/core/ext/transport/chttp2/transport/flow_control.h
@@ -32,6 +32,12 @@
extern "C" grpc_tracer_flag grpc_flowctl_trace;
+namespace grpc {
+namespace testing {
+class TrickledCHTTP2; // to make this a friend
+} // namespace testing
+} // namespace grpc
+
namespace grpc_core {
namespace chttp2 {
@@ -203,6 +209,7 @@
}
private:
+ friend class ::grpc::testing::TrickledCHTTP2;
double TargetLogBdp();
double SmoothLogBdp(grpc_exec_ctx* exec_ctx, double value);
FlowControlAction::Urgency DeltaUrgency(int32_t value,
@@ -297,6 +304,7 @@
}
private:
+ friend class ::grpc::testing::TrickledCHTTP2;
TransportFlowControl* const tfc_;
const grpc_chttp2_stream* const s_;
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index fa6d79c..0809d57 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -577,7 +577,6 @@
grpc_pollset_worker *specific_worker) {
pollable *p = specific_worker->pollable_obj;
grpc_core::mu_guard lock(&p->mu);
- GRPC_STATS_INC_POLLSET_KICK(exec_ctx);
GPR_ASSERT(specific_worker != NULL);
if (specific_worker->kicked) {
if (GRPC_TRACER_ON(grpc_polling_trace)) {
@@ -619,6 +618,7 @@
static grpc_error *pollset_kick(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_pollset_worker *specific_worker) {
+ GRPC_STATS_INC_POLLSET_KICK(exec_ctx);
if (GRPC_TRACER_ON(grpc_polling_trace)) {
gpr_log(GPR_DEBUG,
"PS:%p kick %p tls_pollset=%p tls_worker=%p pollset.root_worker=%p",
@@ -674,6 +674,7 @@
grpc_pollset_worker *w = pollset->root_worker;
if (w != NULL) {
do {
+ GRPC_STATS_INC_POLLSET_KICK(exec_ctx);
append_error(&error, kick_one_worker(exec_ctx, w), err_desc);
w = w->links[PWLINK_POLLSET].next;
} while (w != pollset->root_worker);
diff --git a/src/core/lib/iomgr/pollset_windows.cc b/src/core/lib/iomgr/pollset_windows.cc
index bb4df83..01aff02 100644
--- a/src/core/lib/iomgr/pollset_windows.cc
+++ b/src/core/lib/iomgr/pollset_windows.cc
@@ -161,8 +161,10 @@
while (!worker.kicked) {
if (gpr_cv_wait(&worker.cv, &grpc_polling_mu,
grpc_millis_to_timespec(deadline, GPR_CLOCK_REALTIME))) {
+ grpc_exec_ctx_invalidate_now(exec_ctx);
break;
}
+ grpc_exec_ctx_invalidate_now(exec_ctx);
}
} else {
pollset->kicked_without_pollers = 0;
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
index 8e47aeb..2085e2b 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
@@ -119,6 +119,12 @@
// SSL Server Credentials.
//
+struct grpc_ssl_server_credentials_options {
+ grpc_ssl_client_certificate_request_type client_certificate_request;
+ grpc_ssl_server_certificate_config *certificate_config;
+ grpc_ssl_server_certificate_config_fetcher *certificate_config_fetcher;
+};
+
static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
grpc_server_credentials *creds) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
@@ -130,9 +136,7 @@
static grpc_security_status ssl_server_create_security_connector(
grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
grpc_server_security_connector **sc) {
- grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
- return grpc_ssl_server_security_connector_create(exec_ctx, creds, &c->config,
- sc);
+ return grpc_ssl_server_security_connector_create(exec_ctx, creds, sc);
}
static grpc_server_credentials_vtable ssl_server_vtable = {
@@ -170,6 +174,86 @@
config->num_key_cert_pairs = num_key_cert_pairs;
}
+grpc_ssl_server_certificate_config *grpc_ssl_server_certificate_config_create(
+ const char *pem_root_certs,
+ const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs) {
+ grpc_ssl_server_certificate_config *config =
+ (grpc_ssl_server_certificate_config *)gpr_zalloc(
+ sizeof(grpc_ssl_server_certificate_config));
+ if (pem_root_certs != NULL) {
+ config->pem_root_certs = gpr_strdup(pem_root_certs);
+ }
+ if (num_key_cert_pairs > 0) {
+ GPR_ASSERT(pem_key_cert_pairs != NULL);
+ config->pem_key_cert_pairs = (grpc_ssl_pem_key_cert_pair *)gpr_zalloc(
+ num_key_cert_pairs * sizeof(grpc_ssl_pem_key_cert_pair));
+ }
+ config->num_key_cert_pairs = num_key_cert_pairs;
+ for (size_t i = 0; i < num_key_cert_pairs; i++) {
+ GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
+ GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
+ config->pem_key_cert_pairs[i].cert_chain =
+ gpr_strdup(pem_key_cert_pairs[i].cert_chain);
+ config->pem_key_cert_pairs[i].private_key =
+ gpr_strdup(pem_key_cert_pairs[i].private_key);
+ }
+ return config;
+}
+
+void grpc_ssl_server_certificate_config_destroy(
+ grpc_ssl_server_certificate_config *config) {
+ if (config == NULL) return;
+ for (size_t i = 0; i < config->num_key_cert_pairs; i++) {
+ gpr_free((void *)config->pem_key_cert_pairs[i].private_key);
+ gpr_free((void *)config->pem_key_cert_pairs[i].cert_chain);
+ }
+ gpr_free(config->pem_key_cert_pairs);
+ gpr_free(config->pem_root_certs);
+ gpr_free(config);
+}
+
+grpc_ssl_server_credentials_options *
+grpc_ssl_server_credentials_create_options_using_config(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config *config) {
+ grpc_ssl_server_credentials_options *options = NULL;
+ if (config == NULL) {
+ gpr_log(GPR_ERROR, "Certificate config must not be NULL.");
+ goto done;
+ }
+ options = (grpc_ssl_server_credentials_options *)gpr_zalloc(
+ sizeof(grpc_ssl_server_credentials_options));
+ options->client_certificate_request = client_certificate_request;
+ options->certificate_config = config;
+done:
+ return options;
+}
+
+grpc_ssl_server_credentials_options *
+grpc_ssl_server_credentials_create_options_using_config_fetcher(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config_callback cb, void *user_data) {
+ if (cb == NULL) {
+ gpr_log(GPR_ERROR, "Invalid certificate config callback parameter.");
+ return NULL;
+ }
+
+ grpc_ssl_server_certificate_config_fetcher *fetcher =
+ (grpc_ssl_server_certificate_config_fetcher *)gpr_zalloc(
+ sizeof(grpc_ssl_server_certificate_config_fetcher));
+ fetcher->cb = cb;
+ fetcher->user_data = user_data;
+
+ grpc_ssl_server_credentials_options *options =
+ (grpc_ssl_server_credentials_options *)gpr_zalloc(
+ sizeof(grpc_ssl_server_credentials_options));
+ options->client_certificate_request = client_certificate_request;
+ options->certificate_config_fetcher = fetcher;
+
+ return options;
+}
+
grpc_server_credentials *grpc_ssl_server_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
@@ -186,8 +270,6 @@
size_t num_key_cert_pairs,
grpc_ssl_client_certificate_request_type client_certificate_request,
void *reserved) {
- grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)gpr_zalloc(
- sizeof(grpc_ssl_server_credentials));
GRPC_API_TRACE(
"grpc_ssl_server_credentials_create_ex("
"pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, "
@@ -195,11 +277,67 @@
5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs,
client_certificate_request, reserved));
GPR_ASSERT(reserved == NULL);
+
+ grpc_ssl_server_certificate_config *cert_config =
+ grpc_ssl_server_certificate_config_create(
+ pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs);
+ grpc_ssl_server_credentials_options *options =
+ grpc_ssl_server_credentials_create_options_using_config(
+ client_certificate_request, cert_config);
+
+ return grpc_ssl_server_credentials_create_with_options(options);
+}
+
+grpc_server_credentials *grpc_ssl_server_credentials_create_with_options(
+ grpc_ssl_server_credentials_options *options) {
+ grpc_server_credentials *retval = NULL;
+ grpc_ssl_server_credentials *c = NULL;
+
+ if (options == NULL) {
+ gpr_log(GPR_ERROR,
+ "Invalid options trying to create SSL server credentials.");
+ goto done;
+ }
+
+ if (options->certificate_config == NULL &&
+ options->certificate_config_fetcher == NULL) {
+ gpr_log(GPR_ERROR,
+ "SSL server credentials options must specify either "
+ "certificate config or fetcher.");
+ goto done;
+ } else if (options->certificate_config_fetcher != NULL &&
+ options->certificate_config_fetcher->cb == NULL) {
+ gpr_log(GPR_ERROR, "Certificate config fetcher callback must not be NULL.");
+ goto done;
+ }
+
+ c = (grpc_ssl_server_credentials *)gpr_zalloc(
+ sizeof(grpc_ssl_server_credentials));
c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &ssl_server_vtable;
- ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
- num_key_cert_pairs, client_certificate_request,
- &c->config);
- return &c->base;
+
+ if (options->certificate_config_fetcher != NULL) {
+ c->config.client_certificate_request = options->client_certificate_request;
+ c->certificate_config_fetcher = *options->certificate_config_fetcher;
+ } else {
+ ssl_build_server_config(options->certificate_config->pem_root_certs,
+ options->certificate_config->pem_key_cert_pairs,
+ options->certificate_config->num_key_cert_pairs,
+ options->client_certificate_request, &c->config);
+ }
+
+ retval = &c->base;
+
+done:
+ grpc_ssl_server_credentials_options_destroy(options);
+ return retval;
+}
+
+void grpc_ssl_server_credentials_options_destroy(
+ grpc_ssl_server_credentials_options *o) {
+ if (o == NULL) return;
+ gpr_free(o->certificate_config_fetcher);
+ grpc_ssl_server_certificate_config_destroy(o->certificate_config);
+ gpr_free(o);
}
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h
index 42e425d..5542484 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.h
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h
@@ -29,9 +29,21 @@
grpc_ssl_config config;
} grpc_ssl_credentials;
+struct grpc_ssl_server_certificate_config {
+ grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs;
+ size_t num_key_cert_pairs;
+ char *pem_root_certs;
+};
+
+typedef struct {
+ grpc_ssl_server_certificate_config_callback cb;
+ void *user_data;
+} grpc_ssl_server_certificate_config_fetcher;
+
typedef struct {
grpc_server_credentials base;
grpc_ssl_server_config config;
+ grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher;
} grpc_ssl_server_credentials;
tsi_ssl_pem_key_cert_pair *grpc_convert_grpc_to_tsi_cert_pairs(
diff --git a/src/core/lib/security/transport/security_connector.cc b/src/core/lib/security/transport/security_connector.cc
index b050be2..06160d0 100644
--- a/src/core/lib/security/transport/security_connector.cc
+++ b/src/core/lib/security/transport/security_connector.cc
@@ -34,6 +34,7 @@
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/security_handshaker.h"
@@ -277,6 +278,30 @@
return NULL;
}
+static tsi_client_certificate_request_type
+get_tsi_client_certificate_request_type(
+ grpc_ssl_client_certificate_request_type grpc_request_type) {
+ switch (grpc_request_type) {
+ case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
+ return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
+
+ case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
+
+ case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
+ return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
+
+ case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
+
+ case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
+ return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
+
+ default:
+ return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
+ }
+}
+
/* -- Fake implementation. -- */
typedef struct {
@@ -533,6 +558,15 @@
tsi_ssl_server_handshaker_factory *server_handshaker_factory;
} grpc_ssl_server_security_connector;
+static bool server_connector_has_cert_config_fetcher(
+ grpc_ssl_server_security_connector *c) {
+ GPR_ASSERT(c != NULL);
+ grpc_ssl_server_credentials *server_creds =
+ (grpc_ssl_server_credentials *)c->base.server_creds;
+ GPR_ASSERT(server_creds != NULL);
+ return server_creds->certificate_config_fetcher.cb != NULL;
+}
+
static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc) {
grpc_ssl_channel_security_connector *c =
@@ -573,7 +607,6 @@
tsi_result_to_string(result));
return;
}
-
// Create handshakers.
grpc_handshake_manager_add(
handshake_mgr,
@@ -581,12 +614,102 @@
exec_ctx, tsi_create_adapter_handshaker(tsi_hs), &sc->base));
}
+static const char **fill_alpn_protocol_strings(size_t *num_alpn_protocols) {
+ GPR_ASSERT(num_alpn_protocols != NULL);
+ *num_alpn_protocols = grpc_chttp2_num_alpn_versions();
+ const char **alpn_protocol_strings =
+ (const char **)gpr_malloc(sizeof(const char *) * (*num_alpn_protocols));
+ for (size_t i = 0; i < *num_alpn_protocols; i++) {
+ alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
+ }
+ return alpn_protocol_strings;
+}
+
+/* Attempts to replace the server_handshaker_factory with a new factory using
+ * the provided grpc_ssl_server_certificate_config. Should new factory creation
+ * fail, the existing factory will not be replaced. Returns true on success (new
+ * factory created). */
+static bool try_replace_server_handshaker_factory(
+ grpc_ssl_server_security_connector *sc,
+ const grpc_ssl_server_certificate_config *config) {
+ if (config == NULL) {
+ gpr_log(GPR_ERROR,
+ "Server certificate config callback returned invalid (NULL) "
+ "config.");
+ return false;
+ }
+ gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config);
+
+ size_t num_alpn_protocols = 0;
+ const char **alpn_protocol_strings =
+ fill_alpn_protocol_strings(&num_alpn_protocols);
+ tsi_ssl_pem_key_cert_pair *cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
+ config->pem_key_cert_pairs, config->num_key_cert_pairs);
+ tsi_ssl_server_handshaker_factory *new_handshaker_factory = NULL;
+ grpc_ssl_server_credentials *server_creds =
+ (grpc_ssl_server_credentials *)sc->base.server_creds;
+ tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
+ cert_pairs, config->num_key_cert_pairs, config->pem_root_certs,
+ get_tsi_client_certificate_request_type(
+ server_creds->config.client_certificate_request),
+ ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
+ &new_handshaker_factory);
+ gpr_free(cert_pairs);
+ gpr_free((void *)alpn_protocol_strings);
+
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+ tsi_result_to_string(result));
+ return false;
+ }
+ tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory);
+ sc->server_handshaker_factory = new_handshaker_factory;
+ return true;
+}
+
+/* Attempts to fetch the server certificate config if a callback is available.
+ * Current certificate config will continue to be used if the callback returns
+ * an error. Returns true if new credentials were sucessfully loaded. */
+static bool try_fetch_ssl_server_credentials(
+ grpc_ssl_server_security_connector *sc) {
+ grpc_ssl_server_certificate_config *certificate_config = NULL;
+ bool status;
+
+ GPR_ASSERT(sc != NULL);
+ if (!server_connector_has_cert_config_fetcher(sc)) return false;
+
+ grpc_ssl_server_credentials *server_creds =
+ (grpc_ssl_server_credentials *)sc->base.server_creds;
+ grpc_ssl_certificate_config_reload_status cb_result =
+ server_creds->certificate_config_fetcher.cb(
+ server_creds->certificate_config_fetcher.user_data,
+ &certificate_config);
+ if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
+ gpr_log(GPR_DEBUG, "No change in SSL server credentials.");
+ status = false;
+ } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
+ status = try_replace_server_handshaker_factory(sc, certificate_config);
+ } else {
+ // Log error, continue using previously-loaded credentials.
+ gpr_log(GPR_ERROR,
+ "Failed fetching new server credentials, continuing to "
+ "use previously-loaded credentials.");
+ status = false;
+ }
+
+ if (certificate_config != NULL) {
+ grpc_ssl_server_certificate_config_destroy(certificate_config);
+ }
+ return status;
+}
+
static void ssl_server_add_handshakers(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc,
grpc_handshake_manager *handshake_mgr) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
// Instantiate TSI handshaker.
+ try_fetch_ssl_server_credentials(c);
tsi_handshaker *tsi_hs = NULL;
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
c->server_handshaker_factory, &tsi_hs);
@@ -595,7 +718,6 @@
tsi_result_to_string(result));
return;
}
-
// Create handshakers.
grpc_handshake_manager_add(
handshake_mgr,
@@ -857,31 +979,6 @@
return compute_default_pem_root_certs_once();
}
-static tsi_client_certificate_request_type
-get_tsi_client_certificate_request_type(
- grpc_ssl_client_certificate_request_type grpc_request_type) {
- switch (grpc_request_type) {
- case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
- return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
-
- case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
- return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
-
- case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
- return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
-
- case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
- return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
-
- case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
- return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
-
- default:
- // Is this a sane default
- return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
- }
-}
-
const char *grpc_get_default_ssl_roots(void) {
/* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
loading all the roots once for the lifetime of the process. */
@@ -897,18 +994,14 @@
grpc_call_credentials *request_metadata_creds,
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc) {
- size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
+ size_t num_alpn_protocols = 0;
const char **alpn_protocol_strings =
- (const char **)gpr_malloc(sizeof(const char *) * num_alpn_protocols);
+ fill_alpn_protocol_strings(&num_alpn_protocols);
tsi_result result = TSI_OK;
grpc_ssl_channel_security_connector *c;
- size_t i;
const char *pem_root_certs;
char *port;
bool has_key_cert_pair;
- for (i = 0; i < num_alpn_protocols; i++) {
- alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
- }
if (config == NULL || target_name == NULL) {
gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
@@ -965,50 +1058,64 @@
return GRPC_SECURITY_ERROR;
}
-grpc_security_status grpc_ssl_server_security_connector_create(
- grpc_exec_ctx *exec_ctx, grpc_server_credentials *server_creds,
- const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
- size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
- const char **alpn_protocol_strings =
- (const char **)gpr_malloc(sizeof(const char *) * num_alpn_protocols);
- tsi_result result = TSI_OK;
- grpc_ssl_server_security_connector *c;
- size_t i;
-
- for (i = 0; i < num_alpn_protocols; i++) {
- alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
- }
-
- if (config == NULL || config->num_key_cert_pairs == 0) {
- gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
- goto error;
- }
- c = (grpc_ssl_server_security_connector *)gpr_zalloc(
- sizeof(grpc_ssl_server_security_connector));
-
+static grpc_ssl_server_security_connector *
+grpc_ssl_server_security_connector_initialize(
+ grpc_server_credentials *server_creds) {
+ grpc_ssl_server_security_connector *c =
+ (grpc_ssl_server_security_connector *)gpr_zalloc(
+ sizeof(grpc_ssl_server_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
c->base.base.vtable = &ssl_server_vtable;
- c->base.server_creds = grpc_server_credentials_ref(server_creds);
- result = tsi_create_ssl_server_handshaker_factory_ex(
- config->pem_key_cert_pairs, config->num_key_cert_pairs,
- config->pem_root_certs, get_tsi_client_certificate_request_type(
- config->client_certificate_request),
- ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
- &c->server_handshaker_factory);
- if (result != TSI_OK) {
- gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
- tsi_result_to_string(result));
- ssl_server_destroy(exec_ctx, &c->base.base);
- *sc = NULL;
- goto error;
- }
c->base.add_handshakers = ssl_server_add_handshakers;
- *sc = &c->base;
- gpr_free((void *)alpn_protocol_strings);
- return GRPC_SECURITY_OK;
+ c->base.server_creds = grpc_server_credentials_ref(server_creds);
+ return c;
+}
-error:
- gpr_free((void *)alpn_protocol_strings);
- return GRPC_SECURITY_ERROR;
+grpc_security_status grpc_ssl_server_security_connector_create(
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *gsc,
+ grpc_server_security_connector **sc) {
+ tsi_result result = TSI_OK;
+ grpc_ssl_server_credentials *server_credentials =
+ (grpc_ssl_server_credentials *)gsc;
+ grpc_security_status retval = GRPC_SECURITY_OK;
+
+ GPR_ASSERT(server_credentials != NULL);
+ GPR_ASSERT(sc != NULL);
+
+ grpc_ssl_server_security_connector *c =
+ grpc_ssl_server_security_connector_initialize(gsc);
+ if (server_connector_has_cert_config_fetcher(c)) {
+ // Load initial credentials from certificate_config_fetcher:
+ if (!try_fetch_ssl_server_credentials(c)) {
+ gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher.");
+ retval = GRPC_SECURITY_ERROR;
+ }
+ } else {
+ size_t num_alpn_protocols = 0;
+ const char **alpn_protocol_strings =
+ fill_alpn_protocol_strings(&num_alpn_protocols);
+ result = tsi_create_ssl_server_handshaker_factory_ex(
+ server_credentials->config.pem_key_cert_pairs,
+ server_credentials->config.num_key_cert_pairs,
+ server_credentials->config.pem_root_certs,
+ get_tsi_client_certificate_request_type(
+ server_credentials->config.client_certificate_request),
+ ssl_cipher_suites(), alpn_protocol_strings,
+ (uint16_t)num_alpn_protocols, &c->server_handshaker_factory);
+ gpr_free((void *)alpn_protocol_strings);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+ tsi_result_to_string(result));
+ retval = GRPC_SECURITY_ERROR;
+ }
+ }
+
+ if (retval == GRPC_SECURITY_OK) {
+ *sc = &c->base;
+ } else {
+ if (c != NULL) ssl_server_destroy(exec_ctx, &c->base.base);
+ if (sc != NULL) *sc = NULL;
+ }
+ return retval;
}
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index 8287151..54a563b 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -248,8 +248,8 @@
specific error code otherwise.
*/
grpc_security_status grpc_ssl_server_security_connector_create(
- grpc_exec_ctx *exec_ctx, grpc_server_credentials *server_creds,
- const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *server_credentials,
+ grpc_server_security_connector **sc);
/* Util. */
const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc
index f328a6c..652c26c 100644
--- a/src/core/lib/transport/connectivity_state.cc
+++ b/src/core/lib/transport/connectivity_state.cc
@@ -29,8 +29,6 @@
const char *grpc_connectivity_state_name(grpc_connectivity_state state) {
switch (state) {
- case GRPC_CHANNEL_INIT:
- return "INIT";
case GRPC_CHANNEL_IDLE:
return "IDLE";
case GRPC_CHANNEL_CONNECTING:
@@ -174,7 +172,6 @@
grpc_connectivity_state_name(state), reason, error, error_string);
}
switch (state) {
- case GRPC_CHANNEL_INIT:
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE:
case GRPC_CHANNEL_READY:
diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc
index 2d332e2..339c9bb 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_plugin_registry.cc
@@ -46,8 +46,6 @@
extern "C" void grpc_resolver_sockaddr_shutdown(void);
extern "C" void grpc_server_load_reporting_plugin_init(void);
extern "C" void grpc_server_load_reporting_plugin_shutdown(void);
-extern "C" void census_grpc_plugin_init(void);
-extern "C" void census_grpc_plugin_shutdown(void);
extern "C" void grpc_max_age_filter_init(void);
extern "C" void grpc_max_age_filter_shutdown(void);
extern "C" void grpc_message_size_filter_init(void);
@@ -84,8 +82,6 @@
grpc_resolver_sockaddr_shutdown);
grpc_register_plugin(grpc_server_load_reporting_plugin_init,
grpc_server_load_reporting_plugin_shutdown);
- grpc_register_plugin(census_grpc_plugin_init,
- census_grpc_plugin_shutdown);
grpc_register_plugin(grpc_max_age_filter_init,
grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init,
diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
index 7821858..c9fc17d 100644
--- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
@@ -44,8 +44,6 @@
extern "C" void grpc_lb_policy_pick_first_shutdown(void);
extern "C" void grpc_lb_policy_round_robin_init(void);
extern "C" void grpc_lb_policy_round_robin_shutdown(void);
-extern "C" void census_grpc_plugin_init(void);
-extern "C" void census_grpc_plugin_shutdown(void);
extern "C" void grpc_max_age_filter_init(void);
extern "C" void grpc_max_age_filter_shutdown(void);
extern "C" void grpc_message_size_filter_init(void);
@@ -80,8 +78,6 @@
grpc_lb_policy_pick_first_shutdown);
grpc_register_plugin(grpc_lb_policy_round_robin_init,
grpc_lb_policy_round_robin_shutdown);
- grpc_register_plugin(census_grpc_plugin_init,
- census_grpc_plugin_shutdown);
grpc_register_plugin(grpc_max_age_filter_init,
grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init,
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index 19a25c8..9df5310 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -48,187 +48,13 @@
namespace grpc {
-namespace {
-int kConnectivityCheckIntervalMsec = 500;
-void WatchStateChange(void* arg);
-
-class TagSaver final : public CompletionQueueTag {
- public:
- explicit TagSaver(void* tag) : tag_(tag) {}
- ~TagSaver() override {}
- bool FinalizeResult(void** tag, bool* status) override {
- *tag = tag_;
- delete this;
- return true;
- }
-
- private:
- void* tag_;
-};
-
-// Constantly watches channel connectivity status to reconnect a transiently
-// disconnected channel. This is a temporary work-around before we have retry
-// support.
-class ChannelConnectivityWatcher : private GrpcLibraryCodegen {
- public:
- static void StartWatching(grpc_channel* channel) {
- if (!IsDisabled()) {
- std::unique_lock<std::mutex> lock(g_watcher_mu_);
- if (g_watcher_ == nullptr) {
- g_watcher_ = new ChannelConnectivityWatcher();
- }
- g_watcher_->StartWatchingLocked(channel);
- }
- }
-
- static void StopWatching() {
- if (!IsDisabled()) {
- std::unique_lock<std::mutex> lock(g_watcher_mu_);
- if (g_watcher_->StopWatchingLocked()) {
- delete g_watcher_;
- g_watcher_ = nullptr;
- }
- }
- }
-
- private:
- ChannelConnectivityWatcher() : channel_count_(0), shutdown_(false) {
- gpr_ref_init(&ref_, 0);
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
- gpr_thd_new(&thd_id_, &WatchStateChange, this, &options);
- }
-
- static bool IsDisabled() {
- char* env = gpr_getenv("GRPC_DISABLE_CHANNEL_CONNECTIVITY_WATCHER");
- bool disabled = gpr_is_true(env);
- gpr_free(env);
- return disabled;
- }
-
- void WatchStateChangeImpl() {
- bool ok = false;
- void* tag = NULL;
- CompletionQueue::NextStatus status = CompletionQueue::GOT_EVENT;
- while (true) {
- {
- std::unique_lock<std::mutex> lock(shutdown_mu_);
- if (shutdown_) {
- // Drain cq_ if the watcher is shutting down
- status = cq_.AsyncNext(&tag, &ok, gpr_inf_future(GPR_CLOCK_REALTIME));
- } else {
- status = cq_.AsyncNext(&tag, &ok, gpr_inf_past(GPR_CLOCK_REALTIME));
- // Make sure we've seen 2 TIMEOUTs before going to sleep
- if (status == CompletionQueue::TIMEOUT) {
- status = cq_.AsyncNext(&tag, &ok, gpr_inf_past(GPR_CLOCK_REALTIME));
- if (status == CompletionQueue::TIMEOUT) {
- shutdown_cv_.wait_for(lock, std::chrono::milliseconds(
- kConnectivityCheckIntervalMsec));
- continue;
- }
- }
- }
- }
- ChannelState* channel_state = static_cast<ChannelState*>(tag);
- channel_state->state =
- grpc_channel_check_connectivity_state(channel_state->channel, false);
- if (channel_state->state == GRPC_CHANNEL_SHUTDOWN) {
- void* shutdown_tag = NULL;
- channel_state->shutdown_cq.Next(&shutdown_tag, &ok);
- delete channel_state;
- if (gpr_unref(&ref_)) {
- break;
- }
- } else {
- TagSaver* tag_saver = new TagSaver(channel_state);
- grpc_channel_watch_connectivity_state(
- channel_state->channel, channel_state->state,
- gpr_inf_future(GPR_CLOCK_REALTIME), cq_.cq(), tag_saver);
- }
- }
- }
-
- void StartWatchingLocked(grpc_channel* channel) {
- if (thd_id_ != 0) {
- gpr_ref(&ref_);
- ++channel_count_;
- ChannelState* channel_state = new ChannelState(channel);
- // The first grpc_channel_watch_connectivity_state() is not used to
- // monitor the channel state change, but to hold a reference of the
- // c channel. So that WatchStateChangeImpl() can observe state ==
- // GRPC_CHANNEL_SHUTDOWN before the channel gets destroyed.
- grpc_channel_watch_connectivity_state(
- channel_state->channel, channel_state->state,
- gpr_inf_future(GPR_CLOCK_REALTIME), channel_state->shutdown_cq.cq(),
- new TagSaver(nullptr));
- grpc_channel_watch_connectivity_state(
- channel_state->channel, channel_state->state,
- gpr_inf_future(GPR_CLOCK_REALTIME), cq_.cq(),
- new TagSaver(channel_state));
- }
- }
-
- bool StopWatchingLocked() {
- if (--channel_count_ == 0) {
- {
- std::unique_lock<std::mutex> lock(shutdown_mu_);
- shutdown_ = true;
- shutdown_cv_.notify_one();
- }
- gpr_thd_join(thd_id_);
- return true;
- }
- return false;
- }
-
- friend void WatchStateChange(void* arg);
- struct ChannelState {
- explicit ChannelState(grpc_channel* channel)
- : channel(channel), state(GRPC_CHANNEL_IDLE){};
- grpc_channel* channel;
- grpc_connectivity_state state;
- CompletionQueue shutdown_cq;
- };
- gpr_thd_id thd_id_;
- CompletionQueue cq_;
- gpr_refcount ref_;
- int channel_count_;
-
- std::mutex shutdown_mu_;
- std::condition_variable shutdown_cv_; // protected by shutdown_mu_
- bool shutdown_; // protected by shutdown_mu_
-
- static std::mutex g_watcher_mu_;
- static ChannelConnectivityWatcher* g_watcher_; // protected by g_watcher_mu_
-};
-
-std::mutex ChannelConnectivityWatcher::g_watcher_mu_;
-ChannelConnectivityWatcher* ChannelConnectivityWatcher::g_watcher_ = nullptr;
-
-void WatchStateChange(void* arg) {
- ChannelConnectivityWatcher* watcher =
- static_cast<ChannelConnectivityWatcher*>(arg);
- watcher->WatchStateChangeImpl();
-}
-} // namespace
-
static internal::GrpcLibraryInitializer g_gli_initializer;
Channel::Channel(const grpc::string& host, grpc_channel* channel)
: host_(host), c_channel_(channel) {
g_gli_initializer.summon();
- if (grpc_channel_support_connectivity_watcher(channel)) {
- ChannelConnectivityWatcher::StartWatching(channel);
- }
}
-Channel::~Channel() {
- const bool stop_watching =
- grpc_channel_support_connectivity_watcher(c_channel_);
- grpc_channel_destroy(c_channel_);
- if (stop_watching) {
- ChannelConnectivityWatcher::StopWatching();
- }
-}
+Channel::~Channel() { grpc_channel_destroy(c_channel_); }
namespace {
@@ -259,8 +85,9 @@
&channel_info.service_config_json);
}
-Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
- CompletionQueue* cq) {
+internal::Call Channel::CreateCall(const internal::RpcMethod& method,
+ ClientContext* context,
+ CompletionQueue* cq) {
const bool kRegistered = method.channel_tag() && context->authority().empty();
grpc_call* c_call = NULL;
if (kRegistered) {
@@ -292,10 +119,11 @@
}
grpc_census_call_set_context(c_call, context->census_context());
context->set_call(c_call, shared_from_this());
- return Call(c_call, this, cq);
+ return internal::Call(c_call, this, cq);
}
-void Channel::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
+void Channel::PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) {
static const size_t MAX_OPS = 8;
size_t nops = 0;
grpc_op cops[MAX_OPS];
@@ -313,6 +141,24 @@
return grpc_channel_check_connectivity_state(c_channel_, try_to_connect);
}
+namespace {
+
+class TagSaver final : public internal::CompletionQueueTag {
+ public:
+ explicit TagSaver(void* tag) : tag_(tag) {}
+ ~TagSaver() override {}
+ bool FinalizeResult(void** tag, bool* status) override {
+ *tag = tag_;
+ delete this;
+ return true;
+ }
+
+ private:
+ void* tag_;
+};
+
+} // namespace
+
void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
CompletionQueue* cq, void* tag) {
diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc
index 693b8be..fc18ce9 100644
--- a/src/cpp/client/generic_stub.cc
+++ b/src/cpp/client/generic_stub.cc
@@ -27,8 +27,9 @@
ChannelInterface* channel, ClientContext* context,
const grpc::string& method, CompletionQueue* cq, bool start, void* tag) {
return std::unique_ptr<GenericClientAsyncReaderWriter>(
- GenericClientAsyncReaderWriter::Create(
- channel, cq, RpcMethod(method.c_str(), RpcMethod::BIDI_STREAMING),
+ internal::ClientAsyncReaderWriterFactory<ByteBuffer, ByteBuffer>::Create(
+ channel, cq, internal::RpcMethod(method.c_str(),
+ internal::RpcMethod::BIDI_STREAMING),
context, start, tag));
}
@@ -52,8 +53,9 @@
ClientContext* context, const grpc::string& method,
const ByteBuffer& request, CompletionQueue* cq) {
return std::unique_ptr<GenericClientAsyncResponseReader>(
- GenericClientAsyncResponseReader::Create(
- channel_.get(), cq, RpcMethod(method.c_str(), RpcMethod::NORMAL_RPC),
+ internal::ClientAsyncResponseReaderFactory<ByteBuffer>::Create(
+ channel_.get(), cq,
+ internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC),
context, request, false));
}
diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc
index 4a2e2be..eb6dc8c 100644
--- a/src/cpp/common/completion_queue_cc.cc
+++ b/src/cpp/common/completion_queue_cc.cc
@@ -60,7 +60,7 @@
case GRPC_QUEUE_SHUTDOWN:
return SHUTDOWN;
case GRPC_OP_COMPLETE:
- auto cq_tag = static_cast<CompletionQueueTag*>(ev.tag);
+ auto cq_tag = static_cast<internal::CompletionQueueTag*>(ev.tag);
*ok = ev.success != 0;
*tag = cq_tag;
if (cq_tag->FinalizeResult(tag, ok)) {
@@ -87,7 +87,7 @@
flushed_ = true;
if (grpc_completion_queue_thread_local_cache_flush(cq_->cq_, &res_tag,
&res)) {
- auto cq_tag = static_cast<CompletionQueueTag*>(res_tag);
+ auto cq_tag = static_cast<internal::CompletionQueueTag*>(res_tag);
*ok = res == 1;
if (cq_tag->FinalizeResult(tag, ok)) {
return true;
diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc
index d2cba6d..10dbd3c 100644
--- a/src/cpp/server/health/default_health_check_service.cc
+++ b/src/cpp/server/health/default_health_check_service.cc
@@ -37,11 +37,12 @@
DefaultHealthCheckService::HealthCheckServiceImpl::HealthCheckServiceImpl(
DefaultHealthCheckService* service)
: service_(service), method_(nullptr) {
- MethodHandler* handler =
- new RpcMethodHandler<HealthCheckServiceImpl, ByteBuffer, ByteBuffer>(
+ internal::MethodHandler* handler =
+ new internal::RpcMethodHandler<HealthCheckServiceImpl, ByteBuffer,
+ ByteBuffer>(
std::mem_fn(&HealthCheckServiceImpl::Check), this);
- method_ = new RpcServiceMethod(kHealthCheckMethodName, RpcMethod::NORMAL_RPC,
- handler);
+ method_ = new internal::RpcServiceMethod(
+ kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, handler);
AddMethod(method_);
}
diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h
index 09d5ceb..99d6680 100644
--- a/src/cpp/server/health/default_health_check_service.h
+++ b/src/cpp/server/health/default_health_check_service.h
@@ -41,7 +41,7 @@
private:
const DefaultHealthCheckService* const service_;
- RpcServiceMethod* method_;
+ internal::RpcServiceMethod* method_;
};
DefaultHealthCheckService();
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index d982a3d..6480482 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -90,7 +90,8 @@
ServerCompletionQueue* const cq_;
};
-typedef SneakyCallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus>
+typedef internal::SneakyCallOpSet<internal::CallOpSendInitialMetadata,
+ internal::CallOpServerSendStatus>
UnimplementedAsyncResponseOp;
class Server::UnimplementedAsyncResponse final
: public UnimplementedAsyncResponseOp {
@@ -108,12 +109,12 @@
UnimplementedAsyncRequest* const request_;
};
-class ShutdownTag : public CompletionQueueTag {
+class ShutdownTag : public internal::CompletionQueueTag {
public:
bool FinalizeResult(void** tag, bool* status) { return false; }
};
-class DummyTag : public CompletionQueueTag {
+class DummyTag : public internal::CompletionQueueTag {
public:
bool FinalizeResult(void** tag, bool* status) {
*status = true;
@@ -121,15 +122,15 @@
}
};
-class Server::SyncRequest final : public CompletionQueueTag {
+class Server::SyncRequest final : public internal::CompletionQueueTag {
public:
- SyncRequest(RpcServiceMethod* method, void* tag)
+ SyncRequest(internal::RpcServiceMethod* method, void* tag)
: method_(method),
tag_(tag),
in_flight_(false),
- has_request_payload_(method->method_type() == RpcMethod::NORMAL_RPC ||
- method->method_type() ==
- RpcMethod::SERVER_STREAMING),
+ has_request_payload_(
+ method->method_type() == internal::RpcMethod::NORMAL_RPC ||
+ method->method_type() == internal::RpcMethod::SERVER_STREAMING),
call_details_(nullptr),
cq_(nullptr) {
grpc_metadata_array_init(&request_metadata_);
@@ -212,14 +213,14 @@
void Run(std::shared_ptr<GlobalCallbacks> global_callbacks) {
ctx_.BeginCompletionOp(&call_);
global_callbacks->PreSynchronousRequest(&ctx_);
- method_->handler()->RunHandler(
- MethodHandler::HandlerParameter(&call_, &ctx_, request_payload_));
+ method_->handler()->RunHandler(internal::MethodHandler::HandlerParameter(
+ &call_, &ctx_, request_payload_));
global_callbacks->PostSynchronousRequest(&ctx_);
request_payload_ = nullptr;
cq_.Shutdown();
- CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag();
+ internal::CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag();
cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME));
/* Ensure the cq_ is shutdown */
@@ -229,15 +230,15 @@
private:
CompletionQueue cq_;
- Call call_;
+ internal::Call call_;
ServerContext ctx_;
const bool has_request_payload_;
grpc_byte_buffer* request_payload_;
- RpcServiceMethod* const method_;
+ internal::RpcServiceMethod* const method_;
};
private:
- RpcServiceMethod* const method_;
+ internal::RpcServiceMethod* const method_;
void* const tag_;
bool in_flight_;
const bool has_request_payload_;
@@ -311,14 +312,15 @@
// object
}
- void AddSyncMethod(RpcServiceMethod* method, void* tag) {
+ void AddSyncMethod(internal::RpcServiceMethod* method, void* tag) {
sync_requests_.emplace_back(new SyncRequest(method, tag));
}
void AddUnknownSyncMethod() {
if (!sync_requests_.empty()) {
- unknown_method_.reset(new RpcServiceMethod(
- "unknown", RpcMethod::BIDI_STREAMING, new UnknownMethodHandler));
+ unknown_method_.reset(new internal::RpcServiceMethod(
+ "unknown", internal::RpcMethod::BIDI_STREAMING,
+ new internal::UnknownMethodHandler));
sync_requests_.emplace_back(
new SyncRequest(unknown_method_.get(), nullptr));
}
@@ -355,8 +357,8 @@
CompletionQueue* server_cq_;
int cq_timeout_msec_;
std::vector<std::unique_ptr<SyncRequest>> sync_requests_;
- std::unique_ptr<RpcServiceMethod> unknown_method_;
- std::unique_ptr<RpcServiceMethod> health_check_;
+ std::unique_ptr<internal::RpcServiceMethod> unknown_method_;
+ std::unique_ptr<internal::RpcServiceMethod> health_check_;
std::shared_ptr<Server::GlobalCallbacks> global_callbacks_;
};
@@ -439,13 +441,13 @@
}
static grpc_server_register_method_payload_handling PayloadHandlingForMethod(
- RpcServiceMethod* method) {
+ internal::RpcServiceMethod* method) {
switch (method->method_type()) {
- case RpcMethod::NORMAL_RPC:
- case RpcMethod::SERVER_STREAMING:
+ case internal::RpcMethod::NORMAL_RPC:
+ case internal::RpcMethod::SERVER_STREAMING:
return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER;
- case RpcMethod::CLIENT_STREAMING:
- case RpcMethod::BIDI_STREAMING:
+ case internal::RpcMethod::CLIENT_STREAMING:
+ case internal::RpcMethod::BIDI_STREAMING:
return GRPC_SRM_PAYLOAD_NONE;
}
GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;);
@@ -466,7 +468,7 @@
continue;
}
- RpcServiceMethod* method = it->get();
+ internal::RpcServiceMethod* method = it->get();
void* tag = grpc_server_register_method(
server_, method->name(), host ? host->c_str() : nullptr,
PayloadHandlingForMethod(method), 0);
@@ -606,7 +608,8 @@
}
}
-void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
+void Server::PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) {
static const size_t MAX_OPS = 8;
size_t nops = 0;
grpc_op cops[MAX_OPS];
@@ -622,8 +625,8 @@
ServerInterface::BaseAsyncRequest::BaseAsyncRequest(
ServerInterface* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, void* tag,
- bool delete_on_finalize)
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ void* tag, bool delete_on_finalize)
: server_(server),
context_(context),
stream_(stream),
@@ -645,7 +648,8 @@
}
context_->set_call(call_);
context_->cq_ = call_cq_;
- Call call(call_, server_, call_cq_, server_->max_receive_message_size());
+ internal::Call call(call_, server_, call_cq_,
+ server_->max_receive_message_size());
if (*status && call_) {
context_->BeginCompletionOp(&call);
}
@@ -660,7 +664,8 @@
ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest(
ServerInterface* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, void* tag)
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ void* tag)
: BaseAsyncRequest(server, context, stream, call_cq, tag, true) {}
void ServerInterface::RegisteredAsyncRequest::IssueRequest(
@@ -675,7 +680,7 @@
ServerInterface::GenericAsyncRequest::GenericAsyncRequest(
ServerInterface* server, GenericServerContext* context,
- ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize)
: BaseAsyncRequest(server, context, stream, call_cq, tag,
delete_on_finalize) {
@@ -718,7 +723,7 @@
UnimplementedAsyncRequest* request)
: request_(request) {
Status status(StatusCode::UNIMPLEMENTED, "");
- UnknownMethodHandler::FillOps(request_->context(), this);
+ internal::UnknownMethodHandler::FillOps(request_->context(), this);
request_->stream()->call_.PerformOps(this);
}
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index d7876a0..f2cb636 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -37,7 +37,7 @@
// CompletionOp
-class ServerContext::CompletionOp final : public CallOpSetInterface {
+class ServerContext::CompletionOp final : public internal::CallOpSetInterface {
public:
// initial refs: one in the server context, one in the cq
CompletionOp()
@@ -146,7 +146,7 @@
}
}
-void ServerContext::BeginCompletionOp(Call* call) {
+void ServerContext::BeginCompletionOp(internal::Call* call) {
GPR_ASSERT(!completion_op_);
completion_op_ = new CompletionOp();
if (has_notify_when_done_tag_) {
@@ -155,8 +155,8 @@
call->PerformOps(completion_op_);
}
-CompletionQueueTag* ServerContext::GetCompletionOpTag() {
- return static_cast<CompletionQueueTag*>(completion_op_);
+internal::CompletionQueueTag* ServerContext::GetCompletionOpTag() {
+ return static_cast<internal::CompletionQueueTag*>(completion_op_);
}
void ServerContext::AddInitialMetadata(const grpc::string& key,
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 140f4ce..bb7d990 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -254,6 +254,7 @@
'src/core/tsi/transport_security_adapter.cc',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc',
+ 'src/core/ext/filters/client_channel/backup_poller.cc',
'src/core/ext/filters/client_channel/channel_connectivity.cc',
'src/core/ext/filters/client_channel/client_channel.cc',
'src/core/ext/filters/client_channel/client_channel_factory.cc',
@@ -293,6 +294,7 @@
'third_party/nanopb/pb_encode.c',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
@@ -302,21 +304,7 @@
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc',
'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc',
- 'src/core/ext/census/base_resources.cc',
- 'src/core/ext/census/context.cc',
- 'src/core/ext/census/gen/census.pb.c',
- 'src/core/ext/census/gen/trace_context.pb.c',
'src/core/ext/census/grpc_context.cc',
- 'src/core/ext/census/grpc_filter.cc',
- 'src/core/ext/census/grpc_plugin.cc',
- 'src/core/ext/census/initialize.cc',
- 'src/core/ext/census/intrusive_hash_map.cc',
- 'src/core/ext/census/mlog.cc',
- 'src/core/ext/census/operation.cc',
- 'src/core/ext/census/placeholders.cc',
- 'src/core/ext/census/resource.cc',
- 'src/core/ext/census/trace_context.cc',
- 'src/core/ext/census/tracing.cc',
'src/core/ext/filters/max_age/max_age_filter.cc',
'src/core/ext/filters/message_size/message_size_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index cd1bd98..128e912 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -22,34 +22,6 @@
#include "rb_grpc_imports.generated.h"
-census_initialize_type census_initialize_import;
-census_shutdown_type census_shutdown_import;
-census_supported_type census_supported_import;
-census_enabled_type census_enabled_import;
-census_context_create_type census_context_create_import;
-census_context_destroy_type census_context_destroy_import;
-census_context_get_status_type census_context_get_status_import;
-census_context_initialize_iterator_type census_context_initialize_iterator_import;
-census_context_next_tag_type census_context_next_tag_import;
-census_context_get_tag_type census_context_get_tag_import;
-census_context_encode_type census_context_encode_import;
-census_context_decode_type census_context_decode_import;
-census_trace_mask_type census_trace_mask_import;
-census_set_trace_mask_type census_set_trace_mask_import;
-census_start_rpc_op_timestamp_type census_start_rpc_op_timestamp_import;
-census_start_client_rpc_op_type census_start_client_rpc_op_import;
-census_set_rpc_client_peer_type census_set_rpc_client_peer_import;
-census_start_server_rpc_op_type census_start_server_rpc_op_import;
-census_start_op_type census_start_op_import;
-census_end_op_type census_end_op_import;
-census_trace_print_type census_trace_print_import;
-census_trace_scan_start_type census_trace_scan_start_import;
-census_get_trace_record_type census_get_trace_record_import;
-census_trace_scan_end_type census_trace_scan_end_import;
-census_define_resource_type census_define_resource_import;
-census_delete_resource_type census_delete_resource_import;
-census_resource_id_type census_resource_id_import;
-census_record_values_type census_record_values_import;
grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
grpc_stream_compression_algorithm_name_type grpc_stream_compression_algorithm_name_import;
@@ -155,8 +127,14 @@
grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import;
grpc_secure_channel_create_type grpc_secure_channel_create_import;
grpc_server_credentials_release_type grpc_server_credentials_release_import;
+grpc_ssl_server_certificate_config_create_type grpc_ssl_server_certificate_config_create_import;
+grpc_ssl_server_certificate_config_destroy_type grpc_ssl_server_certificate_config_destroy_import;
grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
+grpc_ssl_server_credentials_create_options_using_config_type grpc_ssl_server_credentials_create_options_using_config_import;
+grpc_ssl_server_credentials_create_options_using_config_fetcher_type grpc_ssl_server_credentials_create_options_using_config_fetcher_import;
+grpc_ssl_server_credentials_options_destroy_type grpc_ssl_server_credentials_options_destroy_import;
+grpc_ssl_server_credentials_create_with_options_type grpc_ssl_server_credentials_create_with_options_import;
grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
grpc_call_set_credentials_type grpc_call_set_credentials_import;
grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
@@ -332,34 +310,6 @@
gpr_timespec_to_micros_type gpr_timespec_to_micros_import;
void grpc_rb_load_imports(HMODULE library) {
- census_initialize_import = (census_initialize_type) GetProcAddress(library, "census_initialize");
- census_shutdown_import = (census_shutdown_type) GetProcAddress(library, "census_shutdown");
- census_supported_import = (census_supported_type) GetProcAddress(library, "census_supported");
- census_enabled_import = (census_enabled_type) GetProcAddress(library, "census_enabled");
- census_context_create_import = (census_context_create_type) GetProcAddress(library, "census_context_create");
- census_context_destroy_import = (census_context_destroy_type) GetProcAddress(library, "census_context_destroy");
- census_context_get_status_import = (census_context_get_status_type) GetProcAddress(library, "census_context_get_status");
- census_context_initialize_iterator_import = (census_context_initialize_iterator_type) GetProcAddress(library, "census_context_initialize_iterator");
- census_context_next_tag_import = (census_context_next_tag_type) GetProcAddress(library, "census_context_next_tag");
- census_context_get_tag_import = (census_context_get_tag_type) GetProcAddress(library, "census_context_get_tag");
- census_context_encode_import = (census_context_encode_type) GetProcAddress(library, "census_context_encode");
- census_context_decode_import = (census_context_decode_type) GetProcAddress(library, "census_context_decode");
- census_trace_mask_import = (census_trace_mask_type) GetProcAddress(library, "census_trace_mask");
- census_set_trace_mask_import = (census_set_trace_mask_type) GetProcAddress(library, "census_set_trace_mask");
- census_start_rpc_op_timestamp_import = (census_start_rpc_op_timestamp_type) GetProcAddress(library, "census_start_rpc_op_timestamp");
- census_start_client_rpc_op_import = (census_start_client_rpc_op_type) GetProcAddress(library, "census_start_client_rpc_op");
- census_set_rpc_client_peer_import = (census_set_rpc_client_peer_type) GetProcAddress(library, "census_set_rpc_client_peer");
- census_start_server_rpc_op_import = (census_start_server_rpc_op_type) GetProcAddress(library, "census_start_server_rpc_op");
- census_start_op_import = (census_start_op_type) GetProcAddress(library, "census_start_op");
- census_end_op_import = (census_end_op_type) GetProcAddress(library, "census_end_op");
- census_trace_print_import = (census_trace_print_type) GetProcAddress(library, "census_trace_print");
- census_trace_scan_start_import = (census_trace_scan_start_type) GetProcAddress(library, "census_trace_scan_start");
- census_get_trace_record_import = (census_get_trace_record_type) GetProcAddress(library, "census_get_trace_record");
- census_trace_scan_end_import = (census_trace_scan_end_type) GetProcAddress(library, "census_trace_scan_end");
- census_define_resource_import = (census_define_resource_type) GetProcAddress(library, "census_define_resource");
- census_delete_resource_import = (census_delete_resource_type) GetProcAddress(library, "census_delete_resource");
- census_resource_id_import = (census_resource_id_type) GetProcAddress(library, "census_resource_id");
- census_record_values_import = (census_record_values_type) GetProcAddress(library, "census_record_values");
grpc_compression_algorithm_parse_import = (grpc_compression_algorithm_parse_type) GetProcAddress(library, "grpc_compression_algorithm_parse");
grpc_compression_algorithm_name_import = (grpc_compression_algorithm_name_type) GetProcAddress(library, "grpc_compression_algorithm_name");
grpc_stream_compression_algorithm_name_import = (grpc_stream_compression_algorithm_name_type) GetProcAddress(library, "grpc_stream_compression_algorithm_name");
@@ -465,8 +415,14 @@
grpc_metadata_credentials_create_from_plugin_import = (grpc_metadata_credentials_create_from_plugin_type) GetProcAddress(library, "grpc_metadata_credentials_create_from_plugin");
grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create");
grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release");
+ grpc_ssl_server_certificate_config_create_import = (grpc_ssl_server_certificate_config_create_type) GetProcAddress(library, "grpc_ssl_server_certificate_config_create");
+ grpc_ssl_server_certificate_config_destroy_import = (grpc_ssl_server_certificate_config_destroy_type) GetProcAddress(library, "grpc_ssl_server_certificate_config_destroy");
grpc_ssl_server_credentials_create_import = (grpc_ssl_server_credentials_create_type) GetProcAddress(library, "grpc_ssl_server_credentials_create");
grpc_ssl_server_credentials_create_ex_import = (grpc_ssl_server_credentials_create_ex_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_ex");
+ grpc_ssl_server_credentials_create_options_using_config_import = (grpc_ssl_server_credentials_create_options_using_config_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_options_using_config");
+ grpc_ssl_server_credentials_create_options_using_config_fetcher_import = (grpc_ssl_server_credentials_create_options_using_config_fetcher_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_options_using_config_fetcher");
+ grpc_ssl_server_credentials_options_destroy_import = (grpc_ssl_server_credentials_options_destroy_type) GetProcAddress(library, "grpc_ssl_server_credentials_options_destroy");
+ grpc_ssl_server_credentials_create_with_options_import = (grpc_ssl_server_credentials_create_with_options_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_with_options");
grpc_server_add_secure_http2_port_import = (grpc_server_add_secure_http2_port_type) GetProcAddress(library, "grpc_server_add_secure_http2_port");
grpc_call_set_credentials_import = (grpc_call_set_credentials_type) GetProcAddress(library, "grpc_call_set_credentials");
grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index c7e78b7..b9b82e5 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -25,7 +25,6 @@
#include <windows.h>
-#include <grpc/census.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/grpc_posix.h>
@@ -47,90 +46,6 @@
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
-typedef int(*census_initialize_type)(int features);
-extern census_initialize_type census_initialize_import;
-#define census_initialize census_initialize_import
-typedef void(*census_shutdown_type)(void);
-extern census_shutdown_type census_shutdown_import;
-#define census_shutdown census_shutdown_import
-typedef int(*census_supported_type)(void);
-extern census_supported_type census_supported_import;
-#define census_supported census_supported_import
-typedef int(*census_enabled_type)(void);
-extern census_enabled_type census_enabled_import;
-#define census_enabled census_enabled_import
-typedef census_context *(*census_context_create_type)(const census_context *base, const census_tag *tags, int ntags, census_context_status const **status);
-extern census_context_create_type census_context_create_import;
-#define census_context_create census_context_create_import
-typedef void(*census_context_destroy_type)(census_context *context);
-extern census_context_destroy_type census_context_destroy_import;
-#define census_context_destroy census_context_destroy_import
-typedef const census_context_status *(*census_context_get_status_type)(const census_context *context);
-extern census_context_get_status_type census_context_get_status_import;
-#define census_context_get_status census_context_get_status_import
-typedef void(*census_context_initialize_iterator_type)(const census_context *context, census_context_iterator *iterator);
-extern census_context_initialize_iterator_type census_context_initialize_iterator_import;
-#define census_context_initialize_iterator census_context_initialize_iterator_import
-typedef int(*census_context_next_tag_type)(census_context_iterator *iterator, census_tag *tag);
-extern census_context_next_tag_type census_context_next_tag_import;
-#define census_context_next_tag census_context_next_tag_import
-typedef int(*census_context_get_tag_type)(const census_context *context, const char *key, census_tag *tag);
-extern census_context_get_tag_type census_context_get_tag_import;
-#define census_context_get_tag census_context_get_tag_import
-typedef size_t(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size);
-extern census_context_encode_type census_context_encode_import;
-#define census_context_encode census_context_encode_import
-typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size);
-extern census_context_decode_type census_context_decode_import;
-#define census_context_decode census_context_decode_import
-typedef int(*census_trace_mask_type)(const census_context *context);
-extern census_trace_mask_type census_trace_mask_import;
-#define census_trace_mask census_trace_mask_import
-typedef void(*census_set_trace_mask_type)(int trace_mask);
-extern census_set_trace_mask_type census_set_trace_mask_import;
-#define census_set_trace_mask census_set_trace_mask_import
-typedef census_timestamp(*census_start_rpc_op_timestamp_type)(void);
-extern census_start_rpc_op_timestamp_type census_start_rpc_op_timestamp_import;
-#define census_start_rpc_op_timestamp census_start_rpc_op_timestamp_import
-typedef census_context *(*census_start_client_rpc_op_type)(const census_context *context, int64_t rpc_name_id, const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, const census_timestamp *start_time);
-extern census_start_client_rpc_op_type census_start_client_rpc_op_import;
-#define census_start_client_rpc_op census_start_client_rpc_op_import
-typedef void(*census_set_rpc_client_peer_type)(census_context *context, const char *peer);
-extern census_set_rpc_client_peer_type census_set_rpc_client_peer_import;
-#define census_set_rpc_client_peer census_set_rpc_client_peer_import
-typedef census_context *(*census_start_server_rpc_op_type)(const char *buffer, int64_t rpc_name_id, const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, census_timestamp *start_time);
-extern census_start_server_rpc_op_type census_start_server_rpc_op_import;
-#define census_start_server_rpc_op census_start_server_rpc_op_import
-typedef census_context *(*census_start_op_type)(census_context *context, const char *family, const char *name, int trace_mask);
-extern census_start_op_type census_start_op_import;
-#define census_start_op census_start_op_import
-typedef void(*census_end_op_type)(census_context *context, int status);
-extern census_end_op_type census_end_op_import;
-#define census_end_op census_end_op_import
-typedef void(*census_trace_print_type)(census_context *context, uint32_t type, const char *buffer, size_t n);
-extern census_trace_print_type census_trace_print_import;
-#define census_trace_print census_trace_print_import
-typedef int(*census_trace_scan_start_type)(int consume);
-extern census_trace_scan_start_type census_trace_scan_start_import;
-#define census_trace_scan_start census_trace_scan_start_import
-typedef int(*census_get_trace_record_type)(census_trace_record *trace_record);
-extern census_get_trace_record_type census_get_trace_record_import;
-#define census_get_trace_record census_get_trace_record_import
-typedef void(*census_trace_scan_end_type)();
-extern census_trace_scan_end_type census_trace_scan_end_import;
-#define census_trace_scan_end census_trace_scan_end_import
-typedef int32_t(*census_define_resource_type)(const uint8_t *resource_pb, size_t resource_pb_size);
-extern census_define_resource_type census_define_resource_import;
-#define census_define_resource census_define_resource_import
-typedef void(*census_delete_resource_type)(int32_t resource_id);
-extern census_delete_resource_type census_delete_resource_import;
-#define census_delete_resource census_delete_resource_import
-typedef int32_t(*census_resource_id_type)(const char *name);
-extern census_resource_id_type census_resource_id_import;
-#define census_resource_id census_resource_id_import
-typedef void(*census_record_values_type)(census_context *context, census_value *values, size_t nvalues);
-extern census_record_values_type census_record_values_import;
-#define census_record_values census_record_values_import
typedef int(*grpc_compression_algorithm_parse_type)(grpc_slice value, grpc_compression_algorithm *algorithm);
extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
#define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import
@@ -446,12 +361,30 @@
typedef void(*grpc_server_credentials_release_type)(grpc_server_credentials *creds);
extern grpc_server_credentials_release_type grpc_server_credentials_release_import;
#define grpc_server_credentials_release grpc_server_credentials_release_import
+typedef grpc_ssl_server_certificate_config *(*grpc_ssl_server_certificate_config_create_type)(const char *pem_root_certs, const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs);
+extern grpc_ssl_server_certificate_config_create_type grpc_ssl_server_certificate_config_create_import;
+#define grpc_ssl_server_certificate_config_create grpc_ssl_server_certificate_config_create_import
+typedef void(*grpc_ssl_server_certificate_config_destroy_type)(grpc_ssl_server_certificate_config *config);
+extern grpc_ssl_server_certificate_config_destroy_type grpc_ssl_server_certificate_config_destroy_import;
+#define grpc_ssl_server_certificate_config_destroy grpc_ssl_server_certificate_config_destroy_import
typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, int force_client_auth, void *reserved);
extern grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
#define grpc_ssl_server_credentials_create grpc_ssl_server_credentials_create_import
typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_ex_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, grpc_ssl_client_certificate_request_type client_certificate_request, void *reserved);
extern grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
#define grpc_ssl_server_credentials_create_ex grpc_ssl_server_credentials_create_ex_import
+typedef grpc_ssl_server_credentials_options *(*grpc_ssl_server_credentials_create_options_using_config_type)(grpc_ssl_client_certificate_request_type client_certificate_request, grpc_ssl_server_certificate_config *certificate_config);
+extern grpc_ssl_server_credentials_create_options_using_config_type grpc_ssl_server_credentials_create_options_using_config_import;
+#define grpc_ssl_server_credentials_create_options_using_config grpc_ssl_server_credentials_create_options_using_config_import
+typedef grpc_ssl_server_credentials_options *(*grpc_ssl_server_credentials_create_options_using_config_fetcher_type)(grpc_ssl_client_certificate_request_type client_certificate_request, grpc_ssl_server_certificate_config_callback cb, void *user_data);
+extern grpc_ssl_server_credentials_create_options_using_config_fetcher_type grpc_ssl_server_credentials_create_options_using_config_fetcher_import;
+#define grpc_ssl_server_credentials_create_options_using_config_fetcher grpc_ssl_server_credentials_create_options_using_config_fetcher_import
+typedef void(*grpc_ssl_server_credentials_options_destroy_type)(grpc_ssl_server_credentials_options *options);
+extern grpc_ssl_server_credentials_options_destroy_type grpc_ssl_server_credentials_options_destroy_import;
+#define grpc_ssl_server_credentials_options_destroy grpc_ssl_server_credentials_options_destroy_import
+typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_with_options_type)(grpc_ssl_server_credentials_options *options);
+extern grpc_ssl_server_credentials_create_with_options_type grpc_ssl_server_credentials_create_with_options_import;
+#define grpc_ssl_server_credentials_create_with_options grpc_ssl_server_credentials_create_with_options_import
typedef int(*grpc_server_add_secure_http2_port_type)(grpc_server *server, const char *addr, grpc_server_credentials *creds);
extern grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
#define grpc_server_add_secure_http2_port grpc_server_add_secure_http2_port_import
diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template
index 215d5f9..fb54de1 100644
--- a/templates/grpc.gemspec.template
+++ b/templates/grpc.gemspec.template
@@ -30,7 +30,7 @@
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.1'
- s.add_dependency 'googleauth', '~> 0.5.1'
+ s.add_dependency 'googleauth', '>= 0.5.1', '< 0.7'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0'
s.add_development_dependency 'bundler', '~> 1.9'
diff --git a/test/core/census/BUILD b/test/core/census/BUILD
deleted file mode 100644
index 24fd280..0000000
--- a/test/core/census/BUILD
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2016 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package")
-
-grpc_package(name = "test/core/census")
-
-licenses(["notice"]) # Apache v2
-
-grpc_cc_test(
- name = "context_test",
- srcs = ["context_test.c"],
- language = "C",
- deps = [
- "//:gpr",
- "//:grpc",
- "//test/core/util:gpr_test_util",
- "//test/core/util:grpc_test_util",
- ],
-)
-
-grpc_cc_test(
- name = "mlog_test",
- srcs = ["mlog_test.c"],
- language = "C",
- deps = [
- "//:gpr",
- "//:grpc",
- "//test/core/util:gpr_test_util",
- "//test/core/util:grpc_test_util",
- ],
-)
-
-grpc_cc_test(
- name = "resource_test",
- srcs = ["resource_test.c"],
- language = "C",
- data = [
- ":data/resource_empty_name.pb",
- ":data/resource_full.pb",
- ":data/resource_minimal_good.pb",
- ":data/resource_no_name.pb",
- ":data/resource_no_numerator.pb",
- ":data/resource_no_unit.pb",
- ],
- deps = [
- "//:gpr",
- "//:grpc",
- "//test/core/util:gpr_test_util",
- "//test/core/util:grpc_test_util",
- ],
-)
-
-grpc_cc_test(
- name = "trace_context_test",
- srcs = ["trace_context_test.c"],
- language = "C",
- data = [
- ":data/context_empty.pb",
- ":data/context_full.pb",
- ":data/context_no_span_options.pb",
- ":data/context_span_only.pb",
- ":data/context_trace_only.pb",
- ],
- deps = [
- "//:gpr",
- "//:grpc",
- "//test/core/util:gpr_test_util",
- "//test/core/util:grpc_test_util",
- ],
-)
diff --git a/test/core/census/README b/test/core/census/README
deleted file mode 100644
index d5363b7..0000000
--- a/test/core/census/README
+++ /dev/null
@@ -1,7 +0,0 @@
-Test source and data files for Census.
-
-binary proto files (*.pb) in data directory are generated from the *.txt file,
-via:
-
-BASE="filename"
-cat $BASE.txt | protoc --encode=google.census.Resource census.proto > $BASE.pb
diff --git a/test/core/census/context_test.c b/test/core/census/context_test.c
deleted file mode 100644
index ca5a6ec..0000000
--- a/test/core/census/context_test.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// Test census_context functions, including encoding/decoding
-
-#include <grpc/census.h>
-#include <grpc/support/log.h>
-#include <grpc/support/time.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "test/core/util/test_config.h"
-
-// A set of tags Used to create a basic context for testing. Note that
-// replace_add_delete_test() relies on specific offsets into this array - if
-// you add or delete entries, you will also need to change the test.
-#define BASIC_TAG_COUNT 8
-static census_tag basic_tags[BASIC_TAG_COUNT] = {
- /* 0 */ {"key0", "tag value", 0},
- /* 1 */ {"k1", "a", CENSUS_TAG_PROPAGATE},
- /* 2 */ {"k2", "a longer tag value supercalifragilisticexpialiadocious",
- CENSUS_TAG_STATS},
- /* 3 */ {"key_three", "", 0},
- /* 4 */ {"a_really_really_really_really_long_key_4", "random",
- CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS},
- /* 5 */ {"k5", "v5", CENSUS_TAG_PROPAGATE},
- /* 6 */ {"k6", "v6", CENSUS_TAG_STATS},
- /* 7 */ {"k7", "v7", CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS}};
-
-// Set of tags used to modify the basic context. Note that
-// replace_add_delete_test() relies on specific offsets into this array - if
-// you add or delete entries, you will also need to change the test. Other
-// tests that rely on specific instances have XXX_XXX_OFFSET definitions (also
-// change the defines below if you add/delete entires).
-#define MODIFY_TAG_COUNT 10
-static census_tag modify_tags[MODIFY_TAG_COUNT] = {
-#define REPLACE_VALUE_OFFSET 0
- /* 0 */ {"key0", "replace key0", 0}, // replaces tag value only
-#define ADD_TAG_OFFSET 1
- /* 1 */ {"new_key", "xyzzy", CENSUS_TAG_STATS}, // new tag
-#define DELETE_TAG_OFFSET 2
- /* 2 */ {"k5", NULL, 0}, // should delete tag
- /* 3 */ {"k5", NULL, 0}, // try deleting already-deleted tag
- /* 4 */ {"non-existent", NULL, 0}, // delete non-existent tag
-#define REPLACE_FLAG_OFFSET 5
- /* 5 */ {"k1", "a", 0}, // change flags only
- /* 6 */ {"k7", "bar", CENSUS_TAG_STATS}, // change flags and value
- /* 7 */ {"k2", "", CENSUS_TAG_PROPAGATE}, // more value and flags change
- /* 8 */ {"k5", "bar", 0}, // add back tag, with different value
- /* 9 */ {"foo", "bar", CENSUS_TAG_PROPAGATE}, // another new tag
-};
-
-// Utility function to compare tags. Returns true if all fields match.
-static bool compare_tag(const census_tag *t1, const census_tag *t2) {
- return (strcmp(t1->key, t2->key) == 0 && strcmp(t1->value, t2->value) == 0 &&
- t1->flags == t2->flags);
-}
-
-// Utility function to validate a tag exists in context.
-static bool validate_tag(const census_context *context, const census_tag *tag) {
- census_tag tag2;
- if (census_context_get_tag(context, tag->key, &tag2) != 1) return false;
- return compare_tag(tag, &tag2);
-}
-
-// Create an empty context.
-static void empty_test(void) {
- struct census_context *context = census_context_create(NULL, NULL, 0, NULL);
- GPR_ASSERT(context != NULL);
- const census_context_status *status = census_context_get_status(context);
- census_context_status expected = {0, 0, 0, 0, 0, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
-}
-
-// Test create and iteration over basic context.
-static void basic_test(void) {
- const census_context_status *status;
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, &status);
- census_context_status expected = {4, 4, 0, 8, 0, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_iterator it;
- census_context_initialize_iterator(context, &it);
- census_tag tag;
- while (census_context_next_tag(&it, &tag)) {
- // can't rely on tag return order: make sure it matches exactly one.
- int matches = 0;
- for (int i = 0; i < BASIC_TAG_COUNT; i++) {
- if (compare_tag(&tag, &basic_tags[i])) matches++;
- }
- GPR_ASSERT(matches == 1);
- }
- census_context_destroy(context);
-}
-
-// Test census_context_get_tag().
-static void lookup_by_key_test(void) {
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- census_tag tag;
- for (int i = 0; i < BASIC_TAG_COUNT; i++) {
- GPR_ASSERT(census_context_get_tag(context, basic_tags[i].key, &tag) == 1);
- GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
- }
- // non-existent keys
- GPR_ASSERT(census_context_get_tag(context, "key", &tag) == 0);
- GPR_ASSERT(census_context_get_tag(context, "key01", &tag) == 0);
- GPR_ASSERT(census_context_get_tag(context, "k9", &tag) == 0);
- GPR_ASSERT(census_context_get_tag(context, "random", &tag) == 0);
- GPR_ASSERT(census_context_get_tag(context, "", &tag) == 0);
- census_context_destroy(context);
-}
-
-// Try creating context with invalid entries.
-static void invalid_test(void) {
- char key[300];
- memset(key, 'k', 299);
- key[299] = 0;
- char value[300];
- memset(value, 'v', 299);
- value[299] = 0;
- census_tag tag = {key, value, 0};
- // long keys, short value. Key lengths (including terminator) should be
- // <= 255 (CENSUS_MAX_TAG_KV_LEN)
- value[3] = 0;
- GPR_ASSERT(strlen(value) == 3);
- GPR_ASSERT(strlen(key) == 299);
- const census_context_status *status;
- struct census_context *context =
- census_context_create(NULL, &tag, 1, &status);
- census_context_status expected = {0, 0, 0, 0, 0, 1, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
- key[CENSUS_MAX_TAG_KV_LEN] = 0;
- GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN);
- context = census_context_create(NULL, &tag, 1, &status);
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
- key[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
- GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN - 1);
- context = census_context_create(NULL, &tag, 1, &status);
- census_context_status expected2 = {0, 1, 0, 1, 0, 0, 0};
- GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
- census_context_destroy(context);
- // now try with long values
- value[3] = 'v';
- GPR_ASSERT(strlen(value) == 299);
- context = census_context_create(NULL, &tag, 1, &status);
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
- value[CENSUS_MAX_TAG_KV_LEN] = 0;
- GPR_ASSERT(strlen(value) == CENSUS_MAX_TAG_KV_LEN);
- context = census_context_create(NULL, &tag, 1, &status);
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
- value[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
- GPR_ASSERT(strlen(value) == CENSUS_MAX_TAG_KV_LEN - 1);
- context = census_context_create(NULL, &tag, 1, &status);
- GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
- census_context_destroy(context);
- // 0 length key.
- key[0] = 0;
- GPR_ASSERT(strlen(key) == 0);
- context = census_context_create(NULL, &tag, 1, &status);
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
- // invalid key character
- key[0] = 31; // 32 (' ') is the first valid character value
- key[1] = 0;
- GPR_ASSERT(strlen(key) == 1);
- context = census_context_create(NULL, &tag, 1, &status);
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
- // invalid value character
- key[0] = ' ';
- value[5] = 127; // 127 (DEL) is ('~' + 1)
- value[8] = 0;
- GPR_ASSERT(strlen(key) == 1);
- GPR_ASSERT(strlen(value) == 8);
- context = census_context_create(NULL, &tag, 1, &status);
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_context_destroy(context);
-}
-
-// Make a copy of a context
-static void copy_test(void) {
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- const census_context_status *status;
- struct census_context *context2 =
- census_context_create(context, NULL, 0, &status);
- census_context_status expected = {4, 4, 0, 0, 0, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- for (int i = 0; i < BASIC_TAG_COUNT; i++) {
- census_tag tag;
- GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) == 1);
- GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
- }
- census_context_destroy(context);
- census_context_destroy(context2);
-}
-
-// replace a single tag value
-static void replace_value_test(void) {
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- const census_context_status *status;
- struct census_context *context2 = census_context_create(
- context, modify_tags + REPLACE_VALUE_OFFSET, 1, &status);
- census_context_status expected = {4, 4, 0, 0, 1, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_tag tag;
- GPR_ASSERT(census_context_get_tag(
- context2, modify_tags[REPLACE_VALUE_OFFSET].key, &tag) == 1);
- GPR_ASSERT(compare_tag(&tag, &modify_tags[REPLACE_VALUE_OFFSET]));
- census_context_destroy(context);
- census_context_destroy(context2);
-}
-
-// replace a single tags flags
-static void replace_flags_test(void) {
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- const census_context_status *status;
- struct census_context *context2 = census_context_create(
- context, modify_tags + REPLACE_FLAG_OFFSET, 1, &status);
- census_context_status expected = {3, 5, 0, 0, 1, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_tag tag;
- GPR_ASSERT(census_context_get_tag(
- context2, modify_tags[REPLACE_FLAG_OFFSET].key, &tag) == 1);
- GPR_ASSERT(compare_tag(&tag, &modify_tags[REPLACE_FLAG_OFFSET]));
- census_context_destroy(context);
- census_context_destroy(context2);
-}
-
-// delete a single tag.
-static void delete_tag_test(void) {
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- const census_context_status *status;
- struct census_context *context2 = census_context_create(
- context, modify_tags + DELETE_TAG_OFFSET, 1, &status);
- census_context_status expected = {3, 4, 1, 0, 0, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_tag tag;
- GPR_ASSERT(census_context_get_tag(
- context2, modify_tags[DELETE_TAG_OFFSET].key, &tag) == 0);
- census_context_destroy(context);
- census_context_destroy(context2);
-}
-
-// add a single new tag.
-static void add_tag_test(void) {
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- const census_context_status *status;
- struct census_context *context2 =
- census_context_create(context, modify_tags + ADD_TAG_OFFSET, 1, &status);
- census_context_status expected = {4, 5, 0, 1, 0, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- census_tag tag;
- GPR_ASSERT(census_context_get_tag(context2, modify_tags[ADD_TAG_OFFSET].key,
- &tag) == 1);
- GPR_ASSERT(compare_tag(&tag, &modify_tags[ADD_TAG_OFFSET]));
- census_context_destroy(context);
- census_context_destroy(context2);
-}
-
-// test many changes at once.
-static void replace_add_delete_test(void) {
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- const census_context_status *status;
- struct census_context *context2 =
- census_context_create(context, modify_tags, MODIFY_TAG_COUNT, &status);
- census_context_status expected = {3, 7, 1, 3, 4, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- // validate context contents. Use specific indices into the two arrays
- // holding tag values.
- GPR_ASSERT(validate_tag(context2, &basic_tags[3]));
- GPR_ASSERT(validate_tag(context2, &basic_tags[4]));
- GPR_ASSERT(validate_tag(context2, &basic_tags[6]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[0]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[1]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[5]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[6]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[7]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[8]));
- GPR_ASSERT(validate_tag(context2, &modify_tags[9]));
- GPR_ASSERT(!validate_tag(context2, &basic_tags[0]));
- GPR_ASSERT(!validate_tag(context2, &basic_tags[1]));
- GPR_ASSERT(!validate_tag(context2, &basic_tags[2]));
- GPR_ASSERT(!validate_tag(context2, &basic_tags[5]));
- GPR_ASSERT(!validate_tag(context2, &basic_tags[7]));
- census_context_destroy(context);
- census_context_destroy(context2);
-}
-
-#define BUF_SIZE 200
-
-// test encode/decode.
-static void encode_decode_test(void) {
- char buffer[BUF_SIZE];
- struct census_context *context =
- census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
- // Test with too small a buffer
- GPR_ASSERT(census_context_encode(context, buffer, 2) == 0);
- // Test with sufficient buffer
- size_t buf_used = census_context_encode(context, buffer, BUF_SIZE);
- GPR_ASSERT(buf_used != 0);
- census_context *context2 = census_context_decode(buffer, buf_used);
- GPR_ASSERT(context2 != NULL);
- const census_context_status *status = census_context_get_status(context2);
- census_context_status expected = {4, 0, 0, 0, 0, 0, 0};
- GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
- for (int i = 0; i < BASIC_TAG_COUNT; i++) {
- census_tag tag;
- if (CENSUS_TAG_IS_PROPAGATED(basic_tags[i].flags)) {
- GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) ==
- 1);
- GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
- } else {
- GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) ==
- 0);
- }
- }
- census_context_destroy(context2);
- census_context_destroy(context);
-}
-
-int main(int argc, char *argv[]) {
- grpc_test_init(argc, argv);
- empty_test();
- basic_test();
- lookup_by_key_test();
- invalid_test();
- copy_test();
- replace_value_test();
- replace_flags_test();
- delete_tag_test();
- add_tag_test();
- replace_add_delete_test();
- encode_decode_test();
- return 0;
-}
diff --git a/test/core/census/data/context_empty.pb b/test/core/census/data/context_empty.pb
deleted file mode 100644
index e69de29..0000000
--- a/test/core/census/data/context_empty.pb
+++ /dev/null
diff --git a/test/core/census/data/context_empty.txt b/test/core/census/data/context_empty.txt
deleted file mode 100644
index e69de29..0000000
--- a/test/core/census/data/context_empty.txt
+++ /dev/null
diff --git a/test/core/census/data/context_full.pb b/test/core/census/data/context_full.pb
deleted file mode 100644
index 7b5895c..0000000
--- a/test/core/census/data/context_full.pb
+++ /dev/null
Binary files differ
diff --git a/test/core/census/data/context_full.txt b/test/core/census/data/context_full.txt
deleted file mode 100644
index 7d8df37..0000000
--- a/test/core/census/data/context_full.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-trace_id_hi : 5
-trace_id_lo : 1
-span_id : 7
-span_options : 1
diff --git a/test/core/census/data/context_no_span_options.pb b/test/core/census/data/context_no_span_options.pb
deleted file mode 100644
index 4b3425a..0000000
--- a/test/core/census/data/context_no_span_options.pb
+++ /dev/null
Binary files differ
diff --git a/test/core/census/data/context_no_span_options.txt b/test/core/census/data/context_no_span_options.txt
deleted file mode 100644
index 4c8398f..0000000
--- a/test/core/census/data/context_no_span_options.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-trace_id_hi : 5
-trace_id_lo : 1
-span_id : 7
diff --git a/test/core/census/data/context_span_only.pb b/test/core/census/data/context_span_only.pb
deleted file mode 100644
index a9315be..0000000
--- a/test/core/census/data/context_span_only.pb
+++ /dev/null
Binary files differ
diff --git a/test/core/census/data/context_span_only.txt b/test/core/census/data/context_span_only.txt
deleted file mode 100644
index 4e473fc..0000000
--- a/test/core/census/data/context_span_only.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-span_id : 7
-span_options : 1
diff --git a/test/core/census/data/context_trace_only.pb b/test/core/census/data/context_trace_only.pb
deleted file mode 100644
index aabb325..0000000
--- a/test/core/census/data/context_trace_only.pb
+++ /dev/null
Binary files differ
diff --git a/test/core/census/data/context_trace_only.txt b/test/core/census/data/context_trace_only.txt
deleted file mode 100644
index e48a6d7..0000000
--- a/test/core/census/data/context_trace_only.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-trace_id_hi : 5
-trace_id_lo : 1
-span_options : 1
diff --git a/test/core/census/data/resource_empty_name.pb b/test/core/census/data/resource_empty_name.pb
deleted file mode 100644
index 4d54744..0000000
--- a/test/core/census/data/resource_empty_name.pb
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/test/core/census/data/resource_empty_name.txt b/test/core/census/data/resource_empty_name.txt
deleted file mode 100644
index 271fd32..0000000
--- a/test/core/census/data/resource_empty_name.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# Name is present, but empty.
-name : ''
-unit {
- numerator : SECS
-}
diff --git a/test/core/census/data/resource_full.pb b/test/core/census/data/resource_full.pb
deleted file mode 100644
index e4c6a2a..0000000
--- a/test/core/census/data/resource_full.pb
+++ /dev/null
Binary files differ
diff --git a/test/core/census/data/resource_full.txt b/test/core/census/data/resource_full.txt
deleted file mode 100644
index 1aa2faf..0000000
--- a/test/core/census/data/resource_full.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# A full resource definition - all fields filled out.
-name : 'full_resource'
-description : 'A resource with everything defined'
-unit {
- # Megabits per second.
- prefix : 6
- numerator : BITS
- denominator : SECS
-}
diff --git a/test/core/census/data/resource_minimal_good.pb b/test/core/census/data/resource_minimal_good.pb
deleted file mode 100644
index 7100c46..0000000
--- a/test/core/census/data/resource_minimal_good.pb
+++ /dev/null
@@ -1,2 +0,0 @@
-
-minimal_good
\ No newline at end of file
diff --git a/test/core/census/data/resource_minimal_good.txt b/test/core/census/data/resource_minimal_good.txt
deleted file mode 100644
index a7a7e71..0000000
--- a/test/core/census/data/resource_minimal_good.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# A minimal "good" Resource definition: has a name and numerator/unit.
-name : 'minimal_good'
-unit {
- numerator : SECS
-}
diff --git a/test/core/census/data/resource_no_name.pb b/test/core/census/data/resource_no_name.pb
deleted file mode 100644
index 4d54744..0000000
--- a/test/core/census/data/resource_no_name.pb
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/test/core/census/data/resource_no_name.txt b/test/core/census/data/resource_no_name.txt
deleted file mode 100644
index 8f12a91..0000000
--- a/test/core/census/data/resource_no_name.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# The minimal good Resource without a name.
-unit {
- numerator : SECS
-}
diff --git a/test/core/census/data/resource_no_numerator.pb b/test/core/census/data/resource_no_numerator.pb
deleted file mode 100644
index 2a5ccee..0000000
--- a/test/core/census/data/resource_no_numerator.pb
+++ /dev/null
@@ -1,2 +0,0 @@
-
-resource_no_numeratorýÿÿÿÿÿÿÿÿ
\ No newline at end of file
diff --git a/test/core/census/data/resource_no_numerator.txt b/test/core/census/data/resource_no_numerator.txt
deleted file mode 100644
index fc1fec7..0000000
--- a/test/core/census/data/resource_no_numerator.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Resource without a numerator
-name : 'resource_no_numerator'
-unit {
- prefix : -3
- denominator : SECS
-}
diff --git a/test/core/census/data/resource_no_unit.pb b/test/core/census/data/resource_no_unit.pb
deleted file mode 100644
index 9dca262..0000000
--- a/test/core/census/data/resource_no_unit.pb
+++ /dev/null
@@ -1,2 +0,0 @@
-
-resource_no_unit
\ No newline at end of file
diff --git a/test/core/census/data/resource_no_unit.txt b/test/core/census/data/resource_no_unit.txt
deleted file mode 100644
index c5d5115..0000000
--- a/test/core/census/data/resource_no_unit.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-# The minimal good resource without a unit
-name : 'resource_no_unit'
diff --git a/test/core/census/intrusive_hash_map_test.c b/test/core/census/intrusive_hash_map_test.c
deleted file mode 100644
index 0826b55..0000000
--- a/test/core/census/intrusive_hash_map_test.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/intrusive_hash_map.h"
-
-#include <grpc/support/log.h>
-#include <grpc/support/useful.h>
-#include "test/core/util/test_config.h"
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* The initial size of an intrusive hash map will be 2 to this power. */
-static const uint32_t kInitialLog2Size = 4;
-
-/* Simple object used for testing intrusive_hash_map. */
-typedef struct object { uint64_t val; } object;
-
-/* Helper function to allocate and initialize object. */
-static __inline object *make_new_object(uint64_t val) {
- object *obj = (object *)gpr_malloc(sizeof(object));
- obj->val = val;
- return obj;
-}
-
-/* Wrapper struct for object. */
-typedef struct ptr_item {
- INTRUSIVE_HASH_MAP_HEADER;
- object *obj;
-} ptr_item;
-
-/* Helper function that creates a new hash map item. It is up to the user to
- * free the item that was allocated. */
-static __inline ptr_item *make_ptr_item(uint64_t key, uint64_t value) {
- ptr_item *new_item = (ptr_item *)gpr_malloc(sizeof(ptr_item));
- new_item->IHM_key = key;
- new_item->IHM_hash_link = NULL;
- new_item->obj = make_new_object(value);
- return new_item;
-}
-
-/* Helper function to deallocate ptr_item. */
-static void free_ptr_item(void *ptr) { gpr_free(((ptr_item *)ptr)->obj); }
-
-/* Simple string object used for testing intrusive_hash_map. */
-typedef struct string_item {
- INTRUSIVE_HASH_MAP_HEADER;
- // User data.
- char buf[32];
- uint16_t len;
-} string_item;
-
-/* Helper function to allocate and initialize string object. */
-static string_item *make_string_item(uint64_t key, const char *buf,
- uint16_t len) {
- string_item *item = (string_item *)gpr_malloc(sizeof(string_item));
- item->IHM_key = key;
- item->IHM_hash_link = NULL;
- item->len = len;
- memcpy(item->buf, buf, sizeof(char) * len);
- return item;
-}
-
-/* Helper function for comparing two string objects. */
-static bool compare_string_item(const string_item *A, const string_item *B) {
- if (A->IHM_key != B->IHM_key || A->len != B->len)
- return false;
- else {
- for (int i = 0; i < A->len; ++i) {
- if (A->buf[i] != B->buf[i]) return false;
- }
- }
-
- return true;
-}
-
-void test_empty() {
- intrusive_hash_map hash_map;
- intrusive_hash_map_init(&hash_map, kInitialLog2Size);
- GPR_ASSERT(0 == intrusive_hash_map_size(&hash_map));
- GPR_ASSERT(intrusive_hash_map_empty(&hash_map));
- intrusive_hash_map_free(&hash_map, NULL);
-}
-
-void test_single_item() {
- intrusive_hash_map hash_map;
- intrusive_hash_map_init(&hash_map, kInitialLog2Size);
-
- ptr_item *new_item = make_ptr_item(10, 20);
- bool ok = intrusive_hash_map_insert(&hash_map, (hm_item *)new_item);
- GPR_ASSERT(ok);
-
- ptr_item *item1 =
- (ptr_item *)intrusive_hash_map_find(&hash_map, (uint64_t)10);
- GPR_ASSERT(item1->obj->val == 20);
- GPR_ASSERT(item1 == new_item);
-
- ptr_item *item2 =
- (ptr_item *)intrusive_hash_map_erase(&hash_map, (uint64_t)10);
- GPR_ASSERT(item2 == new_item);
-
- gpr_free(new_item->obj);
- gpr_free(new_item);
- GPR_ASSERT(0 == intrusive_hash_map_size(&hash_map));
- intrusive_hash_map_free(&hash_map, &free_ptr_item);
-}
-
-void test_two_items() {
- intrusive_hash_map hash_map;
- intrusive_hash_map_init(&hash_map, kInitialLog2Size);
-
- string_item *new_item1 = make_string_item(10, "test1", 5);
- bool ok = intrusive_hash_map_insert(&hash_map, (hm_item *)new_item1);
- GPR_ASSERT(ok);
- string_item *new_item2 = make_string_item(20, "test2", 5);
- ok = intrusive_hash_map_insert(&hash_map, (hm_item *)new_item2);
- GPR_ASSERT(ok);
-
- string_item *item1 =
- (string_item *)intrusive_hash_map_find(&hash_map, (uint64_t)10);
- GPR_ASSERT(compare_string_item(new_item1, item1));
- GPR_ASSERT(item1 == new_item1);
- string_item *item2 =
- (string_item *)intrusive_hash_map_find(&hash_map, (uint64_t)20);
- GPR_ASSERT(compare_string_item(new_item2, item2));
- GPR_ASSERT(item2 == new_item2);
-
- item1 = (string_item *)intrusive_hash_map_erase(&hash_map, (uint64_t)10);
- GPR_ASSERT(item1 == new_item1);
- item2 = (string_item *)intrusive_hash_map_erase(&hash_map, (uint64_t)20);
- GPR_ASSERT(item2 == new_item2);
-
- gpr_free(new_item1);
- gpr_free(new_item2);
- GPR_ASSERT(0 == intrusive_hash_map_size(&hash_map));
- intrusive_hash_map_free(&hash_map, NULL);
-}
-
-// Test resetting and clearing the hash map.
-void test_reset_clear() {
- intrusive_hash_map hash_map;
- intrusive_hash_map_init(&hash_map, kInitialLog2Size);
-
- // Add some data to the hash_map.
- for (uint64_t i = 0; i < 3; ++i) {
- intrusive_hash_map_insert(&hash_map, (hm_item *)make_ptr_item(i, i));
- }
- GPR_ASSERT(3 == intrusive_hash_map_size(&hash_map));
-
- // Test find.
- for (uint64_t i = 0; i < 3; ++i) {
- ptr_item *item = (ptr_item *)intrusive_hash_map_find(&hash_map, i);
- GPR_ASSERT(item != NULL);
- GPR_ASSERT(item->IHM_key == i && item->obj->val == i);
- }
-
- intrusive_hash_map_clear(&hash_map, &free_ptr_item);
- GPR_ASSERT(intrusive_hash_map_empty(&hash_map));
- intrusive_hash_map_free(&hash_map, &free_ptr_item);
-}
-
-// Check that the hash_map contains every key between [min_value, max_value]
-// (inclusive).
-void check_hash_map_values(intrusive_hash_map *hash_map, uint64_t min_value,
- uint64_t max_value) {
- GPR_ASSERT(intrusive_hash_map_size(hash_map) == max_value - min_value + 1);
-
- for (uint64_t i = min_value; i <= max_value; ++i) {
- ptr_item *item = (ptr_item *)intrusive_hash_map_find(hash_map, i);
- GPR_ASSERT(item != NULL);
- GPR_ASSERT(item->obj->val == i);
- }
-}
-
-// Add many items and cause the hash_map to extend.
-void test_extend() {
- intrusive_hash_map hash_map;
- intrusive_hash_map_init(&hash_map, kInitialLog2Size);
-
- const uint64_t kNumValues = (1 << 16);
-
- for (uint64_t i = 0; i < kNumValues; ++i) {
- ptr_item *item = make_ptr_item(i, i);
- bool ok = intrusive_hash_map_insert(&hash_map, (hm_item *)item);
- GPR_ASSERT(ok);
- if (i % 1000 == 0) {
- check_hash_map_values(&hash_map, 0, i);
- }
- }
-
- for (uint64_t i = 0; i < kNumValues; ++i) {
- ptr_item *item = (ptr_item *)intrusive_hash_map_find(&hash_map, i);
- GPR_ASSERT(item != NULL);
- GPR_ASSERT(item->IHM_key == i && item->obj->val == i);
- ptr_item *item2 = (ptr_item *)intrusive_hash_map_erase(&hash_map, i);
- GPR_ASSERT(item == item2);
- gpr_free(item->obj);
- gpr_free(item);
- }
-
- GPR_ASSERT(intrusive_hash_map_empty(&hash_map));
- intrusive_hash_map_free(&hash_map, &free_ptr_item);
-}
-
-void test_stress() {
- intrusive_hash_map hash_map;
- intrusive_hash_map_init(&hash_map, kInitialLog2Size);
- size_t n = 0;
-
- // Randomly add and insert entries 1000000 times.
- for (uint64_t i = 0; i < 1000000; ++i) {
- int op = rand() & 0x1;
-
- switch (op) {
- // Case 0 is insertion of entry.
- case 0: {
- uint64_t key = (uint64_t)(rand() % 10000);
- ptr_item *item = make_ptr_item(key, key);
- bool ok = intrusive_hash_map_insert(&hash_map, (hm_item *)item);
- if (ok) {
- n++;
- } else {
- gpr_free(item->obj);
- gpr_free(item);
- }
- break;
- }
- // Case 1 is removal of entry.
- case 1: {
- uint64_t key = (uint64_t)(rand() % 10000);
- ptr_item *item = (ptr_item *)intrusive_hash_map_find(&hash_map, key);
- if (item != NULL) {
- n--;
- GPR_ASSERT(key == item->obj->val);
- ptr_item *item2 =
- (ptr_item *)intrusive_hash_map_erase(&hash_map, key);
- GPR_ASSERT(item == item2);
- gpr_free(item->obj);
- gpr_free(item);
- }
- break;
- }
- }
- }
- // Check size
- GPR_ASSERT(n == intrusive_hash_map_size(&hash_map));
-
- // Clean the hash_map up.
- intrusive_hash_map_clear(&hash_map, &free_ptr_item);
- GPR_ASSERT(intrusive_hash_map_empty(&hash_map));
- intrusive_hash_map_free(&hash_map, &free_ptr_item);
-}
-
-int main(int argc, char **argv) {
- grpc_test_init(argc, argv);
- gpr_time_init();
- srand((unsigned)gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
-
- test_empty();
- test_single_item();
- test_two_items();
- test_reset_clear();
- test_extend();
- test_stress();
-
- return 0;
-}
diff --git a/test/core/census/mlog_test.c b/test/core/census/mlog_test.c
deleted file mode 100644
index 968fd91..0000000
--- a/test/core/census/mlog_test.c
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/mlog.h"
-#include <grpc/support/cpu.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
-#include <grpc/support/time.h>
-#include <grpc/support/useful.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "test/core/util/test_config.h"
-
-// Change this to non-zero if you want more output.
-#define VERBOSE 0
-
-// Log size to use for all tests.
-#define LOG_SIZE_IN_MB 1
-#define LOG_SIZE_IN_BYTES (LOG_SIZE_IN_MB << 20)
-
-// Fills in 'record' of size 'size'. Each byte in record is filled in with the
-// same value. The value is extracted from 'record' pointer.
-static void write_record(char* record, size_t size) {
- char data = (char)((uintptr_t)record % 255);
- memset(record, data, size);
-}
-
-// Reads fixed size records. Returns the number of records read in
-// 'num_records'.
-static void read_records(size_t record_size, const char* buffer,
- size_t buffer_size, int* num_records) {
- GPR_ASSERT(buffer_size >= record_size);
- GPR_ASSERT(buffer_size % record_size == 0);
- *num_records = (int)(buffer_size / record_size);
- for (int i = 0; i < *num_records; ++i) {
- const char* record = buffer + (record_size * (size_t)i);
- char data = (char)((uintptr_t)record % 255);
- for (size_t j = 0; j < record_size; ++j) {
- GPR_ASSERT(data == record[j]);
- }
- }
-}
-
-// Tries to write the specified number of records. Stops when the log gets
-// full. Returns the number of records written. Spins for random
-// number of times, up to 'max_spin_count', between writes.
-static int write_records_to_log(int writer_id, size_t record_size,
- int num_records, int max_spin_count) {
- int counter = 0;
- for (int i = 0; i < num_records; ++i) {
- int spin_count = max_spin_count ? rand() % max_spin_count : 0;
- if (VERBOSE && (counter++ == num_records / 10)) {
- printf(" Writer %d: %d out of %d written\n", writer_id, i, num_records);
- counter = 0;
- }
- char* record = (char*)(census_log_start_write(record_size));
- if (record == NULL) {
- return i;
- }
- write_record(record, record_size);
- census_log_end_write(record, record_size);
- for (int j = 0; j < spin_count; ++j) {
- GPR_ASSERT(j >= 0);
- }
- }
- return num_records;
-}
-
-// Performs a single read iteration. Returns the number of records read.
-static int perform_read_iteration(size_t record_size) {
- const void* read_buffer = NULL;
- size_t bytes_available;
- int records_read = 0;
- census_log_init_reader();
- while ((read_buffer = census_log_read_next(&bytes_available))) {
- int num_records = 0;
- read_records(record_size, (const char*)read_buffer, bytes_available,
- &num_records);
- records_read += num_records;
- }
- return records_read;
-}
-
-// Asserts that the log is empty.
-static void assert_log_empty(void) {
- census_log_init_reader();
- size_t bytes_available;
- GPR_ASSERT(census_log_read_next(&bytes_available) == NULL);
-}
-
-// Fills the log and verifies data. If 'no fragmentation' is true, records
-// are sized such that CENSUS_LOG_2_MAX_RECORD_SIZE is a multiple of record
-// size. If not a circular log, verifies that the number of records written
-// match the number of records read.
-static void fill_log(size_t log_size, int no_fragmentation, int circular_log) {
- size_t size;
- if (no_fragmentation) {
- int log2size = rand() % (CENSUS_LOG_2_MAX_RECORD_SIZE + 1);
- size = ((size_t)1 << log2size);
- } else {
- while (1) {
- size = 1 + ((size_t)rand() % CENSUS_LOG_MAX_RECORD_SIZE);
- if (CENSUS_LOG_MAX_RECORD_SIZE % size) {
- break;
- }
- }
- }
- int records_written =
- write_records_to_log(0 /* writer id */, size,
- (int)((log_size / size) * 2), 0 /* spin count */);
- int records_read = perform_read_iteration(size);
- if (!circular_log) {
- GPR_ASSERT(records_written == records_read);
- }
- assert_log_empty();
-}
-
-// Structure to pass args to writer_thread
-typedef struct writer_thread_args {
- // Index of this thread in the writers vector.
- int index;
- // Record size.
- size_t record_size;
- // Number of records to write.
- int num_records;
- // Used to signal when writer is complete
- gpr_cv* done;
- gpr_mu* mu;
- int* count;
-} writer_thread_args;
-
-// Writes the given number of records of random size (up to kMaxRecordSize) and
-// random data to the specified log.
-static void writer_thread(void* arg) {
- writer_thread_args* args = (writer_thread_args*)arg;
- // Maximum number of times to spin between writes.
- static const int MAX_SPIN_COUNT = 50;
- int records_written = 0;
- if (VERBOSE) {
- printf(" Writer %d starting\n", args->index);
- }
- while (records_written < args->num_records) {
- records_written += write_records_to_log(args->index, args->record_size,
- args->num_records - records_written,
- MAX_SPIN_COUNT);
- if (records_written < args->num_records) {
- // Ran out of log space. Sleep for a bit and let the reader catch up.
- // This should never happen for circular logs.
- if (VERBOSE) {
- printf(
- " Writer %d stalled due to out-of-space: %d out of %d "
- "written\n",
- args->index, records_written, args->num_records);
- }
- gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(10));
- }
- }
- // Done. Decrement count and signal.
- gpr_mu_lock(args->mu);
- (*args->count)--;
- gpr_cv_signal(args->done);
- if (VERBOSE) {
- printf(" Writer %d done\n", args->index);
- }
- gpr_mu_unlock(args->mu);
-}
-
-// struct to pass args to reader_thread
-typedef struct reader_thread_args {
- // Record size.
- size_t record_size;
- // Interval between read iterations.
- int read_iteration_interval_in_msec;
- // Total number of records.
- int total_records;
- // Signalled when reader should stop.
- gpr_cv stop;
- int stop_flag;
- // Used to signal when reader has finished
- gpr_cv* done;
- gpr_mu* mu;
- int running;
-} reader_thread_args;
-
-// Reads and verifies the specified number of records. Reader can also be
-// stopped via gpr_cv_signal(&args->stop). Sleeps for 'read_interval_in_msec'
-// between read iterations.
-static void reader_thread(void* arg) {
- reader_thread_args* args = (reader_thread_args*)arg;
- if (VERBOSE) {
- printf(" Reader starting\n");
- }
- gpr_timespec interval = gpr_time_from_micros(
- args->read_iteration_interval_in_msec * 1000, GPR_TIMESPAN);
- gpr_mu_lock(args->mu);
- int records_read = 0;
- int num_iterations = 0;
- int counter = 0;
- while (!args->stop_flag && records_read < args->total_records) {
- gpr_cv_wait(&args->stop, args->mu, interval);
- if (!args->stop_flag) {
- records_read += perform_read_iteration(args->record_size);
- GPR_ASSERT(records_read <= args->total_records);
- if (VERBOSE && (counter++ == 100000)) {
- printf(" Reader: %d out of %d read\n", records_read,
- args->total_records);
- counter = 0;
- }
- ++num_iterations;
- }
- }
- // Done
- args->running = 0;
- gpr_cv_signal(args->done);
- if (VERBOSE) {
- printf(" Reader: records: %d, iterations: %d\n", records_read,
- num_iterations);
- }
- gpr_mu_unlock(args->mu);
-}
-
-// Creates NUM_WRITERS writers where each writer writes NUM_RECORDS_PER_WRITER
-// records. Also, starts a reader that iterates over and reads blocks every
-// READ_ITERATION_INTERVAL_IN_MSEC.
-// Number of writers.
-#define NUM_WRITERS 5
-static void multiple_writers_single_reader(int circular_log) {
- // Sleep interval between read iterations.
- static const int READ_ITERATION_INTERVAL_IN_MSEC = 10;
- // Maximum record size.
- static const size_t MAX_RECORD_SIZE = 20;
- // Number of records written by each writer. This is sized such that we
- // will write through the entire log ~10 times.
- const int NUM_RECORDS_PER_WRITER =
- (int)((10 * census_log_remaining_space()) / (MAX_RECORD_SIZE / 2)) /
- NUM_WRITERS;
- size_t record_size = ((size_t)rand() % MAX_RECORD_SIZE) + 1;
- // Create and start writers.
- writer_thread_args writers[NUM_WRITERS];
- int writers_count = NUM_WRITERS;
- gpr_cv writers_done;
- gpr_mu writers_mu; // protects writers_done and writers_count
- gpr_cv_init(&writers_done);
- gpr_mu_init(&writers_mu);
- gpr_thd_id id;
- for (int i = 0; i < NUM_WRITERS; ++i) {
- writers[i].index = i;
- writers[i].record_size = record_size;
- writers[i].num_records = NUM_RECORDS_PER_WRITER;
- writers[i].done = &writers_done;
- writers[i].count = &writers_count;
- writers[i].mu = &writers_mu;
- gpr_thd_new(&id, &writer_thread, &writers[i], NULL);
- }
- // Start reader.
- gpr_cv reader_done;
- gpr_mu reader_mu; // protects reader_done and reader.running
- reader_thread_args reader;
- reader.record_size = record_size;
- reader.read_iteration_interval_in_msec = READ_ITERATION_INTERVAL_IN_MSEC;
- reader.total_records = NUM_WRITERS * NUM_RECORDS_PER_WRITER;
- reader.stop_flag = 0;
- gpr_cv_init(&reader.stop);
- gpr_cv_init(&reader_done);
- reader.done = &reader_done;
- gpr_mu_init(&reader_mu);
- reader.mu = &reader_mu;
- reader.running = 1;
- gpr_thd_new(&id, &reader_thread, &reader, NULL);
- // Wait for writers to finish.
- gpr_mu_lock(&writers_mu);
- while (writers_count != 0) {
- gpr_cv_wait(&writers_done, &writers_mu, gpr_inf_future(GPR_CLOCK_REALTIME));
- }
- gpr_mu_unlock(&writers_mu);
- gpr_mu_destroy(&writers_mu);
- gpr_cv_destroy(&writers_done);
- gpr_mu_lock(&reader_mu);
- if (circular_log) {
- // Stop reader.
- reader.stop_flag = 1;
- gpr_cv_signal(&reader.stop);
- }
- // wait for reader to finish
- while (reader.running) {
- gpr_cv_wait(&reader_done, &reader_mu, gpr_inf_future(GPR_CLOCK_REALTIME));
- }
- if (circular_log) {
- // Assert that there were no out-of-space errors.
- GPR_ASSERT(0 == census_log_out_of_space_count());
- }
- gpr_mu_unlock(&reader_mu);
- gpr_mu_destroy(&reader_mu);
- gpr_cv_destroy(&reader_done);
- if (VERBOSE) {
- printf(" Reader: finished\n");
- }
-}
-
-static void setup_test(int circular_log) {
- census_log_initialize(LOG_SIZE_IN_MB, circular_log);
- // GPR_ASSERT(census_log_remaining_space() == LOG_SIZE_IN_BYTES);
-}
-
-// Attempts to create a record of invalid size (size >
-// CENSUS_LOG_MAX_RECORD_SIZE).
-void test_invalid_record_size(void) {
- static const size_t INVALID_SIZE = CENSUS_LOG_MAX_RECORD_SIZE + 1;
- static const size_t VALID_SIZE = 1;
- printf("Starting test: invalid record size\n");
- setup_test(0);
- void* record = census_log_start_write(INVALID_SIZE);
- GPR_ASSERT(record == NULL);
- // Now try writing a valid record.
- record = census_log_start_write(VALID_SIZE);
- GPR_ASSERT(record != NULL);
- census_log_end_write(record, VALID_SIZE);
- // Verifies that available space went down by one block. In theory, this
- // check can fail if the thread is context switched to a new CPU during the
- // start_write execution (multiple blocks get allocated), but this has not
- // been observed in practice.
- // GPR_ASSERT(LOG_SIZE_IN_BYTES - CENSUS_LOG_MAX_RECORD_SIZE ==
- // census_log_remaining_space());
- census_log_shutdown();
-}
-
-// Tests end_write() with a different size than what was specified in
-// start_write().
-void test_end_write_with_different_size(void) {
- static const size_t START_WRITE_SIZE = 10;
- static const size_t END_WRITE_SIZE = 7;
- printf("Starting test: end write with different size\n");
- setup_test(0);
- void* record_written = census_log_start_write(START_WRITE_SIZE);
- GPR_ASSERT(record_written != NULL);
- census_log_end_write(record_written, END_WRITE_SIZE);
- census_log_init_reader();
- size_t bytes_available;
- const void* record_read = census_log_read_next(&bytes_available);
- GPR_ASSERT(record_written == record_read);
- GPR_ASSERT(END_WRITE_SIZE == bytes_available);
- assert_log_empty();
- census_log_shutdown();
-}
-
-// Verifies that pending records are not available via read_next().
-void test_read_pending_record(void) {
- static const size_t PR_RECORD_SIZE = 1024;
- printf("Starting test: read pending record\n");
- setup_test(0);
- // Start a write.
- void* record_written = census_log_start_write(PR_RECORD_SIZE);
- GPR_ASSERT(record_written != NULL);
- // As write is pending, read should fail.
- census_log_init_reader();
- size_t bytes_available;
- const void* record_read = census_log_read_next(&bytes_available);
- GPR_ASSERT(record_read == NULL);
- // A read followed by end_write() should succeed.
- census_log_end_write(record_written, PR_RECORD_SIZE);
- census_log_init_reader();
- record_read = census_log_read_next(&bytes_available);
- GPR_ASSERT(record_written == record_read);
- GPR_ASSERT(PR_RECORD_SIZE == bytes_available);
- assert_log_empty();
- census_log_shutdown();
-}
-
-// Tries reading beyond pending write.
-void test_read_beyond_pending_record(void) {
- printf("Starting test: read beyond pending record\n");
- setup_test(0);
- // Start a write.
- const size_t incomplete_record_size = 10;
- void* incomplete_record = census_log_start_write(incomplete_record_size);
- GPR_ASSERT(incomplete_record != NULL);
- const size_t complete_record_size = 20;
- void* complete_record = census_log_start_write(complete_record_size);
- GPR_ASSERT(complete_record != NULL);
- GPR_ASSERT(complete_record != incomplete_record);
- census_log_end_write(complete_record, complete_record_size);
- // Now iterate over blocks to read completed records.
- census_log_init_reader();
- size_t bytes_available;
- const void* record_read = census_log_read_next(&bytes_available);
- GPR_ASSERT(complete_record == record_read);
- GPR_ASSERT(complete_record_size == bytes_available);
- // Complete first record.
- census_log_end_write(incomplete_record, incomplete_record_size);
- // Have read past the incomplete record, so read_next() should return NULL.
- // NB: this test also assumes our thread did not get switched to a different
- // CPU between the two start_write calls
- record_read = census_log_read_next(&bytes_available);
- GPR_ASSERT(record_read == NULL);
- // Reset reader to get the newly completed record.
- census_log_init_reader();
- record_read = census_log_read_next(&bytes_available);
- GPR_ASSERT(incomplete_record == record_read);
- GPR_ASSERT(incomplete_record_size == bytes_available);
- assert_log_empty();
- census_log_shutdown();
-}
-
-// Tests scenario where block being read is detached from a core and put on the
-// dirty list.
-void test_detached_while_reading(void) {
- printf("Starting test: detached while reading\n");
- setup_test(0);
- // Start a write.
- static const size_t DWR_RECORD_SIZE = 10;
- void* record_written = census_log_start_write(DWR_RECORD_SIZE);
- GPR_ASSERT(record_written != NULL);
- census_log_end_write(record_written, DWR_RECORD_SIZE);
- // Read this record.
- census_log_init_reader();
- size_t bytes_available;
- const void* record_read = census_log_read_next(&bytes_available);
- GPR_ASSERT(record_read != NULL);
- GPR_ASSERT(DWR_RECORD_SIZE == bytes_available);
- // Now fill the log. This will move the block being read from core-local
- // array to the dirty list.
- while ((record_written = census_log_start_write(DWR_RECORD_SIZE))) {
- census_log_end_write(record_written, DWR_RECORD_SIZE);
- }
-
- // In this iteration, read_next() should only traverse blocks in the
- // core-local array. Therefore, we expect at most gpr_cpu_num_cores() more
- // blocks. As log is full, if read_next() is traversing the dirty list, we
- // will get more than gpr_cpu_num_cores() blocks.
- int block_read = 0;
- while ((record_read = census_log_read_next(&bytes_available))) {
- ++block_read;
- GPR_ASSERT(block_read <= (int)gpr_cpu_num_cores());
- }
- census_log_shutdown();
-}
-
-// Fills non-circular log with records sized such that size is a multiple of
-// CENSUS_LOG_MAX_RECORD_SIZE (no per-block fragmentation).
-void test_fill_log_no_fragmentation(void) {
- printf("Starting test: fill log no fragmentation\n");
- const int circular = 0;
- setup_test(circular);
- fill_log(LOG_SIZE_IN_BYTES, 1 /* no fragmentation */, circular);
- census_log_shutdown();
-}
-
-// Fills circular log with records sized such that size is a multiple of
-// CENSUS_LOG_MAX_RECORD_SIZE (no per-block fragmentation).
-void test_fill_circular_log_no_fragmentation(void) {
- printf("Starting test: fill circular log no fragmentation\n");
- const int circular = 1;
- setup_test(circular);
- fill_log(LOG_SIZE_IN_BYTES, 1 /* no fragmentation */, circular);
- census_log_shutdown();
-}
-
-// Fills non-circular log with records that may straddle end of a block.
-void test_fill_log_with_straddling_records(void) {
- printf("Starting test: fill log with straddling records\n");
- const int circular = 0;
- setup_test(circular);
- fill_log(LOG_SIZE_IN_BYTES, 0 /* block straddling records */, circular);
- census_log_shutdown();
-}
-
-// Fills circular log with records that may straddle end of a block.
-void test_fill_circular_log_with_straddling_records(void) {
- printf("Starting test: fill circular log with straddling records\n");
- const int circular = 1;
- setup_test(circular);
- fill_log(LOG_SIZE_IN_BYTES, 0 /* block straddling records */, circular);
- census_log_shutdown();
-}
-
-// Tests scenario where multiple writers and a single reader are using a log
-// that is configured to discard old records.
-void test_multiple_writers_circular_log(void) {
- printf("Starting test: multiple writers circular log\n");
- const int circular = 1;
- setup_test(circular);
- multiple_writers_single_reader(circular);
- census_log_shutdown();
-}
-
-// Tests scenario where multiple writers and a single reader are using a log
-// that is configured to discard old records.
-void test_multiple_writers(void) {
- printf("Starting test: multiple writers\n");
- const int circular = 0;
- setup_test(circular);
- multiple_writers_single_reader(circular);
- census_log_shutdown();
-}
-
-// Repeat the straddling records and multiple writers tests with a small log.
-void test_small_log(void) {
- printf("Starting test: small log\n");
- const int circular = 0;
- census_log_initialize(0, circular);
- size_t log_size = census_log_remaining_space();
- GPR_ASSERT(log_size > 0);
- fill_log(log_size, 0, circular);
- census_log_shutdown();
- census_log_initialize(0, circular);
- multiple_writers_single_reader(circular);
- census_log_shutdown();
-}
-
-void test_performance(void) {
- for (size_t write_size = 1; write_size < CENSUS_LOG_MAX_RECORD_SIZE;
- write_size *= 2) {
- setup_test(0);
- gpr_timespec start_time = gpr_now(GPR_CLOCK_REALTIME);
- int nrecords = 0;
- while (1) {
- void* record = census_log_start_write(write_size);
- if (record == NULL) {
- break;
- }
- census_log_end_write(record, write_size);
- nrecords++;
- }
- gpr_timespec write_time =
- gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time);
- double write_time_micro =
- (double)write_time.tv_sec * 1000000 + (double)write_time.tv_nsec / 1000;
- census_log_shutdown();
- printf(
- "Wrote %d %d byte records in %.3g microseconds: %g records/us "
- "(%g ns/record), %g gigabytes/s\n",
- nrecords, (int)write_size, write_time_micro,
- nrecords / write_time_micro, 1000 * write_time_micro / nrecords,
- (double)((int)write_size * nrecords) / write_time_micro / 1000);
- }
-}
-
-int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
- gpr_time_init();
- srand((unsigned)gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
- test_invalid_record_size();
- test_end_write_with_different_size();
- test_read_pending_record();
- test_read_beyond_pending_record();
- test_detached_while_reading();
- test_fill_log_no_fragmentation();
- test_fill_circular_log_no_fragmentation();
- test_fill_log_with_straddling_records();
- test_fill_circular_log_with_straddling_records();
- test_small_log();
- test_multiple_writers();
- test_multiple_writers_circular_log();
- test_performance();
- return 0;
-}
diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c
deleted file mode 100644
index 48fc43e..0000000
--- a/test/core/census/resource_test.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/ext/census/resource.h"
-#include <grpc/census.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/useful.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "src/core/ext/census/base_resources.h"
-#include "test/core/util/test_config.h"
-
-// Test all the functionality for dealing with Resources.
-
-// Just startup and shutdown resources subsystem.
-static void test_enable_disable() {
- initialize_resources();
- shutdown_resources();
-}
-
-// A blank/empty initialization should not work.
-static void test_empty_definition() {
- initialize_resources();
- int32_t rid = census_define_resource(NULL, 0);
- GPR_ASSERT(rid == -1);
- uint8_t buffer[50] = {0};
- rid = census_define_resource(buffer, 50);
- GPR_ASSERT(rid == -1);
- shutdown_resources();
-}
-
-// Given a file name, read raw proto and define the resource included within.
-// Returns resource id from census_define_resource().
-static int32_t define_resource_from_file(const char *file) {
-#define BUF_SIZE 512
- uint8_t buffer[BUF_SIZE];
- FILE *input = fopen(file, "rb");
- GPR_ASSERT(input != NULL);
- size_t nbytes = fread(buffer, 1, BUF_SIZE, input);
- GPR_ASSERT(nbytes != 0 && nbytes < BUF_SIZE && feof(input) && !ferror(input));
- int32_t rid = census_define_resource(buffer, nbytes);
- GPR_ASSERT(fclose(input) == 0);
- return rid;
-}
-
-// Test definition of a single resource, using a proto read from a file. The
-// `succeed` parameter indicates whether we expect the definition to succeed or
-// fail. `name` is used to check that the returned resource can be looked up by
-// name.
-static void test_define_single_resource(const char *file, const char *name,
- bool succeed) {
- gpr_log(GPR_INFO, "Test defining resource \"%s\"\n", name);
- initialize_resources();
- int32_t rid = define_resource_from_file(file);
- if (succeed) {
- GPR_ASSERT(rid >= 0);
- int32_t rid2 = census_resource_id(name);
- GPR_ASSERT(rid == rid2);
- } else {
- GPR_ASSERT(rid < 0);
- }
- shutdown_resources();
-}
-
-// Try deleting various resources (both those that exist and those that don't).
-static void test_delete_resource(const char *minimal_good, const char *full) {
- initialize_resources();
- // Try deleting resource before any are defined.
- census_delete_resource(0);
- // Create and check a couple of resources.
- int32_t rid1 = define_resource_from_file(minimal_good);
- int32_t rid2 = define_resource_from_file(full);
- GPR_ASSERT(rid1 >= 0 && rid2 >= 0 && rid1 != rid2);
- int32_t rid3 = census_resource_id("minimal_good");
- int32_t rid4 = census_resource_id("full_resource");
- GPR_ASSERT(rid1 == rid3 && rid2 == rid4);
- // Try deleting non-existant resources.
- census_delete_resource(-1);
- census_delete_resource(rid1 + rid2 + 1);
- census_delete_resource(10000000);
- // Delete one of the previously defined resources and check for deletion.
- census_delete_resource(rid1);
- rid3 = census_resource_id("minimal_good");
- GPR_ASSERT(rid3 < 0);
- // Check that re-adding works.
- rid1 = define_resource_from_file(minimal_good);
- GPR_ASSERT(rid1 >= 0);
- rid3 = census_resource_id("minimal_good");
- GPR_ASSERT(rid1 == rid3);
- shutdown_resources();
-}
-
-// Test define base resources.
-static void test_base_resources() {
- initialize_resources();
- define_base_resources();
- int32_t rid1 = census_resource_id("client_rpc_latency");
- int32_t rid2 = census_resource_id("server_rpc_latency");
- GPR_ASSERT(rid1 >= 0 && rid2 >= 0 && rid1 != rid2);
- shutdown_resources();
-}
-
-int main(int argc, char **argv) {
- const char *resource_empty_name_pb, *resource_full_pb,
- *resource_minimal_good_pb, *resource_no_name_pb,
- *resource_no_numerator_pb, *resource_no_unit_pb;
- if (argc == 7) {
- resource_empty_name_pb = argv[1];
- resource_full_pb = argv[2];
- resource_minimal_good_pb = argv[3];
- resource_no_name_pb = argv[4];
- resource_no_numerator_pb = argv[5];
- resource_no_unit_pb = argv[6];
- } else {
- GPR_ASSERT(argc == 1);
- resource_empty_name_pb = "test/core/census/data/resource_empty_name.pb";
- resource_full_pb = "test/core/census/data/resource_full.pb";
- resource_minimal_good_pb = "test/core/census/data/resource_minimal_good.pb";
- resource_no_name_pb = "test/core/census/data/resource_no_name.pb";
- resource_no_numerator_pb = "test/core/census/data/resource_no_numerator.pb";
- resource_no_unit_pb = "test/core/census/data/resource_no_unit.pb";
- }
- grpc_test_init(argc, argv);
- test_enable_disable();
- test_empty_definition();
- test_define_single_resource(resource_minimal_good_pb, "minimal_good", true);
- test_define_single_resource(resource_full_pb, "full_resource", true);
- test_define_single_resource(resource_no_name_pb, "resource_no_name", false);
- test_define_single_resource(resource_no_numerator_pb, "resource_no_numerator",
- false);
- test_define_single_resource(resource_no_unit_pb, "resource_no_unit", false);
- test_define_single_resource(resource_empty_name_pb, "resource_empty_name",
- false);
- test_delete_resource(resource_minimal_good_pb, resource_full_pb);
- test_base_resources();
- return 0;
-}
diff --git a/test/core/census/trace_context_test.c b/test/core/census/trace_context_test.c
deleted file mode 100644
index 6eb831a..0000000
--- a/test/core/census/trace_context_test.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/census.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/useful.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "src/core/ext/census/base_resources.h"
-#include "src/core/ext/census/resource.h"
-#include "test/core/util/test_config.h"
-
-#include "src/core/ext/census/gen/trace_context.pb.h"
-#include "src/core/ext/census/trace_context.h"
-#include "third_party/nanopb/pb_decode.h"
-#include "third_party/nanopb/pb_encode.h"
-
-#define BUF_SIZE 256
-
-/* Encodes a TraceContext structure (ctxt1) to a buffer, and then decodes it
-to a second TraceContext (ctxt2). Validates that the resulting TraceContext
-has a span_id, trace_id, and that the values are equal to those in initial
-TraceContext. On success, returns true. If encode_trace_context returns 0,
-decode_trace_context fails, or the resulting TraceContext is missing a trace_id
-or span_id, it will return false. */
-bool validate_encode_decode_context(google_trace_TraceContext *ctxt1,
- uint8_t *buffer, size_t buf_size) {
- google_trace_TraceContext ctxt2 = google_trace_TraceContext_init_zero;
- size_t msg_length;
-
- msg_length = encode_trace_context(ctxt1, buffer, buf_size);
- if (msg_length == 0) {
- return false;
- }
-
- if (!decode_trace_context(&ctxt2, buffer, msg_length)) {
- return false;
- }
-
- if (!ctxt2.has_trace_id_hi || !ctxt2.has_trace_id_lo || !ctxt2.has_span_id) {
- return false;
- }
-
- GPR_ASSERT(ctxt1->trace_id_hi == ctxt2.trace_id_hi &&
- ctxt1->trace_id_lo == ctxt2.trace_id_lo &&
- ctxt1->span_id == ctxt2.span_id &&
- ctxt1->has_span_options == ctxt2.has_span_options &&
- (ctxt1->has_span_options
- ? ctxt1->span_options == ctxt2.span_options
- : true));
-
- return true;
-}
-
-/* Decodes a proto-encoded TraceContext from a buffer. If decode_trace_context
-fails or the resulting TraceContext is missing a trace_id or span_id it will
-return false, otherwise returns true. */
-bool validate_decode_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
- size_t msg_length) {
- // Validate the decoding of a context written to buffer.
- if (!decode_trace_context(ctxt, buffer, msg_length)) {
- return false;
- }
-
- if (!ctxt->has_trace_id_hi || !ctxt->has_trace_id_lo || !ctxt->has_span_id) {
- return false;
- }
-
- return true;
-}
-
-/* Read an encoded trace context from a file. Validates that the decoding
-gives the expected result (succeed). */
-static void read_and_validate_context_from_file(google_trace_TraceContext *ctxt,
- const char *file,
- const bool succeed) {
- uint8_t buffer[BUF_SIZE];
- FILE *input = fopen(file, "rb");
- GPR_ASSERT(input != NULL);
- size_t nbytes = fread(buffer, 1, BUF_SIZE, input);
- GPR_ASSERT(nbytes <= BUF_SIZE && feof(input) && !ferror(input));
- bool res = validate_decode_context(ctxt, buffer, nbytes);
- GPR_ASSERT(res == succeed);
- GPR_ASSERT(fclose(input) == 0);
-}
-
-// Test full proto-buffer.
-static void test_full() {
- google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero;
- read_and_validate_context_from_file(
- &ctxt, "test/core/census/data/context_full.pb", true);
-}
-
-// Test empty proto-buffer.
-static void test_empty() {
- google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero;
- read_and_validate_context_from_file(
- &ctxt, "test/core/census/data/context_empty.pb", false);
-}
-
-// Test proto-buffer with only trace_id.
-static void test_trace_only() {
- google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero;
- read_and_validate_context_from_file(
- &ctxt, "test/core/census/data/context_trace_only.pb", false);
-}
-
-// Test proto-buffer with only span_id.
-static void test_span_only() {
- google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero;
- read_and_validate_context_from_file(
- &ctxt, "test/core/census/data/context_span_only.pb", false);
-}
-
-// Test proto-buffer without span_options value.
-static void test_no_span_options() {
- google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero;
- read_and_validate_context_from_file(
- &ctxt, "test/core/census/data/context_no_span_options.pb", true);
- GPR_ASSERT(ctxt.has_span_options == false && ctxt.span_options == 0);
-}
-
-static void test_encode_decode() {
- uint8_t buffer[BUF_SIZE] = {0};
-
- google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero;
- ctxt1.has_trace_id_hi = true;
- ctxt1.has_trace_id_lo = true;
- ctxt1.trace_id_lo = 1;
- ctxt1.trace_id_hi = 2;
- ctxt1.has_span_id = true;
- ctxt1.span_id = 3;
- validate_encode_decode_context(&ctxt1, buffer, sizeof(buffer));
-
- // Missing trace_id. This should fail.
- google_trace_TraceContext ctxt2 = google_trace_TraceContext_init_zero;
- ctxt2.has_trace_id_hi = false;
- ctxt2.has_trace_id_lo = false;
- ctxt2.has_span_id = true;
- validate_encode_decode_context(&ctxt2, buffer, sizeof(buffer));
-}
-
-// Test a corrupted proto-buffer. This should fail.
-static void test_corrupt() {
- uint8_t buffer[BUF_SIZE] = {0};
- google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero;
- size_t msg_length;
-
- ctxt1.has_trace_id_hi = true;
- ctxt1.has_trace_id_lo = true;
- ctxt1.trace_id_lo = 1;
- ctxt1.trace_id_hi = 2;
- ctxt1.has_span_id = true;
- ctxt1.span_id = 3;
- ctxt1.has_span_options = true;
- ctxt1.span_options = SPAN_OPTIONS_IS_SAMPLED;
- msg_length = encode_trace_context(&ctxt1, buffer, sizeof(buffer));
-
- /* Corrupt some bytes. 255 (0xFF) should be illegal for the first byte of the
- proto encoded object. */
- buffer[0] = 255;
-
- bool res = validate_decode_context(&ctxt1, buffer, msg_length);
- GPR_ASSERT(res == false);
-}
-
-static void test_buffer_size() {
- // This buffer is too small. This should fail.
- uint8_t buffer[16] = {0};
- google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero;
- size_t msg_length;
-
- ctxt1.has_trace_id_hi = true;
- ctxt1.has_trace_id_lo = true;
- ctxt1.trace_id_lo = 1;
- ctxt1.trace_id_hi = 2;
- ctxt1.has_span_id = true;
- ctxt1.span_id = 3;
- ctxt1.has_span_options = true;
- ctxt1.span_options = SPAN_OPTIONS_IS_SAMPLED;
- msg_length = encode_trace_context(&ctxt1, buffer, sizeof(buffer));
-
- GPR_ASSERT(msg_length == 0);
-}
-
-int main(int argc, char **argv) {
- grpc_test_init(argc, argv);
- test_full();
- test_empty();
- test_trace_only();
- test_span_only();
- test_encode_decode();
- test_corrupt();
- test_no_span_options();
- test_buffer_size();
-
- return 0;
-}
diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index ba37cd6..0e47d8f 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -53,8 +53,8 @@
size_t n; /* number of iterations */
int *connections; /* indexed by the interation number, value is the index of
the server it connected to or -1 if none */
- int *connectivity_states; /* indexed by the interation number, value is the
- client connectivity state */
+ /* indexed by the interation number, value is the client connectivity state */
+ grpc_connectivity_state *connectivity_states;
} request_sequences;
typedef void (*verifier_fn)(const servers_fixture *, grpc_channel *,
diff --git a/test/core/transport/status_conversion_test.c b/test/core/transport/status_conversion_test.c
index de8fa44..02dad86 100644
--- a/test/core/transport/status_conversion_test.c
+++ b/test/core/transport/status_conversion_test.c
@@ -38,6 +38,7 @@
int i;
grpc_test_init(argc, argv);
+ grpc_init();
GRPC_STATUS_TO_HTTP2_ERROR(GRPC_STATUS_OK, GRPC_HTTP2_NO_ERROR);
GRPC_STATUS_TO_HTTP2_ERROR(GRPC_STATUS_CANCELLED, GRPC_HTTP2_CANCEL);
@@ -129,6 +130,11 @@
GRPC_STATUS_INTERNAL);
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_REFUSED_STREAM, after_deadline,
GRPC_STATUS_UNAVAILABLE);
+ // We only have millisecond granularity in our timing code. This sleeps for 5
+ // millis to ensure that the status conversion code will pick up the fact
+ // that the deadline has expired.
+ gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_millis(5, GPR_TIMESPAN)));
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_CANCEL, after_deadline,
GRPC_STATUS_DEADLINE_EXCEEDED);
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_COMPRESSION_ERROR, after_deadline,
@@ -158,5 +164,7 @@
grpc_http2_status_to_grpc_status(i);
}
+ grpc_shutdown();
+
return 0;
}
diff --git a/test/core/tsi/transport_security_test_lib.c b/test/core/tsi/transport_security_test_lib.c
index 329b237..1f32eab 100644
--- a/test/core/tsi/transport_security_test_lib.c
+++ b/test/core/tsi/transport_security_test_lib.c
@@ -350,25 +350,28 @@
tsi_handshaker_result *handshaker_result = NULL;
unsigned char *bytes_to_send = NULL;
size_t bytes_to_send_size = 0;
+ tsi_result result = TSI_OK;
/* Receive data from peer, if available. */
- size_t buf_size = args->handshake_buffer_size;
- receive_bytes_from_peer(args->fixture, &args->handshake_buffer, &buf_size,
- args->is_client);
- if (buf_size > 0) {
- args->transferred_data = true;
- }
- /* Peform handshaker next. */
- tsi_result result = tsi_handshaker_next(
- handshaker, args->handshake_buffer, buf_size,
- (const unsigned char **)&bytes_to_send, &bytes_to_send_size,
- &handshaker_result, &on_handshake_next_done_wrapper, args);
- if (result != TSI_ASYNC) {
- args->error = on_handshake_next_done(result, args, bytes_to_send,
- bytes_to_send_size, handshaker_result);
- if (args->error != GRPC_ERROR_NONE) {
- return;
+ do {
+ size_t buf_size = args->handshake_buffer_size;
+ receive_bytes_from_peer(args->fixture, &args->handshake_buffer, &buf_size,
+ args->is_client);
+ if (buf_size > 0) {
+ args->transferred_data = true;
}
- }
+ /* Peform handshaker next. */
+ result = tsi_handshaker_next(handshaker, args->handshake_buffer, buf_size,
+ (const unsigned char **)&bytes_to_send,
+ &bytes_to_send_size, &handshaker_result,
+ &on_handshake_next_done_wrapper, args);
+ if (result != TSI_ASYNC) {
+ args->error = on_handshake_next_done(
+ result, args, bytes_to_send, bytes_to_send_size, handshaker_result);
+ if (args->error != GRPC_ERROR_NONE) {
+ return;
+ }
+ }
+ } while (result == TSI_INCOMPLETE_DATA);
notification_wait(fixture);
}
diff --git a/test/core/tsi/transport_security_test_lib.h b/test/core/tsi/transport_security_test_lib.h
index ed8ff85..74f4378 100644
--- a/test/core/tsi/transport_security_test_lib.h
+++ b/test/core/tsi/transport_security_test_lib.h
@@ -21,6 +21,8 @@
#include "src/core/tsi/transport_security_interface.h"
+#include <grpc/support/sync.h>
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index 1bf2888..ed39255 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -82,7 +82,7 @@
half *m = other_half((half *)ep);
gpr_mu_lock(&m->parent->mu);
grpc_error *error = GRPC_ERROR_NONE;
- m->parent->stats->num_writes++;
+ gpr_atm_no_barrier_fetch_add(&m->parent->stats->num_writes, (gpr_atm)1);
if (m->parent->shutdown) {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Endpoint already shutdown");
} else if (m->on_read != NULL) {
diff --git a/test/core/util/passthru_endpoint.h b/test/core/util/passthru_endpoint.h
index da76902..23d21c6 100644
--- a/test/core/util/passthru_endpoint.h
+++ b/test/core/util/passthru_endpoint.h
@@ -19,9 +19,11 @@
#ifndef MOCK_ENDPOINT_H
#define MOCK_ENDPOINT_H
+#include <grpc/support/atm.h>
+
#include "src/core/lib/iomgr/endpoint.h"
-typedef struct { int num_writes; } grpc_passthru_endpoint_stats;
+typedef struct { gpr_atm num_writes; } grpc_passthru_endpoint_stats;
void grpc_passthru_endpoint_create(grpc_endpoint **client,
grpc_endpoint **server,
diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden
index 3d664e8..026a941 100644
--- a/test/cpp/codegen/compiler_test_golden
+++ b/test/cpp/codegen/compiler_test_golden
@@ -39,7 +39,6 @@
namespace grpc {
class CompletionQueue;
class Channel;
-class RpcService;
class ServerCompletionQueue;
class ServerContext;
} // namespace grpc
@@ -169,10 +168,10 @@
::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) override;
::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override;
::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) override;
- const ::grpc::RpcMethod rpcmethod_MethodA1_;
- const ::grpc::RpcMethod rpcmethod_MethodA2_;
- const ::grpc::RpcMethod rpcmethod_MethodA3_;
- const ::grpc::RpcMethod rpcmethod_MethodA4_;
+ const ::grpc::internal::RpcMethod rpcmethod_MethodA1_;
+ const ::grpc::internal::RpcMethod rpcmethod_MethodA2_;
+ const ::grpc::internal::RpcMethod rpcmethod_MethodA3_;
+ const ::grpc::internal::RpcMethod rpcmethod_MethodA4_;
};
static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
@@ -352,7 +351,7 @@
public:
WithStreamedUnaryMethod_MethodA1() {
::grpc::Service::MarkMethodStreamed(0,
- new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1<BaseClass>::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2)));
+ new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1<BaseClass>::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2)));
}
~WithStreamedUnaryMethod_MethodA1() override {
BaseClassMustBeDerivedFromService(this);
@@ -373,7 +372,7 @@
public:
WithSplitStreamingMethod_MethodA3() {
::grpc::Service::MarkMethodStreamed(2,
- new ::grpc::SplitServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithSplitStreamingMethod_MethodA3<BaseClass>::StreamedMethodA3, this, std::placeholders::_1, std::placeholders::_2)));
+ new ::grpc::internal::SplitServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithSplitStreamingMethod_MethodA3<BaseClass>::StreamedMethodA3, this, std::placeholders::_1, std::placeholders::_2)));
}
~WithSplitStreamingMethod_MethodA3() override {
BaseClassMustBeDerivedFromService(this);
@@ -427,7 +426,7 @@
std::shared_ptr< ::grpc::ChannelInterface> channel_;
::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
- const ::grpc::RpcMethod rpcmethod_MethodB1_;
+ const ::grpc::internal::RpcMethod rpcmethod_MethodB1_;
};
static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
@@ -484,7 +483,7 @@
public:
WithStreamedUnaryMethod_MethodB1() {
::grpc::Service::MarkMethodStreamed(0,
- new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1<BaseClass>::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2)));
+ new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1<BaseClass>::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2)));
}
~WithStreamedUnaryMethod_MethodB1() override {
BaseClassMustBeDerivedFromService(this);
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index b7634d0..cf1cc7e 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -28,12 +28,14 @@
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <grpc/support/tls.h>
#include "src/core/lib/iomgr/port.h"
+#include "src/core/lib/support/env.h"
#include "src/proto/grpc/health/v1/health.grpc.pb.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
@@ -459,6 +461,14 @@
if (GetParam().inproc) {
return;
}
+ int poller_slowdown_factor = 1;
+ // It needs 2 pollset_works to reconnect the channel with polling engine
+ // "poll"
+ char* s = gpr_getenv("GRPC_POLL_STRATEGY");
+ if (s != NULL && 0 == strcmp(s, "poll")) {
+ poller_slowdown_factor = 2;
+ }
+ gpr_free(s);
ResetStub();
SendRpc(1);
server_->Shutdown();
@@ -468,10 +478,13 @@
while (cq_->Next(&ignored_tag, &ignored_ok))
;
BuildAndStartServer();
- // It needs more than kConnectivityCheckIntervalMsec time to reconnect the
- // channel.
- gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_millis(1600, GPR_TIMESPAN)));
+ // It needs more than GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS time to
+ // reconnect the channel.
+ gpr_sleep_until(gpr_time_add(
+ gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_millis(
+ 300 * poller_slowdown_factor * grpc_test_slowdown_factor(),
+ GPR_TIMESPAN)));
SendRpc(1);
}
@@ -1999,6 +2012,9 @@
} // namespace grpc
int main(int argc, char** argv) {
+ // Change the backup poll interval from 5s to 200ms to speed up the
+ // ReconnectChannel test
+ gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200");
grpc_test_init(argc, argv);
gpr_tls_init(&g_is_async_end2end_test);
::testing::InitGoogleTest(&argc, argv);
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index c236f76..fc87bad 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -36,6 +36,7 @@
extern "C" {
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
+#include "src/core/lib/support/env.h"
}
#include "src/proto/grpc/testing/echo.grpc.pb.h"
@@ -86,7 +87,11 @@
class ClientLbEnd2endTest : public ::testing::Test {
protected:
ClientLbEnd2endTest()
- : server_host_("localhost"), kRequestMessage_("Live long and prosper.") {}
+ : server_host_("localhost"), kRequestMessage_("Live long and prosper.") {
+ // Make the backup poller poll very frequently in order to pick up
+ // updates from all the subchannels's FDs.
+ gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1");
+ }
void SetUp() override {
response_generator_ = grpc_fake_resolver_response_generator_create();
@@ -305,7 +310,7 @@
ports.clear();
SetNextResolution(ports);
gpr_log(GPR_INFO, "****** SET none *******");
- grpc_connectivity_state channel_state = GRPC_CHANNEL_INIT;
+ grpc_connectivity_state channel_state;
do {
channel_state = channel_->GetState(true /* try to connect */);
} while (channel_state == GRPC_CHANNEL_READY);
@@ -481,7 +486,7 @@
// An empty update will result in the channel going into TRANSIENT_FAILURE.
ports.clear();
SetNextResolution(ports);
- grpc_connectivity_state channel_state = GRPC_CHANNEL_INIT;
+ grpc_connectivity_state channel_state;
do {
channel_state = channel_->GetState(true /* try to connect */);
} while (channel_state == GRPC_CHANNEL_READY);
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 1aa547d..82ca394 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -30,11 +30,13 @@
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/lib/security/credentials/credentials.h"
+#include "src/core/lib/support/env.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
@@ -704,13 +706,25 @@
if (GetParam().inproc) {
return;
}
+ gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200");
+ int poller_slowdown_factor = 1;
+ // It needs 2 pollset_works to reconnect the channel with polling engine
+ // "poll"
+ char* s = gpr_getenv("GRPC_POLL_STRATEGY");
+ if (s != NULL && 0 == strcmp(s, "poll")) {
+ poller_slowdown_factor = 2;
+ }
+ gpr_free(s);
ResetStub();
SendRpc(stub_.get(), 1, false);
RestartServer(std::shared_ptr<AuthMetadataProcessor>());
- // It needs more than kConnectivityCheckIntervalMsec time to reconnect the
- // channel.
- gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_millis(1600, GPR_TIMESPAN)));
+ // It needs more than GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS time to
+ // reconnect the channel.
+ gpr_sleep_until(gpr_time_add(
+ gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_millis(
+ 300 * poller_slowdown_factor * grpc_test_slowdown_factor(),
+ GPR_TIMESPAN)));
SendRpc(stub_.get(), 1, false);
}
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index c370302..b9ee77d 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -36,6 +36,7 @@
extern "C" {
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/support/env.h"
}
#include "test/core/util/port.h"
@@ -74,9 +75,9 @@
using std::chrono::system_clock;
+using grpc::lb::v1::LoadBalancer;
using grpc::lb::v1::LoadBalanceRequest;
using grpc::lb::v1::LoadBalanceResponse;
-using grpc::lb::v1::LoadBalancer;
namespace grpc {
namespace testing {
@@ -332,7 +333,11 @@
num_backends_(num_backends),
num_balancers_(num_balancers),
client_load_reporting_interval_seconds_(
- client_load_reporting_interval_seconds) {}
+ client_load_reporting_interval_seconds) {
+ // Make the backup poller poll very frequently in order to pick up
+ // updates from all the subchannels's FDs.
+ gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1");
+ }
void SetUp() override {
response_generator_ = grpc_fake_resolver_response_generator_create();
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
index f990a7e..90b2edd 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -50,23 +50,6 @@
namespace grpc {
namespace testing {
-namespace {
-
-// When echo_deadline is requested, deadline seen in the ServerContext is set in
-// the response in seconds.
-void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
- EchoResponse* response) {
- if (request->has_param() && request->param().echo_deadline()) {
- gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
- if (context->deadline() != system_clock::time_point::max()) {
- Timepoint2Timespec(context->deadline(), &deadline);
- }
- response->mutable_param()->set_request_deadline(deadline.tv_sec);
- }
-}
-
-} // namespace
-
class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
public:
TestServiceImpl() : signal_client_(false) {}
@@ -74,29 +57,6 @@
Status Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) override {
response->set_message(request->message());
- MaybeEchoDeadline(context, request, response);
- if (request->has_param() && request->param().client_cancel_after_us()) {
- {
- std::unique_lock<std::mutex> lock(mu_);
- signal_client_ = true;
- }
- while (!context->IsCancelled()) {
- gpr_sleep_until(gpr_time_add(
- gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(request->param().client_cancel_after_us(),
- GPR_TIMESPAN)));
- }
- return Status::CANCELLED;
- } else if (request->has_param() &&
- request->param().server_cancel_after_us()) {
- gpr_sleep_until(gpr_time_add(
- gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(request->param().server_cancel_after_us(),
- GPR_TIMESPAN)));
- return Status::CANCELLED;
- } else {
- EXPECT_FALSE(context->IsCancelled());
- }
return Status::OK;
}
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
index e740ea5..522bc9e 100644
--- a/test/cpp/grpclb/grpclb_test.cc
+++ b/test/cpp/grpclb/grpclb_test.cc
@@ -42,6 +42,7 @@
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/support/tmpfile.h"
#include "src/core/lib/surface/channel.h"
@@ -790,6 +791,9 @@
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
grpc_test_init(argc, argv);
+ // Make the backup poller poll very frequently in order to pick up
+ // updates from all the subchannels's FDs.
+ gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1");
grpc_init();
const auto result = RUN_ALL_TESTS();
grpc_shutdown();
diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc
index a0c0414..020ec04 100644
--- a/test/cpp/microbenchmarks/bm_cq.cc
+++ b/test/cpp/microbenchmarks/bm_cq.cc
@@ -70,7 +70,7 @@
static void DoneWithCompletionOnStack(grpc_exec_ctx* exec_ctx, void* arg,
grpc_cq_completion* completion) {}
-class DummyTag final : public CompletionQueueTag {
+class DummyTag final : public internal::CompletionQueueTag {
public:
bool FinalizeResult(void** tag, bool* status) override { return true; }
};
diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
index 389b8c9..25d243a 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
@@ -21,6 +21,7 @@
#include <benchmark/benchmark.h>
#include <gflags/gflags.h>
#include <fstream>
+
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include "src/core/lib/iomgr/timer_manager.h"
@@ -142,17 +143,17 @@
client->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != nullptr,
server->lists[GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT].head != nullptr,
server->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != nullptr,
- client->flow_control->remote_window(),
- server->flow_control->remote_window(),
- client->flow_control->announced_window(),
- server->flow_control->announced_window(),
- client_stream ? client_stream->flow_control->remote_window_delta() : -1,
- server_stream ? server_stream->flow_control->remote_window_delta() : -1,
- client_stream ? client_stream->flow_control->local_window_delta() : -1,
- server_stream ? server_stream->flow_control->local_window_delta() : -1,
- client_stream ? client_stream->flow_control->announced_window_delta()
+ client->flow_control->remote_window_,
+ server->flow_control->remote_window_,
+ client->flow_control->announced_window_,
+ server->flow_control->announced_window_,
+ client_stream ? client_stream->flow_control->remote_window_delta_ : -1,
+ server_stream ? server_stream->flow_control->remote_window_delta_ : -1,
+ client_stream ? client_stream->flow_control->local_window_delta_ : -1,
+ server_stream ? server_stream->flow_control->local_window_delta_ : -1,
+ client_stream ? client_stream->flow_control->announced_window_delta_
: -1,
- server_stream ? server_stream->flow_control->announced_window_delta()
+ server_stream ? server_stream->flow_control->announced_window_delta_
: -1,
client->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h
index a7f8504..9d345a9 100644
--- a/test/cpp/microbenchmarks/fullstack_fixtures.h
+++ b/test/cpp/microbenchmarks/fullstack_fixtures.h
@@ -25,6 +25,7 @@
#include <grpc++/security/server_credentials.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
+#include <grpc/support/atm.h>
#include <grpc/support/log.h>
extern "C" {
@@ -259,7 +260,8 @@
void AddToLabel(std::ostream& out, benchmark::State& state) {
EndpointPairFixture::AddToLabel(out, state);
out << " writes/iter:"
- << (double)stats_.num_writes / (double)state.iterations();
+ << static_cast<double>(gpr_atm_no_barrier_load(&stats_.num_writes)) /
+ static_cast<double>(state.iterations());
}
private:
diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc
index 6802a0a..782f12e 100644
--- a/test/cpp/microbenchmarks/helpers.cc
+++ b/test/cpp/microbenchmarks/helpers.cc
@@ -16,6 +16,8 @@
*
*/
+#include <string.h>
+
#include "test/cpp/microbenchmarks/helpers.h"
void TrackCounters::Finish(benchmark::State &state) {
@@ -45,10 +47,14 @@
<< "/iter:" << ((double)stats.counters[i] / (double)state.iterations());
}
for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
- out << " " << grpc_stats_histogram_name[i] << "-median:"
- << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 50.0)
- << " " << grpc_stats_histogram_name[i] << "-99p:"
- << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 99.0);
+ std::ostringstream median_ss;
+ median_ss << grpc_stats_histogram_name[i] << "-median";
+ state.counters[median_ss.str()] = benchmark::Counter(
+ grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 50.0));
+ std::ostringstream tail_ss;
+ tail_ss << grpc_stats_histogram_name[i] << "-99p";
+ state.counters[tail_ss.str()] = benchmark::Counter(
+ grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 99.0));
}
#ifdef GPR_LOW_LEVEL_COUNTERS
grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot();
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index b5c7208..a541f94 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -245,9 +245,20 @@
if (!cli_cqs_[cq_[thread_idx]]->Next(&got_tag, &ok)) {
return;
}
- ClientRpcContext* ctx;
+ ClientRpcContext* ctx = ClientRpcContext::detag(got_tag);
std::mutex* shutdown_mu = &shutdown_state_[thread_idx]->mutex;
- do {
+ shutdown_mu->lock();
+ while (cli_cqs_[cq_[thread_idx]]->DoThenAsyncNext(
+ [&, ctx, ok, entry_ptr, shutdown_mu]() {
+ if (!ctx->RunNextState(ok, entry_ptr)) {
+ // The RPC and callback are done, so clone the ctx
+ // and kickstart the new one
+ ctx->StartNewClone(cli_cqs_[cq_[thread_idx]].get());
+ delete ctx;
+ }
+ shutdown_mu->unlock();
+ },
+ &got_tag, &ok, gpr_inf_future(GPR_CLOCK_REALTIME))) {
t->UpdateHistogram(entry_ptr);
// Got a regular event, so process it
ctx = ClientRpcContext::detag(got_tag);
@@ -265,18 +276,7 @@
shutdown_mu->unlock();
return;
}
- } while (cli_cqs_[cq_[thread_idx]]->DoThenAsyncNext(
- [&, ctx, ok, entry_ptr, shutdown_mu]() {
- bool next_ok = ok;
- if (!ctx->RunNextState(next_ok, entry_ptr)) {
- // The RPC and callback are done, so clone the ctx
- // and kickstart the new one
- ctx->StartNewClone(cli_cqs_[cq_[thread_idx]].get());
- delete ctx;
- }
- shutdown_mu->unlock();
- },
- &got_tag, &ok, gpr_inf_future(GPR_CLOCK_REALTIME)));
+ }
}
std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 4576be5..1c1a563 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -70,7 +70,7 @@
ServerAsyncReaderWriter<ResponseType, RequestType> *,
CompletionQueue *, ServerCompletionQueue *, void *)>
request_streaming_both_ways_function,
- std::function<grpc::Status(const PayloadConfig &, const RequestType *,
+ std::function<grpc::Status(const PayloadConfig &, RequestType *,
ResponseType *)>
process_rpc)
: Server(config) {
@@ -206,13 +206,12 @@
return;
}
ServerRpcContext *ctx;
- std::mutex *mu_ptr;
+ std::mutex *mu_ptr = &shutdown_state_[thread_idx]->mutex;
do {
ctx = detag(got_tag);
// The tag is a pointer to an RPC context to invoke
// Proceed while holding a lock to make sure that
// this thread isn't supposed to shut down
- mu_ptr = &shutdown_state_[thread_idx]->mutex;
mu_ptr->lock();
if (shutdown_state_[thread_idx]->shutdown) {
mu_ptr->unlock();
@@ -255,7 +254,7 @@
grpc::ServerAsyncResponseWriter<ResponseType> *,
void *)>
request_method,
- std::function<grpc::Status(const RequestType *, ResponseType *)>
+ std::function<grpc::Status(RequestType *, ResponseType *)>
invoke_method)
: srv_ctx_(new ServerContextType),
next_state_(&ServerRpcContextUnaryImpl::invoker),
@@ -301,8 +300,7 @@
std::function<void(ServerContextType *, RequestType *,
grpc::ServerAsyncResponseWriter<ResponseType> *, void *)>
request_method_;
- std::function<grpc::Status(const RequestType *, ResponseType *)>
- invoke_method_;
+ std::function<grpc::Status(RequestType *, ResponseType *)> invoke_method_;
grpc::ServerAsyncResponseWriter<ResponseType> response_writer_;
};
@@ -313,7 +311,7 @@
ServerContextType *,
grpc::ServerAsyncReaderWriter<ResponseType, RequestType> *, void *)>
request_method,
- std::function<grpc::Status(const RequestType *, ResponseType *)>
+ std::function<grpc::Status(RequestType *, ResponseType *)>
invoke_method)
: srv_ctx_(new ServerContextType),
next_state_(&ServerRpcContextStreamingImpl::request_done),
@@ -381,8 +379,7 @@
ServerContextType *,
grpc::ServerAsyncReaderWriter<ResponseType, RequestType> *, void *)>
request_method_;
- std::function<grpc::Status(const RequestType *, ResponseType *)>
- invoke_method_;
+ std::function<grpc::Status(RequestType *, ResponseType *)> invoke_method_;
grpc::ServerAsyncReaderWriter<ResponseType, RequestType> stream_;
};
@@ -394,7 +391,7 @@
grpc::ServerAsyncReader<ResponseType, RequestType> *,
void *)>
request_method,
- std::function<grpc::Status(const RequestType *, ResponseType *)>
+ std::function<grpc::Status(RequestType *, ResponseType *)>
invoke_method)
: srv_ctx_(new ServerContextType),
next_state_(&ServerRpcContextStreamingFromClientImpl::request_done),
@@ -452,8 +449,7 @@
grpc::ServerAsyncReader<ResponseType, RequestType> *,
void *)>
request_method_;
- std::function<grpc::Status(const RequestType *, ResponseType *)>
- invoke_method_;
+ std::function<grpc::Status(RequestType *, ResponseType *)> invoke_method_;
grpc::ServerAsyncReader<ResponseType, RequestType> stream_;
};
@@ -464,7 +460,7 @@
std::function<void(ServerContextType *, RequestType *,
grpc::ServerAsyncWriter<ResponseType> *, void *)>
request_method,
- std::function<grpc::Status(const RequestType *, ResponseType *)>
+ std::function<grpc::Status(RequestType *, ResponseType *)>
invoke_method)
: srv_ctx_(new ServerContextType),
next_state_(&ServerRpcContextStreamingFromServerImpl::request_done),
@@ -521,8 +517,7 @@
std::function<void(ServerContextType *, RequestType *,
grpc::ServerAsyncWriter<ResponseType> *, void *)>
request_method_;
- std::function<grpc::Status(const RequestType *, ResponseType *)>
- invoke_method_;
+ std::function<grpc::Status(RequestType *, ResponseType *)> invoke_method_;
grpc::ServerAsyncWriter<ResponseType> stream_;
};
@@ -551,8 +546,7 @@
builder->RegisterAsyncGenericService(service);
}
-static Status ProcessSimpleRPC(const PayloadConfig &,
- const SimpleRequest *request,
+static Status ProcessSimpleRPC(const PayloadConfig &, SimpleRequest *request,
SimpleResponse *response) {
if (request->response_size() > 0) {
if (!Server::SetPayload(request->response_type(), request->response_size(),
@@ -560,12 +554,17 @@
return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
}
}
+ // We are done using the request. Clear it to reduce working memory.
+ // This proves to reduce cache misses in large message size cases.
+ request->Clear();
return Status::OK;
}
static Status ProcessGenericRPC(const PayloadConfig &payload_config,
- const ByteBuffer *request,
- ByteBuffer *response) {
+ ByteBuffer *request, ByteBuffer *response) {
+ // We are done using the request. Clear it to reduce working memory.
+ // This proves to reduce cache misses in large message size cases.
+ request->Clear();
int resp_size = payload_config.bytebuf_params().resp_size();
std::unique_ptr<char[]> buf(new char[resp_size]);
Slice slice(buf.get(), resp_size);
diff --git a/third_party/benchmark b/third_party/benchmark
index 44c25c8..5b7683f 160000
--- a/third_party/benchmark
+++ b/third_party/benchmark
@@ -1 +1 @@
-Subproject commit 44c25c892a6229b20db7cd9dc05584ea865896de
+Subproject commit 5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index e053642..b9844f8 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -871,42 +871,10 @@
include/grpc/support/workaround_list.h \
src/core/README.md \
src/core/ext/README.md \
-src/core/ext/census/README.md \
-src/core/ext/census/aggregation.h \
-src/core/ext/census/base_resources.cc \
-src/core/ext/census/base_resources.h \
-src/core/ext/census/census_interface.h \
-src/core/ext/census/census_rpc_stats.h \
-src/core/ext/census/context.cc \
-src/core/ext/census/gen/README.md \
-src/core/ext/census/gen/census.pb.c \
-src/core/ext/census/gen/census.pb.h \
-src/core/ext/census/gen/trace_context.pb.c \
-src/core/ext/census/gen/trace_context.pb.h \
src/core/ext/census/grpc_context.cc \
-src/core/ext/census/grpc_filter.cc \
-src/core/ext/census/grpc_filter.h \
-src/core/ext/census/grpc_plugin.cc \
-src/core/ext/census/initialize.cc \
-src/core/ext/census/intrusive_hash_map.cc \
-src/core/ext/census/intrusive_hash_map.h \
-src/core/ext/census/intrusive_hash_map_internal.h \
-src/core/ext/census/mlog.cc \
-src/core/ext/census/mlog.h \
-src/core/ext/census/operation.cc \
-src/core/ext/census/placeholders.cc \
-src/core/ext/census/resource.cc \
-src/core/ext/census/resource.h \
-src/core/ext/census/rpc_metric_id.h \
-src/core/ext/census/trace_context.cc \
-src/core/ext/census/trace_context.h \
-src/core/ext/census/trace_label.h \
-src/core/ext/census/trace_propagation.h \
-src/core/ext/census/trace_status.h \
-src/core/ext/census/trace_string.h \
-src/core/ext/census/tracing.cc \
-src/core/ext/census/tracing.h \
src/core/ext/filters/client_channel/README.md \
+src/core/ext/filters/client_channel/backup_poller.cc \
+src/core/ext/filters/client_channel/backup_poller.h \
src/core/ext/filters/client_channel/channel_connectivity.cc \
src/core/ext/filters/client_channel/client_channel.cc \
src/core/ext/filters/client_channel/client_channel.h \
@@ -935,6 +903,8 @@
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
+src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc \
+src/core/ext/filters/client_channel/lb_policy/subchannel_list.h \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_factory.h \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
diff --git a/tools/gce/create_windows_debug_worker.sh b/tools/gce/create_windows_debug_worker.sh
new file mode 100755
index 0000000..b56c8d9
--- /dev/null
+++ b/tools/gce/create_windows_debug_worker.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Creates a worker for debugging/experiments.
+# The worker will have all the prerequisites that are installed on kokoro
+# windows workers.
+
+set -ex
+
+cd $(dirname $0)
+
+CLOUD_PROJECT=grpc-testing
+ZONE=us-central1-b
+
+if [ "$1" != "" ]
+then
+ INSTANCE_NAME="$1"
+else
+ INSTANCE_NAME="${USER}-windows-kokoro-debug1"
+fi
+
+MACHINE_TYPE=n1-standard-8
+
+gcloud compute instances create $INSTANCE_NAME \
+ --project="$CLOUD_PROJECT" \
+ --zone "$ZONE" \
+ --machine-type $MACHINE_TYPE \
+ --image-project google.com:kokoro \
+ --image kokoro-win7build-v9-prod-debug \
+ --boot-disk-size 500 \
+ --boot-disk-type pd-ssd \
+ --tags=allow-ssh
diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_rc
index ea2a17f..8715d6c 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_linux_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_linux_rc
@@ -22,6 +22,9 @@
# Move docker's storage location to scratch disk so we don't run out of space.
echo 'DOCKER_OPTS="${DOCKER_OPTS} --graph=/tmpfs/docker"' | sudo tee --append /etc/default/docker
+# Use container registry mirror for pulling docker images (should make downloads faster)
+# See https://cloud.google.com/container-registry/docs/using-dockerhub-mirroring
+echo 'DOCKER_OPTS="${DOCKER_OPTS} --registry-mirror=https://mirror.gcr.io"' | sudo tee --append /etc/default/docker
sudo service docker restart
# Populate xdg-cache-home to workaround https://github.com/grpc/grpc/issues/11968
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
index bb046de..6ecf51d 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc
@@ -25,6 +25,7 @@
cd /Users/kbuilder/workspace/grpc
# Needed for identifying Docker image sha1
+brew update
brew install md5sha1sum
# Set up gRPC-Go and gRPC-Java to test
diff --git a/tools/internal_ci/linux/grpc_build_submodule_at_head.sh b/tools/internal_ci/linux/grpc_build_submodule_at_head.sh
index b67b030..e203a62 100755
--- a/tools/internal_ci/linux/grpc_build_submodule_at_head.sh
+++ b/tools/internal_ci/linux/grpc_build_submodule_at_head.sh
@@ -27,5 +27,5 @@
tools/buildgen/generate_projects.sh
git -c user.name='foo' -c user.email='foo@google.com' commit -a -m 'Update submodule'
-tools/run_tests/run_tests_matrix.py -f linux --internal_ci --build_only
+tools/run_tests/run_tests_matrix.py -f linux --inner_jobs 4 -j 4 --internal_ci --build_only
diff --git a/tools/internal_ci/linux/grpc_portability_build_only.cfg b/tools/internal_ci/linux/grpc_portability_build_only.cfg
index 501223c..4acd935 100644
--- a/tools/internal_ci/linux/grpc_portability_build_only.cfg
+++ b/tools/internal_ci/linux/grpc_portability_build_only.cfg
@@ -26,5 +26,5 @@
env_vars {
key: "RUN_TESTS_FLAGS"
- value: "-f portability linux --internal_ci --build_only"
+ value: "-f portability linux --inner_jobs 4 -j 4 --internal_ci --build_only"
}
diff --git a/tools/profiling/microbenchmarks/bm_diff/bm_constants.py b/tools/profiling/microbenchmarks/bm_diff/bm_constants.py
index f8989b1..0ec17fa 100644
--- a/tools/profiling/microbenchmarks/bm_diff/bm_constants.py
+++ b/tools/profiling/microbenchmarks/bm_diff/bm_constants.py
@@ -23,7 +23,7 @@
'bm_metadata', 'bm_fullstack_trickle'
]
-_INTERESTING = ('cpu_time', 'real_time', 'locks_per_iteration',
+_INTERESTING = ('cpu_time', 'real_time', 'call_initial_size-median', 'locks_per_iteration',
'allocs_per_iteration', 'writes_per_iteration',
'atm_cas_per_iteration', 'atm_add_per_iteration',
'nows_per_iteration', 'cli_transport_stalls_per_iteration',
diff --git a/tools/run_tests/dockerize/build_and_run_docker.sh b/tools/run_tests/dockerize/build_and_run_docker.sh
index 80aec82..323c2f7 100755
--- a/tools/run_tests/dockerize/build_and_run_docker.sh
+++ b/tools/run_tests/dockerize/build_and_run_docker.sh
@@ -36,13 +36,13 @@
# Pull the base image to force an update
if [ "$DOCKER_BASE_IMAGE" != "" ]
then
- docker pull $DOCKER_BASE_IMAGE
+ time docker pull $DOCKER_BASE_IMAGE
fi
if [ "$DOCKERHUB_ORGANIZATION" != "" ]
then
DOCKER_IMAGE_NAME=$DOCKERHUB_ORGANIZATION/$DOCKER_IMAGE_NAME
- docker pull $DOCKER_IMAGE_NAME
+ time docker pull $DOCKER_IMAGE_NAME
else
# Make sure docker image has been built. Should be instantaneous if so.
docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
index eea00da..06a5dae 100755
--- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh
+++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
@@ -40,7 +40,7 @@
if [ "$DOCKERHUB_ORGANIZATION" != "" ]
then
DOCKER_IMAGE_NAME=$DOCKERHUB_ORGANIZATION/$DOCKER_IMAGE_NAME
- docker pull $DOCKER_IMAGE_NAME
+ time docker pull $DOCKER_IMAGE_NAME
else
# Make sure docker image has been built. Should be instantaneous if so.
docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh
index 09e0629..dbc6bde 100755
--- a/tools/run_tests/dockerize/build_interop_image.sh
+++ b/tools/run_tests/dockerize/build_interop_image.sh
@@ -78,7 +78,7 @@
if [ "$DOCKERHUB_ORGANIZATION" != "" ]
then
BASE_IMAGE=$DOCKERHUB_ORGANIZATION/$BASE_IMAGE
- docker pull $BASE_IMAGE
+ time docker pull $BASE_IMAGE
else
# Make sure docker image has been built. Should be instantaneous if so.
docker build -t $BASE_IMAGE --force-rm=true tools/dockerfile/interoptest/$BASE_NAME || exit $?
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 46f4cb6..b74e49f 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -191,74 +191,6 @@
"headers": [],
"is_filegroup": false,
"language": "c",
- "name": "census_context_test",
- "src": [
- "test/core/census/context_test.c"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc_test_util"
- ],
- "headers": [],
- "is_filegroup": false,
- "language": "c",
- "name": "census_intrusive_hash_map_test",
- "src": [
- "test/core/census/intrusive_hash_map_test.c"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc_test_util"
- ],
- "headers": [],
- "is_filegroup": false,
- "language": "c",
- "name": "census_resource_test",
- "src": [
- "test/core/census/resource_test.c"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc_test_util"
- ],
- "headers": [],
- "is_filegroup": false,
- "language": "c",
- "name": "census_trace_context_test",
- "src": [
- "test/core/census/trace_context_test.c"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc_test_util"
- ],
- "headers": [],
- "is_filegroup": false,
- "language": "c",
"name": "channel_create_test",
"src": [
"test/core/surface/channel_create_test.c"
@@ -1718,23 +1650,6 @@
"headers": [],
"is_filegroup": false,
"language": "c",
- "name": "mlog_test",
- "src": [
- "test/core/census/mlog_test.c"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc_test_util"
- ],
- "headers": [],
- "is_filegroup": false,
- "language": "c",
"name": "multiple_server_queues_test",
"src": [
"test/core/end2end/multiple_server_queues_test.c"
@@ -7453,7 +7368,6 @@
"headers": [
"third_party/benchmark/include/benchmark/benchmark.h",
"third_party/benchmark/include/benchmark/benchmark_api.h",
- "third_party/benchmark/include/benchmark/macros.h",
"third_party/benchmark/include/benchmark/reporter.h",
"third_party/benchmark/src/arraysize.h",
"third_party/benchmark/src/benchmark_api_internal.h",
@@ -7461,6 +7375,7 @@
"third_party/benchmark/src/colorprint.h",
"third_party/benchmark/src/commandlineflags.h",
"third_party/benchmark/src/complexity.h",
+ "third_party/benchmark/src/counter.h",
"third_party/benchmark/src/cycleclock.h",
"third_party/benchmark/src/internal_macros.h",
"third_party/benchmark/src/log.h",
@@ -7748,64 +7663,14 @@
"nanopb"
],
"headers": [
- "include/grpc/census.h",
- "src/core/ext/census/aggregation.h",
- "src/core/ext/census/base_resources.h",
- "src/core/ext/census/census_interface.h",
- "src/core/ext/census/census_rpc_stats.h",
- "src/core/ext/census/gen/census.pb.h",
- "src/core/ext/census/gen/trace_context.pb.h",
- "src/core/ext/census/grpc_filter.h",
- "src/core/ext/census/intrusive_hash_map.h",
- "src/core/ext/census/intrusive_hash_map_internal.h",
- "src/core/ext/census/mlog.h",
- "src/core/ext/census/resource.h",
- "src/core/ext/census/rpc_metric_id.h",
- "src/core/ext/census/trace_context.h",
- "src/core/ext/census/trace_label.h",
- "src/core/ext/census/trace_propagation.h",
- "src/core/ext/census/trace_status.h",
- "src/core/ext/census/trace_string.h",
- "src/core/ext/census/tracing.h"
+ "include/grpc/census.h"
],
"is_filegroup": true,
"language": "c",
"name": "census",
"src": [
"include/grpc/census.h",
- "src/core/ext/census/aggregation.h",
- "src/core/ext/census/base_resources.cc",
- "src/core/ext/census/base_resources.h",
- "src/core/ext/census/census_interface.h",
- "src/core/ext/census/census_rpc_stats.h",
- "src/core/ext/census/context.cc",
- "src/core/ext/census/gen/census.pb.c",
- "src/core/ext/census/gen/census.pb.h",
- "src/core/ext/census/gen/trace_context.pb.c",
- "src/core/ext/census/gen/trace_context.pb.h",
- "src/core/ext/census/grpc_context.cc",
- "src/core/ext/census/grpc_filter.cc",
- "src/core/ext/census/grpc_filter.h",
- "src/core/ext/census/grpc_plugin.cc",
- "src/core/ext/census/initialize.cc",
- "src/core/ext/census/intrusive_hash_map.cc",
- "src/core/ext/census/intrusive_hash_map.h",
- "src/core/ext/census/intrusive_hash_map_internal.h",
- "src/core/ext/census/mlog.cc",
- "src/core/ext/census/mlog.h",
- "src/core/ext/census/operation.cc",
- "src/core/ext/census/placeholders.cc",
- "src/core/ext/census/resource.cc",
- "src/core/ext/census/resource.h",
- "src/core/ext/census/rpc_metric_id.h",
- "src/core/ext/census/trace_context.cc",
- "src/core/ext/census/trace_context.h",
- "src/core/ext/census/trace_label.h",
- "src/core/ext/census/trace_propagation.h",
- "src/core/ext/census/trace_status.h",
- "src/core/ext/census/trace_string.h",
- "src/core/ext/census/tracing.cc",
- "src/core/ext/census/tracing.h"
+ "src/core/ext/census/grpc_context.cc"
],
"third_party": false,
"type": "filegroup"
@@ -8467,6 +8332,7 @@
"grpc_deadline_filter"
],
"headers": [
+ "src/core/ext/filters/client_channel/backup_poller.h",
"src/core/ext/filters/client_channel/client_channel.h",
"src/core/ext/filters/client_channel/client_channel_factory.h",
"src/core/ext/filters/client_channel/connector.h",
@@ -8490,6 +8356,8 @@
"language": "c",
"name": "grpc_client_channel",
"src": [
+ "src/core/ext/filters/client_channel/backup_poller.cc",
+ "src/core/ext/filters/client_channel/backup_poller.h",
"src/core/ext/filters/client_channel/channel_connectivity.cc",
"src/core/ext/filters/client_channel/client_channel.cc",
"src/core/ext/filters/client_channel/client_channel.h",
@@ -8684,7 +8552,8 @@
"deps": [
"gpr",
"grpc_base",
- "grpc_client_channel"
+ "grpc_client_channel",
+ "grpc_lb_subchannel_list"
],
"headers": [],
"is_filegroup": true,
@@ -8700,7 +8569,8 @@
"deps": [
"gpr",
"grpc_base",
- "grpc_client_channel"
+ "grpc_client_channel",
+ "grpc_lb_subchannel_list"
],
"headers": [],
"is_filegroup": true,
@@ -8715,6 +8585,25 @@
{
"deps": [
"gpr",
+ "grpc_base",
+ "grpc_client_channel"
+ ],
+ "headers": [
+ "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
+ ],
+ "is_filegroup": true,
+ "language": "c",
+ "name": "grpc_lb_subchannel_list",
+ "src": [
+ "src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc",
+ "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
+ ],
+ "third_party": false,
+ "type": "filegroup"
+ },
+ {
+ "deps": [
+ "gpr",
"grpc_base"
],
"headers": [
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 3b1b658..5ba06bf 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -258,102 +258,6 @@
"flaky": false,
"gtest": false,
"language": "c",
- "name": "census_context_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": false
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
- "flaky": false,
- "gtest": false,
- "language": "c",
- "name": "census_intrusive_hash_map_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": false
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
- "flaky": false,
- "gtest": false,
- "language": "c",
- "name": "census_resource_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": false
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
- "flaky": false,
- "gtest": false,
- "language": "c",
- "name": "census_trace_context_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": false
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
- "flaky": false,
- "gtest": false,
- "language": "c",
"name": "channel_create_test",
"platforms": [
"linux",
@@ -1985,30 +1889,6 @@
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
- "flaky": true,
- "gtest": false,
- "language": "c",
- "name": "mlog_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": false
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
@@ -3344,7 +3224,9 @@
"posix"
],
"cpu_cost": 1.0,
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"exclude_iomgrs": [],
"excluded_poll_engines": [
"poll",
@@ -3545,11 +3427,6 @@
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
- "excluded_poll_engines": [
- "poll",
- "poll-cv",
- "epollex"
- ],
"flaky": false,
"gtest": true,
"language": "c++",
@@ -3912,10 +3789,6 @@
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
- "excluded_poll_engines": [
- "poll",
- "poll-cv"
- ],
"flaky": false,
"gtest": true,
"language": "c++",
@@ -3940,11 +3813,6 @@
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
- "excluded_poll_engines": [
- "poll",
- "poll-cv",
- "epollex"
- ],
"flaky": false,
"gtest": false,
"language": "c++",
@@ -4522,7 +4390,6 @@
"posix",
"windows"
],
- "timeout_seconds": 1200,
"uses_polling": true
},
{
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index da5ae53..766c1c0 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -296,23 +296,30 @@
if resolver:
env['GRPC_DNS_RESOLVER'] = resolver
shortname_ext = '' if polling_strategy=='all' else ' GRPC_POLL_STRATEGY=%s' % polling_strategy
- timeout_scaling = 1
-
- if auto_timeout_scaling and polling_strategy == 'poll-cv':
- timeout_scaling *= 5
-
if polling_strategy in target.get('excluded_poll_engines', []):
continue
- # Scale overall test timeout if running under various sanitizers.
- config = self.args.config
- if auto_timeout_scaling and ('asan' in config
- or config == 'msan'
- or config == 'tsan'
- or config == 'ubsan'
- or config == 'helgrind'
- or config == 'memcheck'):
- timeout_scaling *= 20
+ timeout_scaling = 1
+ if auto_timeout_scaling:
+ config = self.args.config
+ if ('asan' in config
+ or config == 'msan'
+ or config == 'tsan'
+ or config == 'ubsan'
+ or config == 'helgrind'
+ or config == 'memcheck'):
+ # Scale overall test timeout if running under various sanitizers.
+ # scaling value is based on historical data analysis
+ timeout_scaling *= 3
+ elif polling_strategy == 'poll-cv':
+ # scale test timeout if running with poll-cv
+ # sanitizer and poll-cv scaling is not cumulative to ensure
+ # reasonable timeout values.
+ # TODO(jtattermusch): based on historical data and 5min default
+ # test timeout poll-cv scaling is currently not useful.
+ # Leaving here so it can be reintroduced if the default test timeout
+ # is decreased in the future.
+ timeout_scaling *= 1
if self.config.build_config in target['exclude_configs']:
continue
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 2aee000..1f7b078 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -26,7 +26,7 @@
git submodule | awk '{ print $1 }' | sort > $submodules
cat << EOF | awk '{ print $1 }' | sort > $want_submodules
- 44c25c892a6229b20db7cd9dc05584ea865896de third_party/benchmark (v0.1.0-343-g44c25c8)
+ 5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8 third_party/benchmark (v1.2.0)
be2ee342d3781ddb954f91f8a7e660c6f59e87e5 third_party/boringssl (heads/chromium-stable)
886e7d75368e3f4fab3f4d0d3584e4abfc557755 third_party/boringssl-with-bazel (version_for_cocoapods_7.0-857-g886e7d7)
30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0)