server: introduce ServerMetricRecorder API and move per-call reporting from a C++ interceptor to a C-core filter (#32106)

* backend metric sampling

* Comments addressed.

* More comments addressed.

* Pushing changes left behind locally.

* Removed empty lines

* Update OrcaService to use ServerMetricRecorder (no named metrics yet)

* Comments addressed.

* More comments addressed

* More comments addressed.

* Comments fixed

* Comments addressed.

* Test fixed

* make seq returned always up-to-date

* skip atomic load when not cached

* Fixed ABSL_GUARDED_BY

* Comments addressed except client_lb_end2end_test

* test updated

* Comments addressed

* BUILD fix.

* BackendMetricDataState moved to a separate header

* comments addressed

* Fixed clang and buildifier errors

* More sanity check errors fixed.

* Fixed xds tests

* Ran generate_projects.sh

* Comments addressed

* comments addressed.

* generate project

* Build fixed

* generate project

* sanity check errors fixed

* test fixed

* Backup poller period override moved to main()

* Also move cfstream override

* Clang fixes, sanitize

* generate_projects.sh

* portable print format fix

* Removed outdated comment
pull/32272/head
Yousuk Seung 2 years ago committed by GitHub
parent 95b2f0c8ca
commit c7f641da0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      BUILD
  2. 33
      CMakeLists.txt
  3. 2
      Makefile
  4. 58
      build_autogenerated.yaml
  5. 2
      config.m4
  6. 2
      config.w32
  7. 13
      gRPC-C++.podspec
  8. 9
      gRPC-Core.podspec
  9. 3
      grpc.gemspec
  10. 6
      grpc.gyp
  11. 3
      include/grpc/impl/grpc_types.h
  12. 43
      include/grpcpp/ext/call_metric_recorder.h
  13. 33
      include/grpcpp/ext/orca_service.h
  14. 108
      include/grpcpp/ext/server_metric_recorder.h
  15. 17
      include/grpcpp/server.h
  16. 16
      include/grpcpp/server_builder.h
  17. 16
      include/grpcpp/server_context.h
  18. 8
      include/grpcpp/server_interface.h
  19. 3
      package.xml
  20. 43
      src/core/BUILD
  21. 148
      src/core/ext/filters/backend_metrics/backend_metric_filter.cc
  22. 56
      src/core/ext/filters/backend_metrics/backend_metric_filter.h
  23. 33
      src/core/ext/filters/backend_metrics/backend_metric_provider.h
  24. 4
      src/core/lib/channel/context.h
  25. 2
      src/core/plugin_registry/grpc_plugin_registry.cc
  26. 311
      src/cpp/server/backend_metric_recorder.cc
  27. 81
      src/cpp/server/backend_metric_recorder.h
  28. 125
      src/cpp/server/orca/call_metric_recorder.cc
  29. 76
      src/cpp/server/orca/orca_interceptor.cc
  30. 49
      src/cpp/server/orca/orca_interceptor.h
  31. 93
      src/cpp/server/orca/orca_service.cc
  32. 17
      src/cpp/server/server_builder.cc
  33. 20
      src/cpp/server/server_cc.cc
  34. 12
      src/cpp/server/server_context.cc
  35. 1
      src/python/grpcio/grpc_core_dependencies.py
  36. 5
      test/cpp/end2end/BUILD
  37. 300
      test/cpp/end2end/client_lb_end2end_test.cc
  38. 30
      test/cpp/end2end/orca_service_end2end_test.cc
  39. 1
      test/cpp/end2end/xds/BUILD
  40. 2
      test/cpp/end2end/xds/xds_end2end_test_lib.cc
  41. 1
      tools/doxygen/Doxyfile.c++
  42. 7
      tools/doxygen/Doxyfile.c++.internal
  43. 3
      tools/doxygen/Doxyfile.core.internal

37
BUILD

@ -761,6 +761,7 @@ grpc_cc_library(
"grpc_base",
# standard plugins
"census",
"//src/core:grpc_backend_metric_filter",
"//src/core:grpc_deadline_filter",
"//src/core:grpc_client_authority_filter",
"//src/core:grpc_lb_policy_grpclb",
@ -1818,6 +1819,7 @@ grpc_cc_library(
"grpc_security_base",
"grpc_service_config_impl",
"grpc_trace",
"grpcpp_backend_metric_recorder",
"grpcpp_call_metric_recorder",
"grpcpp_status",
"iomgr_timer",
@ -1833,6 +1835,7 @@ grpc_cc_library(
"//src/core:error",
"//src/core:gpr_atm",
"//src/core:gpr_manual_constructor",
"//src/core:grpc_backend_metric_provider",
"//src/core:grpc_service_config",
"//src/core:grpc_transport_inproc",
"//src/core:json",
@ -1885,6 +1888,7 @@ grpc_cc_library(
"grpc_service_config_impl",
"grpc_trace",
"grpc_unsecure",
"grpcpp_backend_metric_recorder",
"grpcpp_call_metric_recorder",
"grpcpp_status",
"iomgr_timer",
@ -1896,6 +1900,7 @@ grpc_cc_library(
"//src/core:error",
"//src/core:gpr_atm",
"//src/core:gpr_manual_constructor",
"//src/core:grpc_backend_metric_provider",
"//src/core:grpc_insecure_credentials",
"//src/core:grpc_service_config",
"//src/core:grpc_transport_inproc",
@ -1973,45 +1978,42 @@ grpc_cc_library(
grpc_cc_library(
name = "grpcpp_call_metric_recorder",
srcs = [
"src/cpp/server/orca/call_metric_recorder.cc",
],
external_deps = [
"absl/strings",
"absl/types:optional",
"upb_lib",
],
language = "c++",
public_hdrs = [
"include/grpcpp/ext/call_metric_recorder.h",
],
visibility = ["@grpc:public"],
deps = [
"grpc++_public_hdrs",
"xds_orca_upb",
"//src/core:arena",
"//src/core:grpc_backend_metric_data",
],
deps = ["grpc++_public_hdrs"],
)
grpc_cc_library(
name = "grpcpp_orca_interceptor",
name = "grpcpp_backend_metric_recorder",
srcs = [
"src/cpp/server/orca/orca_interceptor.cc",
"src/cpp/server/backend_metric_recorder.cc",
],
hdrs = [
"src/cpp/server/orca/orca_interceptor.h",
"src/cpp/server/backend_metric_recorder.h",
],
external_deps = [
"absl/base:core_headers",
"absl/strings",
"absl/types:optional",
],
language = "c++",
public_hdrs = [
"include/grpcpp/ext/server_metric_recorder.h",
],
visibility = ["@grpc:public"],
deps = [
"grpc++",
"grpc_base",
"gpr",
"grpc++_public_hdrs",
"grpc_trace",
"grpcpp_call_metric_recorder",
"//src/core:grpc_backend_metric_data",
"//src/core:grpc_backend_metric_provider",
],
)
@ -2022,6 +2024,7 @@ grpc_cc_library(
],
external_deps = [
"absl/base:core_headers",
"absl/strings",
"absl/time",
"absl/types:optional",
"upb_lib",
@ -2037,11 +2040,13 @@ grpc_cc_library(
"gpr",
"grpc++",
"grpc_base",
"grpcpp_backend_metric_recorder",
"protobuf_duration_upb",
"ref_counted_ptr",
"xds_orca_service_upb",
"xds_orca_upb",
"//src/core:default_event_engine",
"//src/core:grpc_backend_metric_data",
"//src/core:ref_counted",
"//src/core:time",
],

33
CMakeLists.txt generated

@ -1703,6 +1703,7 @@ endif()
add_library(grpc
src/core/ext/filters/backend_metrics/backend_metric_filter.cc
src/core/ext/filters/census/grpc_context.cc
src/core/ext/filters/channel_idle/channel_idle_filter.cc
src/core/ext/filters/channel_idle/idle_filter_state.cc
@ -2718,6 +2719,7 @@ endif()
endif()
add_library(grpc_unsecure
src/core/ext/filters/backend_metrics/backend_metric_filter.cc
src/core/ext/filters/census/grpc_context.cc
src/core/ext/filters/channel_idle/channel_idle_filter.cc
src/core/ext/filters/channel_idle/idle_filter_state.cc
@ -3352,6 +3354,7 @@ add_library(grpc++
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -3359,7 +3362,6 @@ add_library(grpc++
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
@ -3498,6 +3500,7 @@ foreach(_hdr
include/grpcpp/create_channel_posix.h
include/grpcpp/ext/call_metric_recorder.h
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/ext/server_metric_recorder.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/grpcpp.h
@ -4057,6 +4060,7 @@ add_library(grpc++_unsecure
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -4064,7 +4068,6 @@ add_library(grpc++_unsecure
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
src/cpp/server/server_cc.cc
@ -4200,6 +4203,7 @@ foreach(_hdr
include/grpcpp/create_channel_posix.h
include/grpcpp/ext/call_metric_recorder.h
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/ext/server_metric_recorder.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/grpcpp.h
@ -7133,6 +7137,7 @@ add_executable(binder_transport_test
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -7140,7 +7145,6 @@ add_executable(binder_transport_test
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
@ -8801,7 +8805,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
src/cpp/server/orca/orca_service.cc
test/core/util/test_lb_policies.cc
test/cpp/end2end/client_lb_end2end_test.cc
@ -10026,6 +10029,7 @@ add_executable(endpoint_binder_pool_test
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -10033,7 +10037,6 @@ add_executable(endpoint_binder_pool_test
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
@ -10718,6 +10721,7 @@ add_executable(fake_binder_test
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -10725,7 +10729,6 @@ add_executable(fake_binder_test
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
@ -21460,6 +21463,7 @@ add_executable(transport_stream_receiver_test
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -21467,7 +21471,6 @@ add_executable(transport_stream_receiver_test
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
@ -22205,6 +22208,7 @@ add_executable(wire_reader_test
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -22212,7 +22216,6 @@ add_executable(wire_reader_test
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
@ -22305,6 +22308,7 @@ add_executable(wire_writer_test
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/backend_metric_recorder.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
@ -22312,7 +22316,6 @@ add_executable(wire_writer_test
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/orca/call_metric_recorder.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
@ -22757,7 +22760,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/connection_attempt_injector.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_cluster_end2end_test.cc
@ -23032,7 +23034,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/connection_attempt_injector.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc
@ -23281,7 +23282,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_core_end2end_test.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -23561,7 +23561,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/csds/csds.cc
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_csds_end2end_test.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -23745,7 +23744,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -23980,7 +23978,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc
@ -24675,7 +24672,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc
@ -24855,7 +24851,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
test/cpp/end2end/xds/xds_override_host_end2end_test.cc
@ -25101,7 +25096,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/connection_attempt_injector.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -25278,7 +25272,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/rls_server.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -25571,7 +25564,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
test/cpp/end2end/xds/xds_routing_end2end_test.cc
@ -25747,7 +25739,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/wrr_locality.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/wrr_locality.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/wrr_locality.grpc.pb.h
src/cpp/server/orca/orca_interceptor.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test_lib.cc
test/cpp/end2end/xds/xds_server.cc

2
Makefile generated

@ -958,6 +958,7 @@ endif
# start of build recipe for library "grpc" (generated by makelib(lib) template function)
LIBGRPC_SRC = \
src/core/ext/filters/backend_metrics/backend_metric_filter.cc \
src/core/ext/filters/census/grpc_context.cc \
src/core/ext/filters/channel_idle/channel_idle_filter.cc \
src/core/ext/filters/channel_idle/idle_filter_state.cc \
@ -1826,6 +1827,7 @@ endif
# start of build recipe for library "grpc_unsecure" (generated by makelib(lib) template function)
LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/backend_metrics/backend_metric_filter.cc \
src/core/ext/filters/census/grpc_context.cc \
src/core/ext/filters/channel_idle/channel_idle_filter.cc \
src/core/ext/filters/channel_idle/idle_filter_state.cc \

@ -324,6 +324,8 @@ libs:
- include/grpc/support/time.h
- include/grpc/support/workaround_list.h
headers:
- src/core/ext/filters/backend_metrics/backend_metric_filter.h
- src/core/ext/filters/backend_metrics/backend_metric_provider.h
- src/core/ext/filters/channel_idle/channel_idle_filter.h
- src/core/ext/filters/channel_idle/idle_filter_state.h
- src/core/ext/filters/client_channel/backend_metric.h
@ -1093,6 +1095,7 @@ libs:
- src/core/tsi/transport_security_interface.h
- third_party/xxhash/xxhash.h
src:
- src/core/ext/filters/backend_metrics/backend_metric_filter.cc
- src/core/ext/filters/census/grpc_context.cc
- src/core/ext/filters/channel_idle/channel_idle_filter.cc
- src/core/ext/filters/channel_idle/idle_filter_state.cc
@ -1986,6 +1989,8 @@ libs:
- include/grpc/support/time.h
- include/grpc/support/workaround_list.h
headers:
- src/core/ext/filters/backend_metrics/backend_metric_filter.h
- src/core/ext/filters/backend_metrics/backend_metric_provider.h
- src/core/ext/filters/channel_idle/channel_idle_filter.h
- src/core/ext/filters/channel_idle/idle_filter_state.h
- src/core/ext/filters/client_channel/backend_metric.h
@ -2369,6 +2374,7 @@ libs:
- src/core/tsi/transport_security_interface.h
- third_party/xxhash/xxhash.h
src:
- src/core/ext/filters/backend_metrics/backend_metric_filter.cc
- src/core/ext/filters/census/grpc_context.cc
- src/core/ext/filters/channel_idle/channel_idle_filter.cc
- src/core/ext/filters/channel_idle/idle_filter_state.cc
@ -2874,6 +2880,7 @@ libs:
- include/grpcpp/create_channel_posix.h
- include/grpcpp/ext/call_metric_recorder.h
- include/grpcpp/ext/health_check_service_server_builder_option.h
- include/grpcpp/ext/server_metric_recorder.h
- include/grpcpp/generic/async_generic_service.h
- include/grpcpp/generic/generic_stub.h
- include/grpcpp/grpcpp.h
@ -3018,6 +3025,7 @@ libs:
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -3069,6 +3077,7 @@ libs:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -3076,7 +3085,6 @@ libs:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
@ -3293,6 +3301,7 @@ libs:
- include/grpcpp/create_channel_posix.h
- include/grpcpp/ext/call_metric_recorder.h
- include/grpcpp/ext/health_check_service_server_builder_option.h
- include/grpcpp/ext/server_metric_recorder.h
- include/grpcpp/generic/async_generic_service.h
- include/grpcpp/generic/generic_stub.h
- include/grpcpp/grpcpp.h
@ -3412,6 +3421,7 @@ libs:
headers:
- src/cpp/client/create_channel_internal.h
- src/cpp/common/channel_filter.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -3436,6 +3446,7 @@ libs:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -3443,7 +3454,6 @@ libs:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
- src/cpp/server/server_cc.cc
@ -5078,6 +5088,7 @@ targets:
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -5129,6 +5140,7 @@ targets:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -5136,7 +5148,6 @@ targets:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
@ -5965,7 +5976,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/core/util/test_lb_policies.h
- test/cpp/end2end/connection_attempt_injector.h
- test/cpp/end2end/test_service_impl.h
@ -5975,7 +5985,6 @@ targets:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/simple_messages.proto
- src/proto/grpc/testing/xds/v3/orca_load_report.proto
- src/cpp/server/orca/orca_interceptor.cc
- src/cpp/server/orca/orca_service.cc
- test/core/util/test_lb_policies.cc
- test/cpp/end2end/client_lb_end2end_test.cc
@ -6435,6 +6444,7 @@ targets:
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -6486,6 +6496,7 @@ targets:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -6493,7 +6504,6 @@ targets:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
@ -6855,6 +6865,7 @@ targets:
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -6906,6 +6917,7 @@ targets:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -6913,7 +6925,6 @@ targets:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
@ -12077,6 +12088,7 @@ targets:
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -12127,6 +12139,7 @@ targets:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -12134,7 +12147,6 @@ targets:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
@ -12469,6 +12481,7 @@ targets:
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -12520,6 +12533,7 @@ targets:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -12527,7 +12541,6 @@ targets:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
@ -12573,6 +12586,7 @@ targets:
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/backend_metric_recorder.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
@ -12624,6 +12638,7 @@ targets:
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/backend_metric_recorder.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
@ -12631,7 +12646,6 @@ targets:
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/orca/call_metric_recorder.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
@ -12756,7 +12770,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/connection_attempt_injector.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
@ -12795,7 +12808,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/connection_attempt_injector.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_cluster_end2end_test.cc
@ -12842,7 +12854,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/connection_attempt_injector.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
@ -12882,7 +12893,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/connection_attempt_injector.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc
@ -12933,7 +12943,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/core/util/scoped_env_var.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
@ -12972,7 +12981,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_core_end2end_test.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -13039,7 +13047,6 @@ targets:
language: c++
headers:
- src/cpp/server/csds/csds.h
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/end2end/xds/xds_end2end_test_lib.h
@ -13080,7 +13087,6 @@ targets:
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/csds/csds.cc
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_csds_end2end_test.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -13098,7 +13104,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/end2end/xds/xds_end2end_test_lib.h
@ -13140,7 +13145,6 @@ targets:
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/proto/grpc/testing/xds/v3/tls.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -13176,7 +13180,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/end2end/xds/xds_end2end_test_lib.h
@ -13216,7 +13219,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
- test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc
@ -13413,7 +13415,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/end2end/xds/xds_end2end_test_lib.h
@ -13453,7 +13454,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
- test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc
@ -13470,7 +13470,6 @@ targets:
build: test
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/core/util/scoped_env_var.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
@ -13512,7 +13511,6 @@ targets:
- src/proto/grpc/testing/xds/v3/stateful_session.proto
- src/proto/grpc/testing/xds/v3/stateful_session_cookie.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
- test/cpp/end2end/xds/xds_override_host_end2end_test.cc
@ -13551,7 +13549,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/connection_attempt_injector.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
@ -13591,7 +13588,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/connection_attempt_injector.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -13609,7 +13605,6 @@ targets:
build: test
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/core/util/scoped_env_var.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/rls_server.h
@ -13651,7 +13646,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/rls_server.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
@ -13712,7 +13706,6 @@ targets:
run: false
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/end2end/xds/xds_end2end_test_lib.h
@ -13752,7 +13745,6 @@ targets:
- src/proto/grpc/testing/xds/v3/route.proto
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
- test/cpp/end2end/xds/xds_routing_end2end_test.cc
@ -13769,7 +13761,6 @@ targets:
build: test
language: c++
headers:
- src/cpp/server/orca/orca_interceptor.h
- test/core/util/scoped_env_var.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/test_service_impl.h
@ -13810,7 +13801,6 @@ targets:
- src/proto/grpc/testing/xds/v3/router.proto
- src/proto/grpc/testing/xds/v3/string.proto
- src/proto/grpc/testing/xds/v3/wrr_locality.proto
- src/cpp/server/orca/orca_interceptor.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test_lib.cc
- test/cpp/end2end/xds/xds_server.cc

2
config.m4 generated

@ -40,6 +40,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_SUBST(GRPC_SHARED_LIBADD)
PHP_NEW_EXTENSION(grpc,
src/core/ext/filters/backend_metrics/backend_metric_filter.cc \
src/core/ext/filters/census/grpc_context.cc \
src/core/ext/filters/channel_idle/channel_idle_filter.cc \
src/core/ext/filters/channel_idle/idle_filter_state.cc \
@ -1266,6 +1267,7 @@ if test "$PHP_GRPC" != "no"; then
-DGRPC_XDS_USER_AGENT_NAME_SUFFIX='"\"PHP\""' \
-DGRPC_XDS_USER_AGENT_VERSION_SUFFIX='"\"1.53.0dev\""')
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/backend_metrics)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/census)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/channel_idle)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel)

2
config.w32 generated

@ -6,6 +6,7 @@ ARG_WITH("grpc", "grpc support", "no");
if (PHP_GRPC != "no") {
EXTENSION("grpc",
"src\\core\\ext\\filters\\backend_metrics\\backend_metric_filter.cc " +
"src\\core\\ext\\filters\\census\\grpc_context.cc " +
"src\\core\\ext\\filters\\channel_idle\\channel_idle_filter.cc " +
"src\\core\\ext\\filters\\channel_idle\\idle_filter_state.cc " +
@ -1264,6 +1265,7 @@ if (PHP_GRPC != "no") {
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\\filters");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\backend_metrics");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\census");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\channel_idle");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel");

13
gRPC-C++.podspec generated

@ -91,6 +91,7 @@ Pod::Spec.new do |s|
'include/grpcpp/create_channel_posix.h',
'include/grpcpp/ext/call_metric_recorder.h',
'include/grpcpp/ext/health_check_service_server_builder_option.h',
'include/grpcpp/ext/server_metric_recorder.h',
'include/grpcpp/generic/async_generic_service.h',
'include/grpcpp/generic/generic_stub.h',
'include/grpcpp/grpcpp.h',
@ -238,7 +239,9 @@ Pod::Spec.new do |s|
ss.dependency 'abseil/types/variant', abseil_version
ss.dependency 'abseil/utility/utility', abseil_version
ss.source_files = 'src/core/ext/filters/channel_idle/channel_idle_filter.h',
ss.source_files = 'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
'src/core/ext/filters/channel_idle/channel_idle_filter.h',
'src/core/ext/filters/channel_idle/idle_filter_state.h',
'src/core/ext/filters/client_channel/backend_metric.h',
'src/core/ext/filters/client_channel/backup_poller.h',
@ -1098,6 +1101,8 @@ Pod::Spec.new do |s|
'src/cpp/common/validate_service_config.cc',
'src/cpp/common/version_cc.cc',
'src/cpp/server/async_generic_service.cc',
'src/cpp/server/backend_metric_recorder.cc',
'src/cpp/server/backend_metric_recorder.h',
'src/cpp/server/channel_argument_option.cc',
'src/cpp/server/create_default_thread_pool.cc',
'src/cpp/server/dynamic_thread_pool.h',
@ -1108,7 +1113,6 @@ Pod::Spec.new do |s|
'src/cpp/server/health/health_check_service.cc',
'src/cpp/server/health/health_check_service_server_builder_option.cc',
'src/cpp/server/insecure_server_credentials.cc',
'src/cpp/server/orca/call_metric_recorder.cc',
'src/cpp/server/secure_server_credentials.cc',
'src/cpp/server/secure_server_credentials.h',
'src/cpp/server/server_builder.cc',
@ -1183,7 +1187,9 @@ Pod::Spec.new do |s|
'third_party/upb/upb/upb.hpp',
'third_party/xxhash/xxhash.h'
ss.private_header_files = 'src/core/ext/filters/channel_idle/channel_idle_filter.h',
ss.private_header_files = 'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
'src/core/ext/filters/channel_idle/channel_idle_filter.h',
'src/core/ext/filters/channel_idle/idle_filter_state.h',
'src/core/ext/filters/client_channel/backend_metric.h',
'src/core/ext/filters/client_channel/backup_poller.h',
@ -1999,6 +2005,7 @@ Pod::Spec.new do |s|
'src/cpp/client/secure_credentials.h',
'src/cpp/common/channel_filter.h',
'src/cpp/common/secure_auth_context.h',
'src/cpp/server/backend_metric_recorder.h',
'src/cpp/server/dynamic_thread_pool.h',
'src/cpp/server/external_connection_acceptor_impl.h',
'src/cpp/server/health/default_health_check_service.h',

9
gRPC-Core.podspec generated

@ -206,7 +206,10 @@ Pod::Spec.new do |s|
ss.dependency 'abseil/utility/utility', abseil_version
ss.compiler_flags = '-DBORINGSSL_PREFIX=GRPC -Wno-unreachable-code -Wno-shorten-64-to-32'
ss.source_files = 'src/core/ext/filters/census/grpc_context.cc',
ss.source_files = 'src/core/ext/filters/backend_metrics/backend_metric_filter.cc',
'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
'src/core/ext/filters/census/grpc_context.cc',
'src/core/ext/filters/channel_idle/channel_idle_filter.cc',
'src/core/ext/filters/channel_idle/channel_idle_filter.h',
'src/core/ext/filters/channel_idle/idle_filter_state.cc',
@ -1886,7 +1889,9 @@ Pod::Spec.new do |s|
'third_party/upb/upb/upb.h',
'third_party/upb/upb/upb.hpp',
'third_party/xxhash/xxhash.h'
ss.private_header_files = 'src/core/ext/filters/channel_idle/channel_idle_filter.h',
ss.private_header_files = 'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
'src/core/ext/filters/channel_idle/channel_idle_filter.h',
'src/core/ext/filters/channel_idle/idle_filter_state.h',
'src/core/ext/filters/client_channel/backend_metric.h',
'src/core/ext/filters/client_channel/backup_poller.h',

3
grpc.gemspec generated

@ -115,6 +115,9 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/support/thd_id.h )
s.files += %w( include/grpc/support/time.h )
s.files += %w( include/grpc/support/workaround_list.h )
s.files += %w( src/core/ext/filters/backend_metrics/backend_metric_filter.cc )
s.files += %w( src/core/ext/filters/backend_metrics/backend_metric_filter.h )
s.files += %w( src/core/ext/filters/backend_metrics/backend_metric_provider.h )
s.files += %w( src/core/ext/filters/census/grpc_context.cc )
s.files += %w( src/core/ext/filters/channel_idle/channel_idle_filter.cc )
s.files += %w( src/core/ext/filters/channel_idle/channel_idle_filter.h )

6
grpc.gyp generated

@ -371,6 +371,7 @@
'upb',
],
'sources': [
'src/core/ext/filters/backend_metrics/backend_metric_filter.cc',
'src/core/ext/filters/census/grpc_context.cc',
'src/core/ext/filters/channel_idle/channel_idle_filter.cc',
'src/core/ext/filters/channel_idle/idle_filter_state.cc',
@ -1181,6 +1182,7 @@
'upb',
],
'sources': [
'src/core/ext/filters/backend_metrics/backend_metric_filter.cc',
'src/core/ext/filters/census/grpc_context.cc',
'src/core/ext/filters/channel_idle/channel_idle_filter.cc',
'src/core/ext/filters/channel_idle/idle_filter_state.cc',
@ -1618,6 +1620,7 @@
'src/cpp/common/validate_service_config.cc',
'src/cpp/common/version_cc.cc',
'src/cpp/server/async_generic_service.cc',
'src/cpp/server/backend_metric_recorder.cc',
'src/cpp/server/channel_argument_option.cc',
'src/cpp/server/create_default_thread_pool.cc',
'src/cpp/server/external_connection_acceptor_impl.cc',
@ -1625,7 +1628,6 @@
'src/cpp/server/health/health_check_service.cc',
'src/cpp/server/health/health_check_service_server_builder_option.cc',
'src/cpp/server/insecure_server_credentials.cc',
'src/cpp/server/orca/call_metric_recorder.cc',
'src/cpp/server/secure_server_credentials.cc',
'src/cpp/server/server_builder.cc',
'src/cpp/server/server_callback.cc',
@ -1751,6 +1753,7 @@
'src/cpp/common/validate_service_config.cc',
'src/cpp/common/version_cc.cc',
'src/cpp/server/async_generic_service.cc',
'src/cpp/server/backend_metric_recorder.cc',
'src/cpp/server/channel_argument_option.cc',
'src/cpp/server/create_default_thread_pool.cc',
'src/cpp/server/external_connection_acceptor_impl.cc',
@ -1758,7 +1761,6 @@
'src/cpp/server/health/health_check_service.cc',
'src/cpp/server/health/health_check_service_server_builder_option.cc',
'src/cpp/server/insecure_server_credentials.cc',
'src/cpp/server/orca/call_metric_recorder.cc',
'src/cpp/server/server_builder.cc',
'src/cpp/server/server_callback.cc',
'src/cpp/server/server_cc.cc',

@ -141,6 +141,9 @@ typedef struct {
#define GRPC_ARG_ENABLE_CENSUS "grpc.census"
/** If non-zero, enable load reporting. */
#define GRPC_ARG_ENABLE_LOAD_REPORTING "grpc.loadreporting"
/** If non-zero, call metric recording is enabled. */
#define GRPC_ARG_SERVER_CALL_METRIC_RECORDING \
"grpc.server_call_metric_recording"
/** Request that optional features default to off (regardless of what they
usually default to) - to enable tight control over what gets enabled */
#define GRPC_ARG_MINIMAL_STACK "grpc.minimal_stack"

@ -28,43 +28,30 @@
#include <grpcpp/impl/sync.h>
#include <grpcpp/support/slice.h>
namespace grpc_core {
class Arena;
struct BackendMetricData;
} // namespace grpc_core
namespace grpc {
class ServerBuilder;
namespace experimental {
class OrcaServerInterceptor;
// Registers the per-rpc orca load reporter into the \a ServerBuilder.
// Once this is done, the server will automatically send the load metrics
// after each RPC as they were reported. In order to report load metrics,
// call the \a ServerContext::ExperimentalGetCallMetricRecorder() method to
// retrieve the recorder for the current call.
void EnableCallMetricRecording(ServerBuilder*);
/// Records call metrics for the purpose of load balancing.
/// During an RPC, call \a ServerContext::ExperimentalGetCallMetricRecorder()
/// method to retrive the recorder for the current call.
class CallMetricRecorder {
public:
explicit CallMetricRecorder(grpc_core::Arena* arena);
~CallMetricRecorder();
virtual ~CallMetricRecorder() = default;
/// Records a call metric measurement for CPU utilization.
/// Multiple calls to this method will override the stored value.
CallMetricRecorder& RecordCpuUtilizationMetric(double value);
/// Values outside of the valid range [0, 1] are ignored.
virtual CallMetricRecorder& RecordCpuUtilizationMetric(double value) = 0;
/// Records a call metric measurement for memory utilization.
/// Multiple calls to this method will override the stored value.
CallMetricRecorder& RecordMemoryUtilizationMetric(double value);
/// Values outside of the valid range [0, 1] are ignored.
virtual CallMetricRecorder& RecordMemoryUtilizationMetric(double value) = 0;
/// Records a call metric measurement for QPS.
/// Records a call metric measurement for queries per second.
/// Multiple calls to this method will override the stored value.
CallMetricRecorder& RecordQpsMetric(double value);
/// Values outside of the valid range [0, infy) are ignored.
virtual CallMetricRecorder& RecordQpsMetric(double value) = 0;
/// Records a call metric measurement for utilization.
/// Multiple calls to this method with the same name will
@ -73,7 +60,9 @@ class CallMetricRecorder {
/// itself, since it's going to be sent as trailers after the RPC
/// finishes. It is assumed the strings are common names that
/// are global constants.
CallMetricRecorder& RecordUtilizationMetric(string_ref name, double value);
/// Values outside of the valid range [0, 1] are ignored.
virtual CallMetricRecorder& RecordUtilizationMetric(string_ref name,
double value) = 0;
/// Records a call metric measurement for request cost.
/// Multiple calls to this method with the same name will
@ -82,14 +71,8 @@ class CallMetricRecorder {
/// itself, since it's going to be sent as trailers after the RPC
/// finishes. It is assumed the strings are common names that
/// are global constants.
CallMetricRecorder& RecordRequestCostMetric(string_ref name, double value);
private:
absl::optional<std::string> CreateSerializedReport();
internal::Mutex mu_;
grpc_core::BackendMetricData* backend_metric_data_ ABSL_GUARDED_BY(&mu_);
friend class experimental::OrcaServerInterceptor;
virtual CallMetricRecorder& RecordRequestCostMetric(string_ref name,
double value) = 0;
};
} // namespace experimental

@ -23,6 +23,7 @@
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include <grpcpp/ext/server_metric_recorder.h>
#include <grpcpp/impl/service_type.h>
#include <grpcpp/impl/sync.h>
#include <grpcpp/server_builder.h>
@ -48,38 +49,22 @@ class OrcaService : public Service {
}
};
explicit OrcaService(Options options);
// Sets or removes the CPU utilization value to be reported to clients.
void SetCpuUtilization(double cpu_utilization);
void DeleteCpuUtilization();
// Sets of removes the memory utilization value to be reported to clients.
void SetMemoryUtilization(double memory_utilization);
void DeleteMemoryUtilization();
// Sets of removes the QPS value to be reported to clients.
void SetQps(double qps);
void DeleteQps();
// Sets or removed named utilization values to be reported to clients.
void SetNamedUtilization(std::string name, double utilization);
void DeleteNamedUtilization(const std::string& name);
void SetAllNamedUtilization(std::map<std::string, double> named_utilization);
// ServerMetricRecorder is required.
OrcaService(ServerMetricRecorder* const server_metric_recorder,
Options options);
private:
class Reactor;
Slice GetOrCreateSerializedResponse();
const ServerMetricRecorder* const server_metric_recorder_;
const absl::Duration min_report_duration_;
grpc::internal::Mutex mu_;
double cpu_utilization_ ABSL_GUARDED_BY(&mu_) = -1;
double memory_utilization_ ABSL_GUARDED_BY(&mu_) = -1;
double qps_ ABSL_GUARDED_BY(&mu_) = -1;
std::map<std::string, double> named_utilization_ ABSL_GUARDED_BY(&mu_);
absl::optional<Slice> response_slice_ ABSL_GUARDED_BY(&mu_);
// Contains the last serialized metrics from server_metric_recorder_.
absl::optional<Slice> response_slice_ ABSL_GUARDED_BY(mu_);
// The update sequence number of metrics serialized in response_slice_.
absl::optional<uint64_t> response_slice_seq_ ABSL_GUARDED_BY(mu_);
};
} // namespace experimental

@ -0,0 +1,108 @@
//
//
// Copyright 2023 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 GRPCPP_EXT_SERVER_METRIC_RECORDER_H
#define GRPCPP_EXT_SERVER_METRIC_RECORDER_H
#include <functional>
#include <map>
#include <memory>
#include <grpcpp/impl/sync.h>
#include <grpcpp/support/string_ref.h>
namespace grpc_core {
struct BackendMetricData;
} // namespace grpc_core
namespace grpc {
class BackendMetricState;
namespace experimental {
/// Records server wide metrics to be reported to the client.
/// Server implementation creates an instance and reports server metrics to it,
/// and then passes it to
/// ServerBuilder::experimental_type::EnableCallMetricRecording or
/// experimental::OrcaService that read metrics to include in the report.
class ServerMetricRecorder {
public:
// Factory method. Use this to create.
static std::unique_ptr<ServerMetricRecorder> Create();
/// Records the server CPU utilization in the range [0, 1].
/// Values outside of the valid range are rejected.
/// Overrides the stored value when called again with a valid value.
void SetCpuUtilization(double value);
/// Records the server memory utilization in the range [0, 1].
/// Values outside of the valid range are rejected.
/// Overrides the stored value when called again with a valid value.
void SetMemoryUtilization(double value);
/// Records number of queries per second to the server in the range [0, infy).
/// Values outside of the valid range are rejected.
/// Overrides the stored value when called again with a valid value.
void SetQps(double value);
/// Records a named resource utilization value in the range [0, 1].
/// Values outside of the valid range are rejected.
/// Overrides the stored value when called again with the same name.
/// The name string should remain valid while this utilization remains
/// in this recorder. It is assumed that strings are common names that are
/// global constants.
void SetNamedUtilization(string_ref name, double value);
/// Replaces all named resource utilization values. No range validation.
/// The name strings should remain valid while utilization values remain
/// in this recorder. It is assumed that strings are common names that are
/// global constants.
void SetAllNamedUtilization(std::map<string_ref, double> named_utilization);
/// Clears the server CPU utilization if recorded.
void ClearCpuUtilization();
/// Clears the server memory utilization if recorded.
void ClearMemoryUtilization();
/// Clears number of queries per second to the server if recorded.
void ClearQps();
/// Clears a named utilization value if exists.
void ClearNamedUtilization(string_ref name);
private:
// To access GetMetrics().
friend class grpc::BackendMetricState;
friend class OrcaService;
struct BackendMetricDataState;
// No direct creation, use the factory method Create() above.
ServerMetricRecorder();
// Updates the metric state by applying `updater` to the data and incrementing
// the sequence number.
void UpdateBackendMetricDataState(
std::function<void(grpc_core::BackendMetricData*)> updater);
grpc_core::BackendMetricData GetMetrics() const;
// Returned metric data is guaranteed to be identical between two calls if the
// sequence numbers match.
std::shared_ptr<const BackendMetricDataState> GetMetricsIfChanged() const;
mutable grpc::internal::Mutex mu_;
std::shared_ptr<const BackendMetricDataState> metric_state_
ABSL_GUARDED_BY(mu_);
};
} // namespace experimental
} // namespace grpc
#endif // GRPCPP_EXT_SERVER_METRIC_RECORDER_H

@ -183,7 +183,8 @@ class Server : public ServerInterface, private internal::GrpcLibrary {
std::vector<
std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
interceptor_creators = std::vector<std::unique_ptr<
experimental::ServerInterceptorFactoryInterface>>());
experimental::ServerInterceptorFactoryInterface>>(),
experimental::ServerMetricRecorder* server_metric_recorder = nullptr);
/// Start the server.
///
@ -255,6 +256,14 @@ class Server : public ServerInterface, private internal::GrpcLibrary {
return max_receive_message_size_;
}
bool call_metric_recording_enabled() const override {
return call_metric_recording_enabled_;
}
experimental::ServerMetricRecorder* server_metric_recorder() const override {
return server_metric_recorder_;
}
CompletionQueue* CallbackCQ() ABSL_LOCKS_EXCLUDED(mu_) override;
ServerInitializer* initializer();
@ -338,6 +347,12 @@ class Server : public ServerInterface, private internal::GrpcLibrary {
// Shutdown. Even though this is only used with NDEBUG, instantiate it in all
// cases since otherwise the size will be inconsistent.
std::vector<CompletionQueue*> cq_list_;
// Whetner per-call load reporting is enabled.
bool call_metric_recording_enabled_ = false;
// Interface to read or update server-wide metrics. Optional.
experimental::ServerMetricRecorder* server_metric_recorder_ = nullptr;
};
} // namespace grpc

@ -59,7 +59,6 @@ class ExternalConnectionAcceptorImpl;
class CallbackGenericService;
namespace experimental {
class OrcaServerInterceptorFactory;
// EXPERIMENTAL API:
// Interface for a grpc server to build transports with connections created out
// of band.
@ -283,6 +282,16 @@ class ServerBuilder {
std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
provider);
/// Enables per-call load reporting. The server will automatically send the
/// load metrics after each RPC. The caller can report load metrics for the
/// current call to what ServerContext::ExperimentalGetCallMetricRecorder()
/// returns. The server merges metrics from the optional
/// server_metric_recorder when provided where the call metric recorder take
/// a higher precedence. The caller owns and must ensure the server metric
/// recorder outlives the server.
void EnableCallMetricRecording(
experimental::ServerMetricRecorder* server_metric_recorder = nullptr);
private:
ServerBuilder* builder_;
};
@ -355,7 +364,6 @@ class ServerBuilder {
private:
friend class grpc::testing::ServerBuilderPluginTest;
friend class grpc::experimental::OrcaServerInterceptorFactory;
struct SyncServerSettings {
SyncServerSettings()
@ -406,14 +414,12 @@ class ServerBuilder {
std::vector<
std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>>
interceptor_creators_;
std::vector<
std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>>
internal_interceptor_creators_;
std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
acceptors_;
grpc_server_config_fetcher* server_config_fetcher_ = nullptr;
std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
authorization_provider_;
experimental::ServerMetricRecorder* server_metric_recorder_ = nullptr;
};
} // namespace grpc

@ -116,8 +116,8 @@ class DefaultReactorTestPeer;
} // namespace testing
namespace experimental {
class OrcaServerInterceptor;
class CallMetricRecorder;
class ServerMetricRecorder;
} // namespace experimental
/// Base class of ServerContext.
@ -404,7 +404,6 @@ class ServerContextBase {
friend class grpc::ClientContext;
friend class grpc::GenericServerContext;
friend class grpc::GenericCallbackServerContext;
friend class grpc::experimental::OrcaServerInterceptor;
/// Prevent copying.
ServerContextBase(const ServerContextBase&);
@ -418,7 +417,13 @@ class ServerContextBase {
/// Return the tag queued by BeginCompletionOp()
grpc::internal::CompletionQueueTag* GetCompletionOpTag();
void set_call(grpc_call* call) { call_.call = call; }
void set_call(grpc_call* call, bool call_metric_recording_enabled,
experimental::ServerMetricRecorder* server_metric_recorder) {
call_.call = call;
if (call_metric_recording_enabled) {
CreateCallMetricRecorder(server_metric_recorder);
}
}
void BindDeadlineAndMetadata(gpr_timespec deadline, grpc_metadata_array* arr);
@ -445,7 +450,10 @@ class ServerContextBase {
}
}
void CreateCallMetricRecorder();
// This should be called only once and only when call metric recording is
// enabled.
void CreateCallMetricRecorder(
experimental::ServerMetricRecorder* server_metric_recorder = nullptr);
struct CallWrapper {
~CallWrapper();

@ -54,6 +54,7 @@ class CallbackGenericService;
namespace experimental {
class ServerInterceptorFactoryInterface;
class ServerMetricRecorder;
} // namespace experimental
class ServerInterface : public internal::CallHook {
@ -350,6 +351,13 @@ class ServerInterface : public internal::CallHook {
return nullptr;
}
// Whether per-call load reporting is enabled.
virtual bool call_metric_recording_enabled() const = 0;
// Interface to read or update server-wide metrics. Returns null when not set.
virtual experimental::ServerMetricRecorder* server_metric_recorder()
const = 0;
// A method to get the callbackable completion queue associated with this
// server. If the return value is nullptr, this server doesn't support
// callback operations.

3
package.xml generated

@ -97,6 +97,9 @@
<file baseinstalldir="/" name="include/grpc/support/thd_id.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/time.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/workaround_list.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/backend_metrics/backend_metric_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/backend_metrics/backend_metric_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/backend_metrics/backend_metric_provider.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/census/grpc_context.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/channel_idle/channel_idle_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/channel_idle/channel_idle_filter.h" role="src" />

@ -3643,6 +3643,14 @@ grpc_cc_library(
deps = ["//:gpr_platform"],
)
grpc_cc_library(
name = "grpc_backend_metric_provider",
hdrs = [
"ext/filters/backend_metrics/backend_metric_provider.h",
],
language = "c++",
)
grpc_cc_library(
name = "grpc_lb_policy_rls",
srcs = [
@ -4673,6 +4681,41 @@ grpc_cc_library(
alwayslink = 1,
)
grpc_cc_library(
name = "grpc_backend_metric_filter",
srcs = [
"ext/filters/backend_metrics/backend_metric_filter.cc",
],
hdrs = [
"ext/filters/backend_metrics/backend_metric_filter.h",
],
external_deps = [
"absl/status:statusor",
"absl/strings",
"absl/types:optional",
"upb_lib",
],
language = "c++",
deps = [
"arena_promise",
"channel_args",
"channel_fwd",
"channel_stack_type",
"context",
"grpc_backend_metric_data",
"grpc_backend_metric_provider",
"map",
"slice",
"//:channel_stack_builder",
"//:config",
"//:gpr",
"//:gpr_platform",
"//:grpc_base",
"//:grpc_trace",
"//:xds_orca_upb",
],
)
grpc_cc_library(
name = "polling_resolver",
srcs = [

@ -0,0 +1,148 @@
// Copyright 2023 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 "src/core/ext/filters/backend_metrics/backend_metric_filter.h"
#include <inttypes.h>
#include <limits.h>
#include <stddef.h>
#include <functional>
#include <map>
#include <memory>
#include <utility>
#include "absl/strings/string_view.h"
#include "upb/upb.h"
#include "upb/upb.hpp"
#include "xds/data/orca/v3/orca_load_report.upb.h"
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/channel/context.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/map.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/surface/channel_stack_type.h"
#include "src/core/lib/transport/metadata_batch.h"
namespace grpc_core {
TraceFlag grpc_backend_metric_filter_trace(false, "backend_metric_filter");
absl::optional<std::string> BackendMetricFilter::MaybeSerializeBackendMetrics(
BackendMetricProvider* provider) const {
if (provider == nullptr) return absl::nullopt;
BackendMetricData data = provider->GetBackendMetricData();
upb::Arena arena;
xds_data_orca_v3_OrcaLoadReport* response =
xds_data_orca_v3_OrcaLoadReport_new(arena.ptr());
bool has_data = false;
if (data.cpu_utilization != -1) {
xds_data_orca_v3_OrcaLoadReport_set_cpu_utilization(response,
data.cpu_utilization);
has_data = true;
}
if (data.mem_utilization != -1) {
xds_data_orca_v3_OrcaLoadReport_set_mem_utilization(response,
data.mem_utilization);
has_data = true;
}
if (data.qps != -1) {
xds_data_orca_v3_OrcaLoadReport_set_rps_fractional(response, data.qps);
has_data = true;
}
for (const auto& p : data.request_cost) {
xds_data_orca_v3_OrcaLoadReport_request_cost_set(
response,
upb_StringView_FromDataAndSize(p.first.data(), p.first.size()),
p.second, arena.ptr());
has_data = true;
}
for (const auto& p : data.utilization) {
xds_data_orca_v3_OrcaLoadReport_utilization_set(
response,
upb_StringView_FromDataAndSize(p.first.data(), p.first.size()),
p.second, arena.ptr());
has_data = true;
}
if (!has_data) {
return absl::nullopt;
}
size_t len;
char* buf =
xds_data_orca_v3_OrcaLoadReport_serialize(response, arena.ptr(), &len);
return std::string(buf, len);
}
const grpc_channel_filter BackendMetricFilter::kFilter =
MakePromiseBasedFilter<BackendMetricFilter, FilterEndpoint::kServer>(
"backend_metric");
absl::StatusOr<BackendMetricFilter> BackendMetricFilter::Create(
const ChannelArgs&, ChannelFilter::Args) {
return BackendMetricFilter();
}
ArenaPromise<ServerMetadataHandle> BackendMetricFilter::MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) {
return ArenaPromise<ServerMetadataHandle>(Map(
next_promise_factory(std::move(call_args)),
[this](ServerMetadataHandle trailing_metadata) {
auto* ctx = &GetContext<
grpc_call_context_element>()[GRPC_CONTEXT_BACKEND_METRIC_PROVIDER];
if (ctx == nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_filter_trace)) {
gpr_log(GPR_INFO, "[%p] No BackendMetricProvider.", this);
}
return trailing_metadata;
}
absl::optional<std::string> serialized = MaybeSerializeBackendMetrics(
reinterpret_cast<BackendMetricProvider*>(ctx->value));
if (serialized.has_value() && !serialized->empty()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_filter_trace)) {
gpr_log(GPR_INFO,
"[%p] Backend metrics serialized. size: %" PRIuPTR, this,
serialized->size());
}
trailing_metadata->Set(
EndpointLoadMetricsBinMetadata(),
Slice::FromCopiedString(std::move(*serialized)));
} else if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_filter_trace)) {
gpr_log(GPR_INFO, "[%p] No backend metrics.", this);
}
return trailing_metadata;
}));
}
void RegisterBackendMetricFilter(CoreConfiguration::Builder* builder) {
builder->channel_init()->RegisterStage(
GRPC_SERVER_CHANNEL, INT_MAX, [](ChannelStackBuilder* builder) {
if (builder->channel_args().Contains(
GRPC_ARG_SERVER_CALL_METRIC_RECORDING)) {
builder->PrependFilter(&BackendMetricFilter::kFilter);
}
return true;
});
}
} // namespace grpc_core

@ -0,0 +1,56 @@
/*
*
* Copyright 2023 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_SRC_CORE_EXT_FILTERS_BACKEND_METRICS_BACKEND_METRIC_FILTER_H
#define GRPC_SRC_CORE_EXT_FILTERS_BACKEND_METRICS_BACKEND_METRIC_FILTER_H
#include <grpc/support/port_platform.h>
#include <string>
#include "absl/status/statusor.h"
#include "absl/types/optional.h"
#include "src/core/ext/filters/backend_metrics/backend_metric_provider.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_fwd.h"
#include "src/core/lib/channel/promise_based_filter.h"
#include "src/core/lib/promise/arena_promise.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
class BackendMetricFilter : public ChannelFilter {
public:
static const grpc_channel_filter kFilter;
static absl::StatusOr<BackendMetricFilter> Create(const ChannelArgs& args,
ChannelFilter::Args);
// Construct a promise for one call.
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
private:
absl::optional<std::string> MaybeSerializeBackendMetrics(
BackendMetricProvider* provider) const;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_FILTERS_BACKEND_METRICS_BACKEND_METRIC_FILTER_H

@ -0,0 +1,33 @@
/*
*
* Copyright 2023 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_SRC_CORE_EXT_FILTERS_BACKEND_METRICS_BACKEND_METRIC_PROVIDER_H
#define GRPC_SRC_CORE_EXT_FILTERS_BACKEND_METRICS_BACKEND_METRIC_PROVIDER_H
namespace grpc_core {
struct BackendMetricData;
class BackendMetricProvider {
public:
virtual ~BackendMetricProvider() = default;
virtual BackendMetricData GetBackendMetricData() = 0;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_FILTERS_BACKEND_METRICS_BACKEND_METRIC_PROVIDER_H

@ -45,6 +45,10 @@ typedef enum {
/// Holds a pointer to ServiceConfigCallData associated with this call.
GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA,
/// Holds a pointer to BackendMetricProvider associated with this call on
/// the server.
GRPC_CONTEXT_BACKEND_METRIC_PROVIDER,
GRPC_CONTEXT_COUNT
} grpc_context_index;

@ -50,6 +50,7 @@ extern void RegisterServiceConfigChannelArgFilter(
extern void RegisterExtraFilters(CoreConfiguration::Builder* builder);
extern void RegisterResourceQuota(CoreConfiguration::Builder* builder);
extern void FaultInjectionFilterRegister(CoreConfiguration::Builder* builder);
extern void RegisterBackendMetricFilter(CoreConfiguration::Builder* builder);
extern void RegisterNativeDnsResolver(CoreConfiguration::Builder* builder);
extern void RegisterAresDnsResolver(CoreConfiguration::Builder* builder);
extern void RegisterSockaddrResolver(CoreConfiguration::Builder* builder);
@ -110,6 +111,7 @@ void BuildCoreConfiguration(CoreConfiguration::Builder* builder) {
#endif // !GRPC_NO_RLS
// Run last so it gets a consistent location.
// TODO(ctiller): Is this actually necessary?
RegisterBackendMetricFilter(builder);
RegisterSecurityFilters(builder);
RegisterExtraFilters(builder);
RegisterBuiltins(builder);

@ -0,0 +1,311 @@
//
// Copyright 2023 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/cpp/server/backend_metric_recorder.h"
#include <inttypes.h>
#include <functional>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <grpc/support/log.h>
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/ext/server_metric_recorder.h>
#include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h"
#include "src/core/lib/debug/trace.h"
using grpc_core::BackendMetricData;
namespace {
// All utilization values must be in [0, 1].
bool IsUtilizationValid(double utilization) {
return utilization >= 0.0 && utilization <= 1.0;
}
// QPS must be in [0, infy).
bool IsQpsValid(double qps) { return qps >= 0.0; }
grpc_core::TraceFlag grpc_backend_metric_trace(false, "backend_metric");
} // namespace
namespace grpc {
namespace experimental {
std::unique_ptr<ServerMetricRecorder> ServerMetricRecorder::Create() {
return std::unique_ptr<ServerMetricRecorder>(new ServerMetricRecorder());
}
ServerMetricRecorder::ServerMetricRecorder()
: metric_state_(std::make_shared<const BackendMetricDataState>()) {}
void ServerMetricRecorder::UpdateBackendMetricDataState(
std::function<void(BackendMetricData*)> updater) {
internal::MutexLock lock(&mu_);
auto new_state = std::make_shared<BackendMetricDataState>(*metric_state_);
updater(&new_state->data);
++new_state->sequence_number;
metric_state_ = std::move(new_state);
}
void ServerMetricRecorder::SetCpuUtilization(double value) {
if (!IsUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] CPU utilization rejected: %f", this, value);
}
return;
}
UpdateBackendMetricDataState(
[value](BackendMetricData* data) { data->cpu_utilization = value; });
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] CPU utilization set: %f", this, value);
}
}
void ServerMetricRecorder::SetMemoryUtilization(double value) {
if (!IsUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Mem utilization rejected: %f", this, value);
}
return;
}
UpdateBackendMetricDataState(
[value](BackendMetricData* data) { data->mem_utilization = value; });
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Mem utilization set: %f", this, value);
}
}
void ServerMetricRecorder::SetQps(double value) {
if (!IsQpsValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] QPS rejected: %f", this, value);
}
return;
}
UpdateBackendMetricDataState(
[value](BackendMetricData* data) { data->qps = value; });
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] QPS set: %f", this, value);
}
}
void ServerMetricRecorder::SetNamedUtilization(string_ref name, double value) {
if (!IsUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Named utilization rejected: %f name: %s", this,
value, std::string(name.data(), name.size()).c_str());
}
return;
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Named utilization set: %f name: %s", this, value,
std::string(name.data(), name.size()).c_str());
}
UpdateBackendMetricDataState([name, value](BackendMetricData* data) {
data->utilization[absl::string_view(name.data(), name.size())] = value;
});
}
void ServerMetricRecorder::SetAllNamedUtilization(
std::map<string_ref, double> named_utilization) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] All named utilization updated. size: %" PRIuPTR,
this, named_utilization.size());
}
UpdateBackendMetricDataState(
[utilization = std::move(named_utilization)](BackendMetricData* data) {
data->utilization.clear();
for (const auto& u : utilization) {
data->utilization[absl::string_view(u.first.data(), u.first.size())] =
u.second;
}
});
}
void ServerMetricRecorder::ClearCpuUtilization() {
UpdateBackendMetricDataState(
[](BackendMetricData* data) { data->cpu_utilization = -1; });
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] CPU utilization cleared.", this);
}
}
void ServerMetricRecorder::ClearMemoryUtilization() {
UpdateBackendMetricDataState(
[](BackendMetricData* data) { data->mem_utilization = -1; });
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Mem utilization cleared.", this);
}
}
void ServerMetricRecorder::ClearQps() {
UpdateBackendMetricDataState([](BackendMetricData* data) { data->qps = -1; });
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] QPS utilization cleared.", this);
}
}
void ServerMetricRecorder::ClearNamedUtilization(string_ref name) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Named utilization cleared. name: %s", this,
std::string(name.data(), name.size()).c_str());
}
UpdateBackendMetricDataState([name](BackendMetricData* data) {
data->utilization.erase(absl::string_view(name.data(), name.size()));
});
}
grpc_core::BackendMetricData ServerMetricRecorder::GetMetrics() const {
auto result = GetMetricsIfChanged();
return result->data;
}
std::shared_ptr<const ServerMetricRecorder::BackendMetricDataState>
ServerMetricRecorder::GetMetricsIfChanged() const {
std::shared_ptr<const BackendMetricDataState> result;
{
internal::MutexLock lock(&mu_);
result = metric_state_;
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
const auto& data = result->data;
gpr_log(GPR_INFO,
"[%p] GetMetrics() returned: seq:%" PRIu64
" cpu:%f mem:%f qps:%f utilization size: %" PRIuPTR,
this, result->sequence_number, data.cpu_utilization,
data.mem_utilization, data.qps, data.utilization.size());
}
return result;
}
} // namespace experimental
experimental::CallMetricRecorder&
BackendMetricState::RecordCpuUtilizationMetric(double value) {
if (!IsUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] CPU utilization value rejected: %f", this, value);
}
return *this;
}
cpu_utilization_.store(value, std::memory_order_relaxed);
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] CPU utilization recorded: %f", this, value);
}
return *this;
}
experimental::CallMetricRecorder&
BackendMetricState::RecordMemoryUtilizationMetric(double value) {
if (!IsUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Mem utilization value rejected: %f", this, value);
}
return *this;
}
mem_utilization_.store(value, std::memory_order_relaxed);
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Mem utilization recorded: %f", this, value);
}
return *this;
}
experimental::CallMetricRecorder& BackendMetricState::RecordQpsMetric(
double value) {
if (!IsQpsValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] QPS value rejected: %f", this, value);
}
return *this;
}
qps_.store(value, std::memory_order_relaxed);
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] QPS recorded: %f", this, value);
}
return *this;
}
experimental::CallMetricRecorder& BackendMetricState::RecordUtilizationMetric(
string_ref name, double value) {
if (!IsUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Utilization value rejected: %s %f", this,
std::string(name.data(), name.length()).c_str(), value);
}
return *this;
}
internal::MutexLock lock(&mu_);
absl::string_view name_sv(name.data(), name.length());
utilization_[name_sv] = value;
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Utilization recorded: %s %f", this,
std::string(name_sv).c_str(), value);
}
return *this;
}
experimental::CallMetricRecorder& BackendMetricState::RecordRequestCostMetric(
string_ref name, double value) {
internal::MutexLock lock(&mu_);
absl::string_view name_sv(name.data(), name.length());
request_cost_[name_sv] = value;
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] Request cost recorded: %s %f", this,
std::string(name_sv).c_str(), value);
}
return *this;
}
BackendMetricData BackendMetricState::GetBackendMetricData() {
// Merge metrics from the ServerMetricRecorder first since metrics recorded
// to CallMetricRecorder takes a higher precedence.
BackendMetricData data;
if (server_metric_recorder_ != nullptr) {
data = server_metric_recorder_->GetMetrics();
}
// Only overwrite if the value is set i.e. in the valid range.
const double cpu = cpu_utilization_.load(std::memory_order_relaxed);
if (IsUtilizationValid(cpu)) {
data.cpu_utilization = cpu;
}
const double mem = mem_utilization_.load(std::memory_order_relaxed);
if (IsUtilizationValid(mem)) {
data.mem_utilization = mem;
}
const double qps = qps_.load(std::memory_order_relaxed);
if (IsQpsValid(qps)) {
data.qps = qps;
}
{
internal::MutexLock lock(&mu_);
data.utilization = std::move(utilization_);
data.request_cost = std::move(request_cost_);
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO,
"[%p] Backend metric data returned: cpu:%f mem:%f qps:%f "
"utilization size:%" PRIuPTR " request_cost size:%" PRIuPTR,
this, data.cpu_utilization, data.mem_utilization, data.qps,
data.utilization.size(), data.request_cost.size());
}
return data;
}
} // namespace grpc

@ -0,0 +1,81 @@
//
//
// Copyright 2023 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_SRC_CPP_SERVER_BACKEND_METRIC_RECORDER_H
#define GRPC_SRC_CPP_SERVER_BACKEND_METRIC_RECORDER_H
#include <stdint.h>
#include <atomic>
#include <map>
#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/ext/server_metric_recorder.h>
#include <grpcpp/impl/sync.h>
#include <grpcpp/support/string_ref.h>
#include "src/core/ext/filters/backend_metrics/backend_metric_provider.h"
#include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h"
namespace grpc {
namespace experimental {
// Backend metrics and an associated update sequence number.
struct ServerMetricRecorder::BackendMetricDataState {
grpc_core::BackendMetricData data;
uint64_t sequence_number = 0;
};
} // namespace experimental
class BackendMetricState : public grpc_core::BackendMetricProvider,
public experimental::CallMetricRecorder {
public:
// `server_metric_recorder` is optional. When set, GetBackendMetricData()
// merges metrics from `server_metric_recorder` with metrics recorded to this.
explicit BackendMetricState(
experimental::ServerMetricRecorder* server_metric_recorder)
: server_metric_recorder_(server_metric_recorder) {}
experimental::CallMetricRecorder& RecordCpuUtilizationMetric(
double value) override;
experimental::CallMetricRecorder& RecordMemoryUtilizationMetric(
double value) override;
experimental::CallMetricRecorder& RecordQpsMetric(double value) override;
experimental::CallMetricRecorder& RecordUtilizationMetric(
string_ref name, double value) override;
experimental::CallMetricRecorder& RecordRequestCostMetric(
string_ref name, double value) override;
// This clears metrics currently recorded. Don't call twice.
grpc_core::BackendMetricData GetBackendMetricData() override;
private:
experimental::ServerMetricRecorder* server_metric_recorder_;
std::atomic<double> cpu_utilization_{-1.0};
std::atomic<double> mem_utilization_{-1.0};
std::atomic<double> qps_{-1.0};
internal::Mutex mu_;
std::map<absl::string_view, double> utilization_ ABSL_GUARDED_BY(mu_);
std::map<absl::string_view, double> request_cost_ ABSL_GUARDED_BY(mu_);
};
} // namespace grpc
#endif // GRPC_SRC_CPP_SERVER_BACKEND_METRIC_RECORDER_H

@ -1,125 +0,0 @@
//
// Copyright 2022 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>
#include <map>
#include <string>
#include <utility>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "upb/upb.h"
#include "upb/upb.hpp"
#include "xds/data/orca/v3/orca_load_report.upb.h"
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/impl/sync.h>
#include <grpcpp/support/string_ref.h>
#include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h"
#include "src/core/lib/resource_quota/arena.h"
namespace grpc {
namespace experimental {
CallMetricRecorder::CallMetricRecorder(grpc_core::Arena* arena)
: backend_metric_data_(arena->New<grpc_core::BackendMetricData>()) {}
CallMetricRecorder::~CallMetricRecorder() {
backend_metric_data_->~BackendMetricData();
}
CallMetricRecorder& CallMetricRecorder::RecordCpuUtilizationMetric(
double value) {
internal::MutexLock lock(&mu_);
backend_metric_data_->cpu_utilization = value;
return *this;
}
CallMetricRecorder& CallMetricRecorder::RecordMemoryUtilizationMetric(
double value) {
internal::MutexLock lock(&mu_);
backend_metric_data_->mem_utilization = value;
return *this;
}
CallMetricRecorder& CallMetricRecorder::RecordQpsMetric(double value) {
internal::MutexLock lock(&mu_);
backend_metric_data_->qps = value;
return *this;
}
CallMetricRecorder& CallMetricRecorder::RecordUtilizationMetric(
grpc::string_ref name, double value) {
internal::MutexLock lock(&mu_);
absl::string_view name_sv(name.data(), name.length());
backend_metric_data_->utilization[name_sv] = value;
return *this;
}
CallMetricRecorder& CallMetricRecorder::RecordRequestCostMetric(
grpc::string_ref name, double value) {
internal::MutexLock lock(&mu_);
absl::string_view name_sv(name.data(), name.length());
backend_metric_data_->request_cost[name_sv] = value;
return *this;
}
absl::optional<std::string> CallMetricRecorder::CreateSerializedReport() {
upb::Arena arena;
internal::MutexLock lock(&mu_);
bool has_data = backend_metric_data_->cpu_utilization != -1 ||
backend_metric_data_->mem_utilization != -1 ||
!backend_metric_data_->utilization.empty() ||
!backend_metric_data_->request_cost.empty();
if (!has_data) {
return absl::nullopt;
}
xds_data_orca_v3_OrcaLoadReport* response =
xds_data_orca_v3_OrcaLoadReport_new(arena.ptr());
if (backend_metric_data_->cpu_utilization != -1) {
xds_data_orca_v3_OrcaLoadReport_set_cpu_utilization(
response, backend_metric_data_->cpu_utilization);
}
if (backend_metric_data_->mem_utilization != -1) {
xds_data_orca_v3_OrcaLoadReport_set_mem_utilization(
response, backend_metric_data_->mem_utilization);
}
if (backend_metric_data_->qps != -1) {
xds_data_orca_v3_OrcaLoadReport_set_rps_fractional(
response, backend_metric_data_->qps);
}
for (const auto& p : backend_metric_data_->request_cost) {
xds_data_orca_v3_OrcaLoadReport_request_cost_set(
response,
upb_StringView_FromDataAndSize(p.first.data(), p.first.size()),
p.second, arena.ptr());
}
for (const auto& p : backend_metric_data_->utilization) {
xds_data_orca_v3_OrcaLoadReport_utilization_set(
response,
upb_StringView_FromDataAndSize(p.first.data(), p.first.size()),
p.second, arena.ptr());
}
size_t buf_length;
char* buf = xds_data_orca_v3_OrcaLoadReport_serialize(response, arena.ptr(),
&buf_length);
return std::string(buf, buf_length);
}
} // namespace experimental
} // namespace grpc

@ -1,76 +0,0 @@
//
// Copyright 2022 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/cpp/server/orca/orca_interceptor.h"
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
#include "src/core/lib/transport/metadata_batch.h"
namespace grpc {
namespace experimental {
void OrcaServerInterceptor::Intercept(InterceptorBatchMethods* methods) {
if (methods->QueryInterceptionHookPoint(
InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) {
auto context = info_->server_context();
context->CreateCallMetricRecorder();
} else if (methods->QueryInterceptionHookPoint(
InterceptionHookPoints::PRE_SEND_STATUS)) {
auto trailers = methods->GetSendTrailingMetadata();
if (trailers != nullptr) {
auto context = info_->server_context();
auto* recorder = context->call_metric_recorder_;
auto serialized = recorder->CreateSerializedReport();
if (serialized.has_value() && !serialized->empty()) {
std::string key =
std::string(grpc_core::EndpointLoadMetricsBinMetadata::key());
trailers->emplace(
std::make_pair(std::move(key), std::move(serialized.value())));
}
}
}
methods->Proceed();
}
Interceptor* OrcaServerInterceptorFactory::CreateServerInterceptor(
ServerRpcInfo* info) {
return new OrcaServerInterceptor(info);
}
void OrcaServerInterceptorFactory::Register(grpc::ServerBuilder* builder) {
builder->internal_interceptor_creators_.push_back(
std::make_unique<OrcaServerInterceptorFactory>());
}
void EnableCallMetricRecording(grpc::ServerBuilder* builder) {
OrcaServerInterceptorFactory::Register(builder);
}
} // namespace experimental
} // namespace grpc

@ -1,49 +0,0 @@
//
// Copyright 2022 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_SRC_CPP_SERVER_ORCA_ORCA_INTERCEPTOR_H
#define GRPC_SRC_CPP_SERVER_ORCA_ORCA_INTERCEPTOR_H
#include <grpcpp/support/interceptor.h>
#include <grpcpp/support/server_interceptor.h>
namespace grpc {
class ServerBuilder;
namespace experimental {
class ServerRpcInfo;
class OrcaServerInterceptor : public Interceptor {
public:
explicit OrcaServerInterceptor(ServerRpcInfo* info) : info_(info) {}
void Intercept(InterceptorBatchMethods* methods) override;
private:
ServerRpcInfo* info_;
};
class OrcaServerInterceptorFactory : public ServerInterceptorFactoryInterface {
public:
static void Register(ServerBuilder* builder);
Interceptor* CreateServerInterceptor(ServerRpcInfo* info) override;
};
} // namespace experimental
} // namespace grpc
#endif // GRPC_SRC_CPP_SERVER_ORCA_ORCA_INTERCEPTOR_H

@ -15,13 +15,14 @@
//
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include "google/protobuf/duration.upb.h"
@ -33,6 +34,7 @@
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/log.h>
#include <grpcpp/ext/orca_service.h>
#include <grpcpp/ext/server_metric_recorder.h>
#include <grpcpp/impl/rpc_method.h>
#include <grpcpp/impl/rpc_service_method.h>
#include <grpcpp/impl/server_callback_handlers.h>
@ -43,12 +45,14 @@
#include <grpcpp/support/slice.h>
#include <grpcpp/support/status.h>
#include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h"
#include "src/core/lib/event_engine/default_event_engine.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/cpp/server/backend_metric_recorder.h"
namespace grpc {
namespace experimental {
@ -166,8 +170,11 @@ class OrcaService::Reactor : public ServerWriteReactor<ByteBuffer>,
// OrcaService
//
OrcaService::OrcaService(OrcaService::Options options)
: min_report_duration_(options.min_report_duration) {
OrcaService::OrcaService(ServerMetricRecorder* const server_metric_recorder,
Options options)
: server_metric_recorder_(server_metric_recorder),
min_report_duration_(options.min_report_duration) {
GPR_ASSERT(server_metric_recorder_ != nullptr);
AddMethod(new internal::RpcServiceMethod(
"/xds.service.orca.v3.OpenRcaService/StreamCoreMetrics",
internal::RpcMethod::SERVER_STREAMING, /*handler=*/nullptr));
@ -178,88 +185,38 @@ OrcaService::OrcaService(OrcaService::Options options)
}));
}
void OrcaService::SetCpuUtilization(double cpu_utilization) {
grpc::internal::MutexLock lock(&mu_);
cpu_utilization_ = cpu_utilization;
response_slice_.reset();
}
void OrcaService::DeleteCpuUtilization() {
grpc::internal::MutexLock lock(&mu_);
cpu_utilization_ = -1;
response_slice_.reset();
}
void OrcaService::SetMemoryUtilization(double memory_utilization) {
grpc::internal::MutexLock lock(&mu_);
memory_utilization_ = memory_utilization;
response_slice_.reset();
}
void OrcaService::DeleteMemoryUtilization() {
grpc::internal::MutexLock lock(&mu_);
memory_utilization_ = -1;
response_slice_.reset();
}
void OrcaService::SetQps(double qps) {
grpc::internal::MutexLock lock(&mu_);
qps_ = qps;
response_slice_.reset();
}
void OrcaService::DeleteQps() {
grpc::internal::MutexLock lock(&mu_);
qps_ = -1;
response_slice_.reset();
}
void OrcaService::SetNamedUtilization(std::string name, double utilization) {
grpc::internal::MutexLock lock(&mu_);
named_utilization_[std::move(name)] = utilization;
response_slice_.reset();
}
void OrcaService::DeleteNamedUtilization(const std::string& name) {
grpc::internal::MutexLock lock(&mu_);
named_utilization_.erase(name);
response_slice_.reset();
}
void OrcaService::SetAllNamedUtilization(
std::map<std::string, double> named_utilization) {
grpc::internal::MutexLock lock(&mu_);
named_utilization_ = std::move(named_utilization);
response_slice_.reset();
}
Slice OrcaService::GetOrCreateSerializedResponse() {
grpc::internal::MutexLock lock(&mu_);
if (!response_slice_.has_value()) {
std::shared_ptr<const ServerMetricRecorder::BackendMetricDataState> result =
server_metric_recorder_->GetMetricsIfChanged();
if (!response_slice_seq_.has_value() ||
*response_slice_seq_ != result->sequence_number) {
const auto& data = result->data;
upb::Arena arena;
xds_data_orca_v3_OrcaLoadReport* response =
xds_data_orca_v3_OrcaLoadReport_new(arena.ptr());
if (cpu_utilization_ != -1) {
if (data.cpu_utilization != -1) {
xds_data_orca_v3_OrcaLoadReport_set_cpu_utilization(response,
cpu_utilization_);
data.cpu_utilization);
}
if (memory_utilization_ != -1) {
if (data.mem_utilization != -1) {
xds_data_orca_v3_OrcaLoadReport_set_mem_utilization(response,
memory_utilization_);
data.mem_utilization);
}
if (qps_ != -1) {
xds_data_orca_v3_OrcaLoadReport_set_rps_fractional(response, qps_);
if (data.qps != -1) {
xds_data_orca_v3_OrcaLoadReport_set_rps_fractional(response, data.qps);
}
for (const auto& p : named_utilization_) {
for (const auto& u : data.utilization) {
xds_data_orca_v3_OrcaLoadReport_utilization_set(
response,
upb_StringView_FromDataAndSize(p.first.data(), p.first.size()),
p.second, arena.ptr());
upb_StringView_FromDataAndSize(u.first.data(), u.first.size()),
u.second, arena.ptr());
}
size_t buf_length;
char* buf = xds_data_orca_v3_OrcaLoadReport_serialize(response, arena.ptr(),
&buf_length);
response_slice_.emplace(buf, buf_length);
response_slice_seq_ = result->sequence_number;
}
return Slice(*response_slice_);
}

@ -21,7 +21,6 @@
#include <string.h>
#include <algorithm>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
@ -158,6 +157,13 @@ void ServerBuilder::experimental_type::SetAuthorizationPolicyProvider(
builder_->authorization_provider_ = std::move(provider);
}
void ServerBuilder::experimental_type::EnableCallMetricRecording(
experimental::ServerMetricRecorder* server_metric_recorder) {
builder_->AddChannelArgument(GRPC_ARG_SERVER_CALL_METRIC_RECORDING, 1);
GPR_ASSERT(builder_->server_metric_recorder_ == nullptr);
builder_->server_metric_recorder_ = server_metric_recorder;
}
ServerBuilder& ServerBuilder::SetOption(
std::unique_ptr<ServerBuilderOption> option) {
options_.push_back(std::move(option));
@ -355,18 +361,11 @@ std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
gpr_log(GPR_INFO, "Callback server.");
}
// Merge the application and internal interceptors together.
// Internal interceptors go first.
auto creators = std::move(internal_interceptor_creators_);
creators.insert(creators.end(),
std::make_move_iterator(interceptor_creators_.begin()),
std::make_move_iterator(interceptor_creators_.end()));
std::unique_ptr<grpc::Server> server(new grpc::Server(
&args, sync_server_cqs, sync_server_settings_.min_pollers,
sync_server_settings_.max_pollers, sync_server_settings_.cq_timeout_msec,
std::move(acceptors_), server_config_fetcher_, resource_quota_,
std::move(creators)));
std::move(interceptor_creators_), server_metric_recorder_));
ServerInitializer* initializer = server->initializer();

@ -170,7 +170,8 @@ bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag,
}
return true;
}
context_->set_call(call_);
context_->set_call(call_, server_->call_metric_recording_enabled(),
server_->server_metric_recorder());
context_->cq_ = call_cq_;
if (call_wrapper_.call() == nullptr) {
// Fill it since it is empty.
@ -408,7 +409,8 @@ class Server::SyncRequest final : public grpc::internal::CompletionQueueTag {
call_, server_, &cq_, server_->max_receive_message_size(),
ctx_->ctx.set_server_rpc_info(method_->name(), method_->method_type(),
server_->interceptor_creators_));
ctx_->ctx.set_call(call_);
ctx_->ctx.set_call(call_, server_->call_metric_recording_enabled(),
server_->server_metric_recorder());
ctx_->ctx.cq_ = &cq_;
request_metadata_.count = 0;
@ -636,7 +638,9 @@ class Server::CallbackRequest final
}
// Bind the call, deadline, and metadata from what we got
req_->ctx_->set_call(req_->call_);
req_->ctx_->set_call(req_->call_,
req_->server_->call_metric_recording_enabled(),
req_->server_->server_metric_recorder());
req_->ctx_->cq_ = req_->cq_;
req_->ctx_->BindDeadlineAndMetadata(req_->deadline_,
&req_->request_metadata_);
@ -878,7 +882,8 @@ Server::Server(
grpc_resource_quota* server_rq,
std::vector<
std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>>
interceptor_creators)
interceptor_creators,
experimental::ServerMetricRecorder* server_metric_recorder)
: acceptors_(std::move(acceptors)),
interceptor_creators_(std::move(interceptor_creators)),
max_receive_message_size_(INT_MIN),
@ -888,7 +893,8 @@ Server::Server(
shutdown_notified_(false),
server_(nullptr),
server_initializer_(new ServerInitializer(this)),
health_check_service_disabled_(false) {
health_check_service_disabled_(false),
server_metric_recorder_(server_metric_recorder) {
gpr_once_init(&grpc::g_once_init_callbacks, grpc::InitGlobalCallbacks);
global_callbacks_ = grpc::g_callbacks;
global_callbacks_->UpdateArguments(args);
@ -935,6 +941,10 @@ Server::Server(
strcmp(channel_args.args[i].key, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH)) {
max_receive_message_size_ = channel_args.args[i].value.integer;
}
if (0 == strcmp(channel_args.args[i].key,
GRPC_ARG_SERVER_CALL_METRIC_RECORDING)) {
call_metric_recording_enabled_ = channel_args.args[i].value.integer;
}
}
server_ = grpc_server_create(&channel_args, nullptr);
grpc_server_set_config_fetcher(server_, server_config_fetcher);

@ -41,6 +41,7 @@
#include <grpc/support/time.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/ext/server_metric_recorder.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/call_op_set.h>
#include <grpcpp/impl/call_op_set_interface.h>
@ -54,11 +55,13 @@
#include <grpcpp/support/server_interceptor.h>
#include <grpcpp/support/string_ref.h>
#include "src/core/lib/channel/context.h"
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/surface/call.h"
#include "src/cpp/server/backend_metric_recorder.h"
namespace grpc {
@ -398,10 +401,15 @@ void ServerContextBase::SetLoadReportingCosts(
}
}
void ServerContextBase::CreateCallMetricRecorder() {
void ServerContextBase::CreateCallMetricRecorder(
experimental::ServerMetricRecorder* server_metric_recorder) {
GPR_ASSERT(call_metric_recorder_ == nullptr);
grpc_core::Arena* arena = grpc_call_get_arena(call_.call);
call_metric_recorder_ = arena->New<experimental::CallMetricRecorder>(arena);
auto* backend_metric_state =
arena->New<BackendMetricState>(server_metric_recorder);
call_metric_recorder_ = backend_metric_state;
grpc_call_context_set(call_.call, GRPC_CONTEXT_BACKEND_METRIC_PROVIDER,
backend_metric_state, nullptr);
}
grpc::string_ref ServerContextBase::ExperimentalGetAuthority() const {

@ -15,6 +15,7 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!!
CORE_SOURCE_FILES = [
'src/core/ext/filters/backend_metrics/backend_metric_filter.cc',
'src/core/ext/filters/census/grpc_context.cc',
'src/core/ext/filters/channel_idle/channel_idle_filter.cc',
'src/core/ext/filters/channel_idle/idle_filter_state.cc',

@ -495,7 +495,8 @@ grpc_cc_test(
"//:gpr",
"//:grpc",
"//:grpc++",
"//:grpcpp_orca_interceptor",
"//:grpcpp_backend_metric_recorder",
"//:grpcpp_call_metric_recorder",
"//:grpcpp_orca_service",
"//src/core:channel_args",
"//src/proto/grpc/testing:echo_messages_proto",
@ -946,6 +947,8 @@ grpc_cc_test(
],
deps = [
"//:grpc++",
"//:grpcpp_backend_metric_recorder",
"//:grpcpp_call_metric_recorder",
"//:grpcpp_orca_service",
"//src/proto/grpc/testing/xds/v3:orca_service_proto",
"//test/core/util:grpc_test_util",

@ -41,6 +41,7 @@
#include <grpcpp/create_channel.h>
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/ext/orca_service.h>
#include <grpcpp/ext/server_metric_recorder.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/sync.h>
#include <grpcpp/server.h>
@ -94,44 +95,29 @@ class MyTestServiceImpl : public TestServiceImpl {
++request_count_;
}
AddClient(context->peer());
absl::optional<xds::data::orca::v3::OrcaLoadReport> load_report;
{
grpc_core::MutexLock lock(&load_report_mu_);
load_report = load_report_;
}
if (request->has_param() && request->param().has_backend_metrics()) {
if (!load_report.has_value()) load_report.emplace();
const auto& request_metrics = request->param().backend_metrics();
auto* recorder = context->ExperimentalGetCallMetricRecorder();
EXPECT_NE(recorder, nullptr);
// Do not record when zero since it indicates no test per-call report.
if (request_metrics.cpu_utilization() > 0) {
load_report->set_cpu_utilization(request_metrics.cpu_utilization());
recorder->RecordCpuUtilizationMetric(request_metrics.cpu_utilization());
}
if (request_metrics.mem_utilization() > 0) {
load_report->set_mem_utilization(request_metrics.mem_utilization());
recorder->RecordMemoryUtilizationMetric(
request_metrics.mem_utilization());
}
if (request_metrics.rps_fractional() > 0) {
load_report->set_rps_fractional(request_metrics.rps_fractional());
recorder->RecordQpsMetric(request_metrics.rps_fractional());
}
for (const auto& p : request_metrics.request_cost()) {
(*load_report->mutable_request_cost())[p.first] = p.second;
}
for (const auto& p : request_metrics.utilization()) {
(*load_report->mutable_utilization())[p.first] = p.second;
}
}
if (load_report.has_value()) {
auto* recorder = context->ExperimentalGetCallMetricRecorder();
EXPECT_NE(recorder, nullptr);
recorder->RecordCpuUtilizationMetric(load_report->cpu_utilization())
.RecordMemoryUtilizationMetric(load_report->mem_utilization())
.RecordQpsMetric(load_report->rps_fractional());
for (const auto& p : load_report->request_cost()) {
char* key = static_cast<char*>(
grpc_call_arena_alloc(context->c_call(), p.first.size() + 1));
strncpy(key, p.first.data(), p.first.size());
key[p.first.size()] = '\0';
recorder->RecordRequestCostMetric(key, p.second);
}
for (const auto& p : load_report->utilization()) {
for (const auto& p : request_metrics.utilization()) {
char* key = static_cast<char*>(
grpc_call_arena_alloc(context->c_call(), p.first.size() + 1));
strncpy(key, p.first.data(), p.first.size());
@ -142,7 +128,7 @@ class MyTestServiceImpl : public TestServiceImpl {
return TestServiceImpl::Echo(context, request, response);
}
int request_count() {
size_t request_count() {
grpc_core::MutexLock lock(&mu_);
return request_count_;
}
@ -157,15 +143,6 @@ class MyTestServiceImpl : public TestServiceImpl {
return clients_;
}
// TODO(roth): Once the backend utilization APIs are updated, change
// this to use those instead of manually constructing the data for
// each call.
void SetLoadReport(
absl::optional<xds::data::orca::v3::OrcaLoadReport> load_report) {
grpc_core::MutexLock lock(&load_report_mu_);
load_report_ = std::move(load_report);
}
private:
void AddClient(const std::string& client) {
grpc_core::MutexLock lock(&clients_mu_);
@ -173,14 +150,10 @@ class MyTestServiceImpl : public TestServiceImpl {
}
grpc_core::Mutex mu_;
int request_count_ ABSL_GUARDED_BY(&mu_) = 0;
size_t request_count_ ABSL_GUARDED_BY(&mu_) = 0;
grpc_core::Mutex clients_mu_;
std::set<std::string> clients_ ABSL_GUARDED_BY(&clients_mu_);
grpc_core::Mutex load_report_mu_;
absl::optional<xds::data::orca::v3::OrcaLoadReport> load_report_
ABSL_GUARDED_BY(&load_report_mu_);
};
class FakeResolverResponseGeneratorWrapper {
@ -278,16 +251,6 @@ class ClientLbEnd2endTest : public ::testing::Test {
creds_(new SecureChannelCredentials(
grpc_fake_transport_security_credentials_create())) {}
static void SetUpTestSuite() {
// Make the backup poller poll very frequently in order to pick up
// updates from all the subchannels's FDs.
GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1);
#if TARGET_OS_IPHONE
// Workaround Apple CFStream bug
grpc_core::SetEnv("grpc_cfstream", "0");
#endif
}
void SetUp() override {
grpc_init();
bool localhost_resolves_to_ipv4 = false;
@ -418,14 +381,16 @@ class ClientLbEnd2endTest : public ::testing::Test {
const grpc_core::DebugLocation& debug_location,
const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
std::function<bool(const Status&)> continue_predicate,
int timeout_ms = 15000) {
EchoRequest* request_ptr = nullptr, int timeout_ms = 15000) {
absl::Time deadline = absl::InfiniteFuture();
if (timeout_ms != 0) {
deadline = absl::Now() +
(absl::Milliseconds(timeout_ms) * grpc_test_slowdown_factor());
}
while (true) {
Status status = SendRpc(stub);
Status status =
SendRpc(stub, /*response=*/nullptr, /*timeout_ms=*/1000,
/*wait_for_ready=*/false, /*request=*/request_ptr);
if (!continue_predicate(status)) return;
EXPECT_LE(absl::Now(), deadline)
<< debug_location.file() << ":" << debug_location.line();
@ -437,6 +402,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
const int port_;
std::unique_ptr<Server> server_;
MyTestServiceImpl service_;
std::unique_ptr<experimental::ServerMetricRecorder> server_metric_recorder_;
experimental::OrcaService orca_service_;
std::unique_ptr<std::thread> thread_;
@ -447,7 +413,11 @@ class ClientLbEnd2endTest : public ::testing::Test {
explicit ServerData(int port = 0)
: port_(port > 0 ? port : grpc_pick_unused_port_or_die()),
orca_service_(experimental::OrcaService::Options()) {}
server_metric_recorder_(experimental::ServerMetricRecorder::Create()),
orca_service_(
server_metric_recorder_.get(),
experimental::OrcaService::Options().set_min_report_duration(
absl::Seconds(0.1))) {}
void Start(const std::string& server_host) {
gpr_log(GPR_INFO, "starting server on port %d", port_);
@ -466,12 +436,13 @@ class ClientLbEnd2endTest : public ::testing::Test {
std::ostringstream server_address;
server_address << server_host << ":" << port_;
ServerBuilder builder;
experimental::EnableCallMetricRecording(&builder);
std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials(
grpc_fake_transport_security_server_credentials_create()));
builder.AddListeningPort(server_address.str(), std::move(creds));
builder.RegisterService(&service_);
builder.RegisterService(&orca_service_);
grpc::ServerBuilder::experimental_type(&builder)
.EnableCallMetricRecording(server_metric_recorder_.get());
server_ = builder.BuildAndStart();
grpc_core::MutexLock lock(&mu_);
server_ready_ = true;
@ -2552,8 +2523,12 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricData) {
(*request_cost)["foo"] = 0.8;
(*request_cost)["bar"] = 1.4;
auto* utilization = load_report.mutable_utilization();
(*utilization)["baz"] = 1.1;
(*utilization)["baz"] = 1.0;
(*utilization)["quux"] = 0.9;
// This will be rejected.
(*utilization)["out_of_range_invalid"] = 1.1;
auto expected = load_report;
expected.mutable_utilization()->erase("out_of_range_invalid");
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
@ -2565,19 +2540,19 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricData) {
ASSERT_TRUE(actual.has_value());
// TODO(roth): Change this to use EqualsProto() once that becomes
// available in OSS.
EXPECT_EQ(actual->cpu_utilization(), load_report.cpu_utilization());
EXPECT_EQ(actual->mem_utilization(), load_report.mem_utilization());
EXPECT_EQ(actual->rps_fractional(), load_report.rps_fractional());
EXPECT_EQ(actual->request_cost().size(), load_report.request_cost().size());
EXPECT_EQ(actual->cpu_utilization(), expected.cpu_utilization());
EXPECT_EQ(actual->mem_utilization(), expected.mem_utilization());
EXPECT_EQ(actual->rps_fractional(), expected.rps_fractional());
EXPECT_EQ(actual->request_cost().size(), expected.request_cost().size());
for (const auto& p : actual->request_cost()) {
auto it = load_report.request_cost().find(p.first);
ASSERT_NE(it, load_report.request_cost().end());
auto it = expected.request_cost().find(p.first);
ASSERT_NE(it, expected.request_cost().end());
EXPECT_EQ(it->second, p.second);
}
EXPECT_EQ(actual->utilization().size(), load_report.utilization().size());
EXPECT_EQ(actual->utilization().size(), expected.utilization().size());
for (const auto& p : actual->utilization()) {
auto it = load_report.utilization().find(p.first);
ASSERT_NE(it, load_report.utilization().end());
auto it = expected.utilization().find(p.first);
ASSERT_NE(it, expected.utilization().end());
EXPECT_EQ(it->second, p.second);
}
}
@ -2736,10 +2711,10 @@ TEST_F(OobBackendMetricTest, Basic) {
StartServers(1);
// Set initial backend metric data on server.
constexpr char kMetricName[] = "foo";
servers_[0]->orca_service_.SetCpuUtilization(0.1);
servers_[0]->orca_service_.SetMemoryUtilization(0.2);
servers_[0]->orca_service_.SetQps(0.3);
servers_[0]->orca_service_.SetNamedUtilization(kMetricName, 0.4);
servers_[0]->server_metric_recorder_->SetCpuUtilization(0.1);
servers_[0]->server_metric_recorder_->SetMemoryUtilization(0.2);
servers_[0]->server_metric_recorder_->SetQps(0.3);
servers_[0]->server_metric_recorder_->SetNamedUtilization(kMetricName, 0.4);
// Start client.
auto response_generator = BuildResolverResponseGenerator();
auto channel = BuildChannel("oob_backend_metric_test_lb", response_generator);
@ -2751,6 +2726,7 @@ TEST_F(OobBackendMetricTest, Basic) {
EXPECT_EQ("oob_backend_metric_test_lb",
channel->GetLoadBalancingPolicyName());
// Check report seen by client.
bool report_seen = false;
for (size_t i = 0; i < 5; ++i) {
auto report = GetBackendMetricReport();
if (report.has_value()) {
@ -2761,19 +2737,22 @@ TEST_F(OobBackendMetricTest, Basic) {
EXPECT_THAT(
report->second.utilization(),
::testing::UnorderedElementsAre(::testing::Pair(kMetricName, 0.4)));
report_seen = true;
break;
}
gpr_sleep_until(grpc_timeout_seconds_to_deadline(1));
}
ASSERT_TRUE(report_seen);
// Now update the utilization data on the server.
// Note that the server may send a new report while we're updating these,
// so we set them in reverse order, so that we know we'll get all new
// data once we see a report with the new CPU utilization value.
servers_[0]->orca_service_.SetNamedUtilization(kMetricName, 0.7);
servers_[0]->orca_service_.SetQps(0.6);
servers_[0]->orca_service_.SetMemoryUtilization(0.5);
servers_[0]->orca_service_.SetCpuUtilization(0.4);
servers_[0]->server_metric_recorder_->SetNamedUtilization(kMetricName, 0.7);
servers_[0]->server_metric_recorder_->SetQps(0.6);
servers_[0]->server_metric_recorder_->SetMemoryUtilization(0.5);
servers_[0]->server_metric_recorder_->SetCpuUtilization(0.4);
// Wait for client to see new report.
report_seen = false;
for (size_t i = 0; i < 5; ++i) {
auto report = GetBackendMetricReport();
if (report.has_value()) {
@ -2785,11 +2764,13 @@ TEST_F(OobBackendMetricTest, Basic) {
EXPECT_THAT(
report->second.utilization(),
::testing::UnorderedElementsAre(::testing::Pair(kMetricName, 0.7)));
report_seen = true;
break;
}
}
gpr_sleep_until(grpc_timeout_seconds_to_deadline(1));
}
ASSERT_TRUE(report_seen);
}
//
@ -2882,97 +2863,125 @@ TEST_F(ControlPlaneStatusRewritingTest, RewritesFromConfigSelector) {
// WeightedRoundRobinTest
//
using WeightedRoundRobinTest = ClientLbEnd2endTest;
const char kServiceConfigPerCall[] =
"{\n"
" \"loadBalancingConfig\": [\n"
" {\"weighted_round_robin_experimental\": {\n"
" \"blackoutPeriod\": \"0s\",\n"
" \"weightUpdatePeriod\": \"0.1s\"\n"
" }}\n"
" ]\n"
"}";
const char kServiceConfigOob[] =
"{\n"
" \"loadBalancingConfig\": [\n"
" {\"weighted_round_robin_experimental\": {\n"
" \"blackoutPeriod\": \"0s\",\n"
" \"weightUpdatePeriod\": \"0.1s\",\n"
" \"enableOobLoadReport\": true\n"
" }}\n"
" ]\n"
"}";
class WeightedRoundRobinTest : public ClientLbEnd2endTest {
protected:
void ExpectWeightedRoundRobinPicks(
const grpc_core::DebugLocation& location,
const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
const std::vector<size_t>& expected_weights, size_t total_passes = 3,
EchoRequest* request_ptr = nullptr) {
GPR_ASSERT(expected_weights.size() == servers_.size());
size_t total_picks_per_pass = 0;
for (size_t picks : expected_weights) {
total_picks_per_pass += picks;
}
size_t num_picks = 0;
size_t num_passes = 0;
SendRpcsUntil(
location, stub,
[&](const Status&) {
if (++num_picks == total_picks_per_pass) {
bool match = true;
for (size_t i = 0; i < expected_weights.size(); ++i) {
if (servers_[i]->service_.request_count() !=
expected_weights[i]) {
match = false;
break;
}
}
if (match) {
if (++num_passes == total_passes) return false;
} else {
num_passes = 0;
}
num_picks = 0;
ResetCounters();
}
return true;
},
request_ptr);
}
};
TEST_F(WeightedRoundRobinTest, Basic) {
TEST_F(WeightedRoundRobinTest, CallAndServerMetric) {
const int kNumServers = 3;
StartServers(kNumServers);
// Tell each server to report the appropriate CPU utilization.
xds::data::orca::v3::OrcaLoadReport load_report;
load_report.set_rps_fractional(100);
load_report.set_cpu_utilization(0.9);
servers_[0]->service_.SetLoadReport(load_report);
load_report.set_cpu_utilization(0.3);
servers_[1]->service_.SetLoadReport(load_report);
servers_[2]->service_.SetLoadReport(load_report);
// Report server metrics that should give 1:2:4 WRR picks.
servers_[0]->server_metric_recorder_->SetCpuUtilization(0.9);
servers_[0]->server_metric_recorder_->SetQps(9);
servers_[1]->server_metric_recorder_->SetCpuUtilization(0.3);
servers_[1]->server_metric_recorder_->SetQps(6);
servers_[2]->server_metric_recorder_->SetCpuUtilization(0.3);
servers_[2]->server_metric_recorder_->SetQps(12);
// Create channel.
auto response_generator = BuildResolverResponseGenerator();
auto channel = BuildChannel("", response_generator);
auto stub = BuildStub(channel);
const char kServiceConfig[] =
"{\n"
" \"loadBalancingConfig\": [\n"
" {\"weighted_round_robin_experimental\": {\n"
" \"blackoutPeriod\": \"0s\"\n"
" }}\n"
" ]\n"
"}";
response_generator.SetNextResolution(GetServersPorts(), kServiceConfig);
// Wait for the right set of WRR picks.
size_t num_picks = 0;
SendRpcsUntil(DEBUG_LOCATION, stub, [&](const Status&) {
if (++num_picks == 7) {
gpr_log(GPR_INFO, "request counts: %d %d %d",
servers_[0]->service_.request_count(),
servers_[1]->service_.request_count(),
servers_[2]->service_.request_count());
if (servers_[0]->service_.request_count() == 1 &&
servers_[1]->service_.request_count() == 3 &&
servers_[2]->service_.request_count() == 3) {
return false;
}
num_picks = 0;
ResetCounters();
}
return true;
});
response_generator.SetNextResolution(GetServersPorts(),
kServiceConfigPerCall);
// Send requests with per-call reported QPS set to 100.
// This should override per-server QPS above and give 1:3:3 WRR picks.
EchoRequest request;
request.mutable_param()->mutable_backend_metrics()->set_rps_fractional(100);
ExpectWeightedRoundRobinPicks(DEBUG_LOCATION, stub,
/*expected_weights=*/{1, 3, 3},
/*total_passes=*/3, &request);
// Now send requests without per-call reported QPS.
// This should change WRR picks back to 1:2:4.
ExpectWeightedRoundRobinPicks(DEBUG_LOCATION, stub,
/*expected_weights=*/{1, 2, 4});
// Check LB policy name for the channel.
EXPECT_EQ("weighted_round_robin_experimental",
channel->GetLoadBalancingPolicyName());
}
TEST_F(WeightedRoundRobinTest, OobReporting) {
class WeightedRoundRobinParamTest
: public WeightedRoundRobinTest,
public ::testing::WithParamInterface<const char*> {};
INSTANTIATE_TEST_SUITE_P(WeightedRoundRobin, WeightedRoundRobinParamTest,
::testing::Values(kServiceConfigPerCall,
kServiceConfigOob));
TEST_P(WeightedRoundRobinParamTest, Basic) {
const int kNumServers = 3;
StartServers(kNumServers);
// Tell each server to report the appropriate CPU utilization.
servers_[0]->orca_service_.SetCpuUtilization(0.9);
servers_[0]->orca_service_.SetQps(100);
servers_[1]->orca_service_.SetCpuUtilization(0.3);
servers_[1]->orca_service_.SetQps(100);
servers_[2]->orca_service_.SetCpuUtilization(0.3);
servers_[2]->orca_service_.SetQps(100);
// Report server metrics that should give 1:3:3 WRR picks.
servers_[0]->server_metric_recorder_->SetCpuUtilization(0.9);
servers_[0]->server_metric_recorder_->SetQps(100);
servers_[1]->server_metric_recorder_->SetCpuUtilization(0.3);
servers_[1]->server_metric_recorder_->SetQps(100);
servers_[2]->server_metric_recorder_->SetCpuUtilization(0.3);
servers_[2]->server_metric_recorder_->SetQps(100);
// Create channel.
auto response_generator = BuildResolverResponseGenerator();
auto channel = BuildChannel("", response_generator);
auto stub = BuildStub(channel);
const char kServiceConfig[] =
"{\n"
" \"loadBalancingConfig\": [\n"
" {\"weighted_round_robin_experimental\": {\n"
" \"blackoutPeriod\": \"0s\",\n"
" \"enableOobLoadReport\": true\n"
" }}\n"
" ]\n"
"}";
response_generator.SetNextResolution(GetServersPorts(), kServiceConfig);
response_generator.SetNextResolution(GetServersPorts(), GetParam());
// Wait for the right set of WRR picks.
size_t num_picks = 0;
SendRpcsUntil(DEBUG_LOCATION, stub, [&](const Status&) {
if (++num_picks == 7) {
gpr_log(GPR_INFO, "request counts: %d %d %d",
servers_[0]->service_.request_count(),
servers_[1]->service_.request_count(),
servers_[2]->service_.request_count());
if (servers_[0]->service_.request_count() == 1 &&
servers_[1]->service_.request_count() == 3 &&
servers_[2]->service_.request_count() == 3) {
return false;
}
num_picks = 0;
ResetCounters();
}
return true;
});
ExpectWeightedRoundRobinPicks(DEBUG_LOCATION, stub,
/*expected_weights=*/{1, 3, 3});
// Check LB policy name for the channel.
EXPECT_EQ("weighted_round_robin_experimental",
channel->GetLoadBalancingPolicyName());
@ -2984,6 +2993,13 @@ TEST_F(WeightedRoundRobinTest, OobReporting) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
// Make the backup poller poll very frequently in order to pick up
// updates from all the subchannels's FDs.
GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1);
#if TARGET_OS_IPHONE
// Workaround Apple CFStream bug
grpc_core::SetEnv("grpc_cfstream", "0");
#endif
grpc::testing::TestEnvironment env(&argc, argv);
grpc_init();
grpc::testing::ConnectionAttemptInjector::Init();

@ -24,7 +24,9 @@
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/ext/orca_service.h>
#include <grpcpp/ext/server_metric_recorder.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
@ -44,6 +46,7 @@ namespace testing {
namespace {
using experimental::OrcaService;
using experimental::ServerMetricRecorder;
class OrcaServiceEnd2endTest : public ::testing::Test {
protected:
@ -91,8 +94,10 @@ class OrcaServiceEnd2endTest : public ::testing::Test {
};
OrcaServiceEnd2endTest()
: orca_service_(OrcaService::Options().set_min_report_duration(
absl::ZeroDuration())) {
: server_metric_recorder_(ServerMetricRecorder::Create()),
orca_service_(server_metric_recorder_.get(),
OrcaService::Options().set_min_report_duration(
absl::ZeroDuration())) {
std::string server_address =
absl::StrCat("localhost:", grpc_pick_unused_port_or_die());
ServerBuilder builder;
@ -107,6 +112,7 @@ class OrcaServiceEnd2endTest : public ::testing::Test {
~OrcaServiceEnd2endTest() override { server_->Shutdown(); }
std::string server_address_;
std::unique_ptr<ServerMetricRecorder> server_metric_recorder_;
OrcaService orca_service_;
std::unique_ptr<Server> server_;
std::unique_ptr<OpenRcaService::Stub> stub_;
@ -140,24 +146,24 @@ TEST_F(OrcaServiceEnd2endTest, Basic) {
EXPECT_THAT(response.utilization(), ::testing::UnorderedElementsAre());
});
// Now set CPU utilization on the server.
orca_service_.SetCpuUtilization(0.5);
server_metric_recorder_->SetCpuUtilization(0.5);
ReadResponses([](const OrcaLoadReport& response) {
EXPECT_EQ(response.cpu_utilization(), 0.5);
EXPECT_EQ(response.mem_utilization(), 0);
EXPECT_THAT(response.utilization(), ::testing::UnorderedElementsAre());
});
// Update CPU utilization and set memory utilization.
orca_service_.SetCpuUtilization(0.8);
orca_service_.SetMemoryUtilization(0.4);
server_metric_recorder_->SetCpuUtilization(0.8);
server_metric_recorder_->SetMemoryUtilization(0.4);
ReadResponses([](const OrcaLoadReport& response) {
EXPECT_EQ(response.cpu_utilization(), 0.8);
EXPECT_EQ(response.mem_utilization(), 0.4);
EXPECT_THAT(response.utilization(), ::testing::UnorderedElementsAre());
});
// Unset CPU and memory utilization and set a named utilization.
orca_service_.DeleteCpuUtilization();
orca_service_.DeleteMemoryUtilization();
orca_service_.SetNamedUtilization(kMetricName1, 0.3);
server_metric_recorder_->ClearCpuUtilization();
server_metric_recorder_->ClearMemoryUtilization();
server_metric_recorder_->SetNamedUtilization(kMetricName1, 0.3);
ReadResponses([&](const OrcaLoadReport& response) {
EXPECT_EQ(response.cpu_utilization(), 0);
EXPECT_EQ(response.mem_utilization(), 0);
@ -166,9 +172,9 @@ TEST_F(OrcaServiceEnd2endTest, Basic) {
::testing::UnorderedElementsAre(::testing::Pair(kMetricName1, 0.3)));
});
// Unset the previous named utilization and set two new ones.
orca_service_.DeleteNamedUtilization(kMetricName1);
orca_service_.SetNamedUtilization(kMetricName2, 0.2);
orca_service_.SetNamedUtilization(kMetricName3, 0.1);
server_metric_recorder_->ClearNamedUtilization(kMetricName1);
server_metric_recorder_->SetNamedUtilization(kMetricName2, 0.2);
server_metric_recorder_->SetNamedUtilization(kMetricName3, 0.1);
ReadResponses([&](const OrcaLoadReport& response) {
EXPECT_EQ(response.cpu_utilization(), 0);
EXPECT_EQ(response.mem_utilization(), 0);
@ -178,7 +184,7 @@ TEST_F(OrcaServiceEnd2endTest, Basic) {
::testing::Pair(kMetricName3, 0.1)));
});
// Replace the entire named metric map at once.
orca_service_.SetAllNamedUtilization(
server_metric_recorder_->SetAllNamedUtilization(
{{kMetricName2, 0.5}, {kMetricName4, 0.9}});
ReadResponses([&](const OrcaLoadReport& response) {
EXPECT_EQ(response.cpu_utilization(), 0);

@ -59,7 +59,6 @@ grpc_cc_library(
"//:grpc",
"//:grpc++",
"//:grpc_resolver_fake",
"//:grpcpp_orca_interceptor",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
"//src/proto/grpc/testing/duplicate:echo_duplicate_proto",

@ -251,7 +251,7 @@ XdsEnd2endTest::BackendServerThread::Credentials() {
void XdsEnd2endTest::BackendServerThread::RegisterAllServices(
ServerBuilder* builder) {
experimental::EnableCallMetricRecording(builder);
ServerBuilder::experimental_type(builder).EnableCallMetricRecording();
builder->RegisterService(&backend_service_);
builder->RegisterService(&backend_service1_);
builder->RegisterService(&backend_service2_);

@ -952,6 +952,7 @@ include/grpcpp/create_channel_binder.h \
include/grpcpp/create_channel_posix.h \
include/grpcpp/ext/call_metric_recorder.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/ext/server_metric_recorder.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/grpcpp.h \

@ -952,6 +952,7 @@ include/grpcpp/create_channel_binder.h \
include/grpcpp/create_channel_posix.h \
include/grpcpp/ext/call_metric_recorder.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/ext/server_metric_recorder.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/grpcpp.h \
@ -1071,6 +1072,9 @@ include/grpcpp/support/time.h \
include/grpcpp/support/validate_service_config.h \
include/grpcpp/version_info.h \
include/grpcpp/xds_server_builder.h \
src/core/ext/filters/backend_metrics/backend_metric_filter.cc \
src/core/ext/filters/backend_metrics/backend_metric_filter.h \
src/core/ext/filters/backend_metrics/backend_metric_provider.h \
src/core/ext/filters/census/grpc_context.cc \
src/core/ext/filters/channel_idle/channel_idle_filter.cc \
src/core/ext/filters/channel_idle/channel_idle_filter.h \
@ -2719,6 +2723,8 @@ src/cpp/common/tls_credentials_options.cc \
src/cpp/common/validate_service_config.cc \
src/cpp/common/version_cc.cc \
src/cpp/server/async_generic_service.cc \
src/cpp/server/backend_metric_recorder.cc \
src/cpp/server/backend_metric_recorder.h \
src/cpp/server/channel_argument_option.cc \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.h \
@ -2729,7 +2735,6 @@ src/cpp/server/health/default_health_check_service.h \
src/cpp/server/health/health_check_service.cc \
src/cpp/server/health/health_check_service_server_builder_option.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/orca/call_metric_recorder.cc \
src/cpp/server/secure_server_credentials.cc \
src/cpp/server/secure_server_credentials.h \
src/cpp/server/server_builder.cc \

@ -877,6 +877,9 @@ include/grpc/support/time.h \
include/grpc/support/workaround_list.h \
src/core/README.md \
src/core/ext/README.md \
src/core/ext/filters/backend_metrics/backend_metric_filter.cc \
src/core/ext/filters/backend_metrics/backend_metric_filter.h \
src/core/ext/filters/backend_metrics/backend_metric_provider.h \
src/core/ext/filters/census/grpc_context.cc \
src/core/ext/filters/channel_idle/channel_idle_filter.cc \
src/core/ext/filters/channel_idle/channel_idle_filter.h \

Loading…
Cancel
Save