grpc 1.83.1 → 1.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +21 -17
  3. data/include/grpc/credentials.h +10 -0
  4. data/include/grpc/grpc_security_constants.h +2 -0
  5. data/include/grpc/impl/channel_arg_names.h +9 -0
  6. data/src/core/call/call_filters.h +4 -2
  7. data/src/core/call/client_call.cc +20 -8
  8. data/src/core/call/client_call.h +4 -0
  9. data/src/core/call/interception_chain.cc +2 -0
  10. data/src/core/call/interception_chain.h +14 -1
  11. data/src/core/call/metadata.cc +1 -3
  12. data/src/core/call/metadata_batch.h +13 -5
  13. data/src/core/call/server_call.cc +31 -14
  14. data/src/core/call/server_call.h +4 -0
  15. data/src/core/channelz/text_encode.cc +9 -4
  16. data/src/core/channelz/v2tov1/convert.cc +2 -2
  17. data/src/core/client_channel/backup_poller.cc +1 -2
  18. data/src/core/client_channel/client_channel.cc +6 -33
  19. data/src/core/client_channel/client_channel_filter.cc +22 -55
  20. data/src/core/client_channel/client_channel_filter.h +2 -2
  21. data/src/core/client_channel/client_channel_service_config.cc +3 -19
  22. data/src/core/client_channel/direct_channel.cc +7 -1
  23. data/src/core/client_channel/direct_channel.h +2 -2
  24. data/src/core/client_channel/load_balanced_call_destination.cc +5 -3
  25. data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -12
  26. data/src/core/client_channel/subchannel.cc +310 -1058
  27. data/src/core/client_channel/subchannel.h +44 -329
  28. data/src/core/client_channel/subchannel_metrics.cc +48 -0
  29. data/src/core/client_channel/subchannel_metrics.h +60 -0
  30. data/src/core/credentials/call/external/file_external_account_credentials.cc +1 -1
  31. data/src/core/credentials/call/external/url_external_account_credentials.cc +2 -3
  32. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +8 -24
  33. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h +3 -6
  34. data/src/core/credentials/call/gdch_service_account/gdch_service_account_credentials.cc +525 -0
  35. data/src/core/credentials/call/gdch_service_account/gdch_service_account_credentials.h +138 -0
  36. data/src/core/credentials/call/json_util.h +1 -0
  37. data/src/core/credentials/call/jwt/json_token.cc +10 -2
  38. data/src/core/credentials/call/jwt/jwt_verifier.cc +15 -1
  39. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +1 -1
  40. data/src/core/credentials/call/oauth2/oauth2_credentials.cc +42 -79
  41. data/src/core/credentials/call/oauth2/oauth2_credentials.h +2 -5
  42. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc +52 -31
  43. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.h +21 -8
  44. data/src/core/credentials/transport/google_default/google_default_credentials.cc +3 -4
  45. data/src/core/credentials/transport/ssl/ssl_credentials.cc +59 -72
  46. data/src/core/credentials/transport/ssl/ssl_credentials.h +9 -8
  47. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +12 -6
  48. data/src/core/credentials/transport/ssl/ssl_security_connector.h +4 -4
  49. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -18
  50. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +9 -6
  51. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +45 -56
  52. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +5 -4
  53. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +26 -0
  54. data/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc +1 -1
  55. data/src/core/credentials/transport/tls/load_system_roots.h +2 -6
  56. data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +2 -4
  57. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +13 -15
  58. data/src/core/credentials/transport/tls/load_system_roots_supported.h +3 -2
  59. data/src/core/credentials/transport/tls/load_system_roots_windows.cc +5 -8
  60. data/src/core/credentials/transport/tls/spiffe_utils.cc +1 -1
  61. data/src/core/credentials/transport/tls/ssl_utils.cc +39 -28
  62. data/src/core/credentials/transport/tls/ssl_utils.h +12 -49
  63. data/src/core/credentials/transport/tls/tls_security_connector.cc +48 -33
  64. data/src/core/credentials/transport/tls/tls_security_connector.h +31 -10
  65. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +15 -11
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +20 -9
  67. data/src/core/ext/filters/rbac/rbac_filter.cc +43 -21
  68. data/src/core/ext/filters/rbac/rbac_filter.h +21 -3
  69. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -2
  70. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +1 -1
  71. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -20
  72. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +32 -67
  73. data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -0
  74. data/src/core/ext/transport/chttp2/transport/flow_control.h +78 -4
  75. data/src/core/ext/transport/chttp2/transport/frame.h +2 -0
  76. data/src/core/ext/transport/chttp2/transport/frame_data.cc +3 -4
  77. data/src/core/ext/transport/chttp2/transport/goaway.h +7 -0
  78. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +5 -3
  79. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +3 -1
  80. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +141 -130
  81. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +22 -22
  82. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +402 -269
  83. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +80 -49
  84. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +1 -2
  85. data/src/core/ext/transport/chttp2/transport/http2_status.h +38 -37
  86. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +178 -5
  87. data/src/core/ext/transport/chttp2/transport/http2_transport.h +345 -5
  88. data/src/core/ext/transport/chttp2/transport/parsing.cc +5 -5
  89. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +3 -2
  90. data/src/core/ext/transport/chttp2/transport/ping_promise.h +25 -5
  91. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +3 -4
  92. data/src/core/ext/transport/chttp2/transport/read_context.h +30 -3
  93. data/src/core/ext/transport/chttp2/transport/stream.h +65 -23
  94. data/src/core/ext/transport/chttp2/transport/writing.cc +0 -3
  95. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -5
  96. data/src/core/ext/transport/inproc/legacy_inproc_transport.cc +4 -17
  97. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upb.h +1912 -0
  98. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upb_minitable.c +300 -0
  99. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upb_minitable.h +37 -0
  100. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upb.h +187 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upb_minitable.c +64 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upb_minitable.h +31 -0
  103. data/src/core/ext/upb-gen/envoy/service/ext_proc/v3/external_processor.upb.h +2362 -0
  104. data/src/core/ext/upb-gen/envoy/service/ext_proc/v3/external_processor.upb_minitable.c +556 -0
  105. data/src/core/ext/upb-gen/envoy/service/ext_proc/v3/external_processor.upb_minitable.h +47 -0
  106. data/src/core/ext/upb-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upb.h +5 -5
  107. data/src/core/ext/upb-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upb_minitable.c +3 -3
  108. data/src/core/ext/upb-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upb_minitable.h +5 -5
  109. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upbdefs.c +453 -0
  110. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upbdefs.h +67 -0
  111. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upbdefs.c +142 -0
  112. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upbdefs.h +37 -0
  113. data/src/core/ext/upbdefs-gen/grpc/channelz/v1/channelz.upbdefs.c +715 -0
  114. data/src/core/ext/upbdefs-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upbdefs.h +44 -44
  115. data/src/core/filter/auth/server_auth_filter.cc +2 -3
  116. data/src/core/filter/composite/composite_filter.cc +45 -33
  117. data/src/core/filter/composite/composite_filter.h +5 -4
  118. data/src/core/filter/ext_proc/ext_proc_filter.cc +224 -0
  119. data/src/core/filter/ext_proc/ext_proc_filter.h +155 -0
  120. data/src/core/filter/ext_proc/ext_proc_messages.cc +701 -0
  121. data/src/core/filter/ext_proc/ext_proc_messages.h +297 -0
  122. data/src/core/filter/filter_args.h +13 -2
  123. data/src/core/handshaker/http_connect/http_proxy_mapper.cc +30 -3
  124. data/src/core/handshaker/security/security_handshaker.cc +9 -6
  125. data/src/core/lib/channel/channel_stack.cc +3 -0
  126. data/src/core/lib/channel/channel_stack.h +2 -0
  127. data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -2
  128. data/src/core/lib/channel/promise_based_filter.cc +132 -20
  129. data/src/core/lib/channel/promise_based_filter.h +42 -12
  130. data/src/core/lib/compression/compression_internal.cc +4 -5
  131. data/src/core/lib/debug/trace_flags.cc +8 -0
  132. data/src/core/lib/debug/trace_flags.h +3 -0
  133. data/src/core/lib/event_engine/ares_resolver.cc +54 -50
  134. data/src/core/lib/event_engine/ares_resolver.h +3 -2
  135. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +3 -3
  136. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +4 -10
  137. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +74 -33
  138. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +4 -4
  139. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +6 -2
  140. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -0
  141. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +3 -0
  142. data/src/core/lib/event_engine/windows/windows_endpoint.cc +1 -3
  143. data/src/core/lib/experiments/experiments.cc +60 -96
  144. data/src/core/lib/experiments/experiments.h +34 -50
  145. data/src/core/lib/iomgr/cfstream_handle.cc +2 -6
  146. data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -10
  147. data/src/core/lib/iomgr/error.cc +2 -6
  148. data/src/core/lib/iomgr/error_cfstream.cc +1 -1
  149. data/src/core/lib/iomgr/ev_poll_posix.cc +5 -9
  150. data/src/core/lib/iomgr/event_engine_shims/closure.cc +1 -1
  151. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +1 -2
  152. data/src/core/lib/iomgr/event_engine_shims/tcp_client.cc +1 -2
  153. data/src/core/lib/iomgr/iomgr_posix.cc +0 -4
  154. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +0 -4
  155. data/src/core/lib/iomgr/iomgr_windows.cc +0 -4
  156. data/src/core/lib/iomgr/socket_factory_posix.h +1 -1
  157. data/src/core/lib/iomgr/socket_utils_posix.cc +3 -0
  158. data/src/core/lib/iomgr/socket_utils_posix.h +3 -0
  159. data/src/core/lib/iomgr/systemd_utils.cc +0 -1
  160. data/src/core/lib/iomgr/tcp_client.h +1 -1
  161. data/src/core/lib/iomgr/tcp_posix.cc +23 -15
  162. data/src/core/lib/iomgr/tcp_server.h +1 -1
  163. data/src/core/lib/iomgr/tcp_server_posix.cc +2 -3
  164. data/src/core/lib/iomgr/tcp_server_utils_posix.h +0 -1
  165. data/src/core/lib/iomgr/tcp_server_windows.cc +0 -1
  166. data/src/core/lib/iomgr/tcp_windows.cc +5 -10
  167. data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -4
  168. data/src/core/lib/iomgr/unix_sockets_posix.h +3 -1
  169. data/src/core/lib/iomgr/vsock.h +3 -1
  170. data/src/core/lib/resource_quota/memory_quota.cc +1 -1
  171. data/src/core/lib/security/authorization/rbac_policy.cc +139 -56
  172. data/src/core/lib/security/authorization/rbac_policy.h +21 -3
  173. data/src/core/lib/surface/call.cc +3 -9
  174. data/src/core/lib/surface/call_utils.h +113 -0
  175. data/src/core/lib/surface/channel_create.cc +1 -1
  176. data/src/core/lib/surface/channel_create.h +0 -2
  177. data/src/core/lib/surface/channel_init.cc +77 -38
  178. data/src/core/lib/surface/channel_init.h +30 -16
  179. data/src/core/lib/surface/filter_stack_call.cc +5 -10
  180. data/src/core/lib/surface/init.cc +13 -27
  181. data/src/core/lib/surface/version.cc +1 -1
  182. data/src/core/lib/transport/error_utils.cc +0 -27
  183. data/src/core/lib/transport/error_utils.h +0 -16
  184. data/src/core/lib/transport/transport.h +7 -5
  185. data/src/core/load_balancing/pick_first/pick_first.cc +2 -0
  186. data/src/core/load_balancing/rls/rls.cc +28 -11
  187. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +33 -42
  188. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.h +0 -2
  189. data/src/core/load_balancing/xds/cds.cc +3 -1
  190. data/src/core/load_balancing/xds/xds_cluster_impl.cc +0 -1
  191. data/src/core/mitigation_engine/mitigation.h +14 -5
  192. data/src/core/mitigation_engine/mitigation_engine.h +7 -3
  193. data/src/core/mitigation_engine/mitigation_provider.h +2 -1
  194. data/src/core/plugin_registry/grpc_plugin_registry.cc +39 -8
  195. data/src/core/resolver/dns/{event_engine/event_engine_client_channel_resolver.cc → dns_resolver.cc} +42 -41
  196. data/src/core/resolver/dns/{event_engine/event_engine_client_channel_resolver.h → dns_resolver.h} +8 -5
  197. data/src/core/resolver/dns/{event_engine/service_config_helper.cc → service_config_helper.cc} +1 -1
  198. data/src/core/resolver/dns/{event_engine/service_config_helper.h → service_config_helper.h} +3 -3
  199. data/src/core/resolver/endpoint_addresses.h +3 -0
  200. data/src/core/resolver/google_c2p/google_c2p_resolver.cc +2 -1
  201. data/src/core/resolver/xds/xds_resolver.cc +35 -9
  202. data/src/core/server/server.cc +2 -6
  203. data/src/core/server/server_config_selector.h +18 -3
  204. data/src/core/server/server_config_selector_filter.cc +178 -91
  205. data/src/core/server/server_config_selector_filter.h +58 -3
  206. data/src/core/server/xds_server_config_fetcher.cc +196 -129
  207. data/src/core/server/xds_server_config_fetcher.h +49 -0
  208. data/src/core/server/xds_server_config_fetcher_legacy.cc +41 -37
  209. data/src/core/telemetry/histogram.h +94 -14
  210. data/src/core/telemetry/instrument.cc +179 -74
  211. data/src/core/telemetry/instrument.h +78 -30
  212. data/src/core/telemetry/metrics.h +5 -0
  213. data/src/core/{resolver/dns/dns_resolver_plugin.h → telemetry/telemetry_label.h} +12 -8
  214. data/src/core/tsi/alts/crypt/aes_gcm.cc +10 -13
  215. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +2 -2
  216. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +3 -1
  217. data/src/core/tsi/ssl_telemetry_utils.cc +216 -259
  218. data/src/core/tsi/ssl_telemetry_utils.h +12 -2
  219. data/src/core/tsi/ssl_transport_security.cc +238 -80
  220. data/src/core/tsi/ssl_transport_security.h +63 -33
  221. data/src/core/tsi/tls_telemetry.cc +31 -0
  222. data/src/core/tsi/tls_telemetry.h +47 -0
  223. data/src/core/tsi/transport_security.cc +2 -2
  224. data/src/core/tsi/transport_security.h +1 -1
  225. data/src/core/tsi/transport_security_interface.h +1 -1
  226. data/src/core/{resolver/dns/native/dns_resolver.h → util/address_sorting_init.cc} +21 -8
  227. data/src/core/{resolver/dns/c_ares/grpc_ares_wrapper_posix.cc → util/address_sorting_init.h} +7 -8
  228. data/src/core/util/http_client/httpcli.cc +16 -53
  229. data/src/core/util/http_client/httpcli.h +0 -7
  230. data/src/core/util/http_client/httpcli_security_connector.cc +13 -8
  231. data/src/core/util/linux/cpu.cc +1 -1
  232. data/src/core/util/load_file.cc +3 -9
  233. data/src/core/util/load_file.h +3 -4
  234. data/src/core/util/matchers.h +8 -0
  235. data/src/core/util/posix/cpu.cc +1 -1
  236. data/src/core/util/status_helper.cc +0 -20
  237. data/src/core/util/status_helper.h +3 -14
  238. data/src/core/xds/grpc/xds_audit_logger_registry.cc +51 -31
  239. data/src/core/xds/grpc/xds_audit_logger_registry.h +17 -3
  240. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -10
  241. data/src/core/xds/grpc/xds_bootstrap_grpc.h +8 -6
  242. data/src/core/xds/grpc/xds_bootstrap_grpc_builder.cc +488 -0
  243. data/src/core/xds/grpc/xds_bootstrap_grpc_builder.h +97 -0
  244. data/src/core/xds/grpc/xds_certificate_provider.cc +7 -7
  245. data/src/core/xds/grpc/xds_client_grpc.cc +4 -8
  246. data/src/core/xds/grpc/xds_client_grpc.h +0 -4
  247. data/src/core/xds/grpc/xds_cluster.h +1 -0
  248. data/src/core/xds/grpc/xds_cluster_parser.cc +1 -5
  249. data/src/core/xds/grpc/xds_cluster_parser.h +0 -2
  250. data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +0 -2
  251. data/src/core/xds/grpc/xds_cluster_specifier_plugin.h +0 -2
  252. data/src/core/xds/grpc/xds_common_types.cc +0 -91
  253. data/src/core/xds/grpc/xds_common_types.h +1 -47
  254. data/src/core/xds/grpc/xds_common_types_parser.cc +84 -378
  255. data/src/core/xds/grpc/xds_common_types_parser.h +9 -11
  256. data/src/core/xds/grpc/xds_endpoint_parser.cc +0 -2
  257. data/src/core/xds/grpc/xds_grpc_service_parser.cc +177 -0
  258. data/src/core/{resolver/dns/c_ares/dns_resolver_ares.h → xds/grpc/xds_grpc_service_parser.h} +14 -9
  259. data/src/core/xds/grpc/xds_http_composite_filter.cc +26 -21
  260. data/src/core/xds/grpc/xds_http_composite_filter.h +4 -3
  261. data/src/core/xds/grpc/xds_http_ext_proc_filter.cc +418 -0
  262. data/src/core/xds/grpc/xds_http_ext_proc_filter.h +89 -0
  263. data/src/core/xds/grpc/xds_http_fault_filter.cc +9 -12
  264. data/src/core/xds/grpc/xds_http_fault_filter.h +1 -4
  265. data/src/core/xds/grpc/xds_http_filter.cc +2 -1
  266. data/src/core/xds/grpc/xds_http_filter.h +6 -5
  267. data/src/core/xds/grpc/xds_http_filter_registry.cc +10 -127
  268. data/src/core/xds/grpc/xds_http_filter_registry.h +7 -59
  269. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +13 -14
  270. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -2
  271. data/src/core/xds/grpc/xds_http_rbac_filter.cc +403 -25
  272. data/src/core/xds/grpc/xds_http_rbac_filter.h +1 -3
  273. data/src/core/xds/grpc/xds_http_stateful_session_filter.cc +8 -13
  274. data/src/core/xds/grpc/xds_http_stateful_session_filter.h +1 -4
  275. data/src/core/xds/grpc/xds_lb_policy_registry.cc +0 -292
  276. data/src/core/xds/grpc/xds_lb_policy_registry.h +7 -3
  277. data/src/core/xds/grpc/xds_listener.cc +2 -0
  278. data/src/core/xds/grpc/xds_listener.h +5 -0
  279. data/src/core/xds/grpc/xds_listener_parser.cc +16 -11
  280. data/src/core/xds/grpc/xds_matcher_parse.h +3 -1
  281. data/src/core/xds/grpc/xds_metadata_parser.cc +6 -1
  282. data/src/core/xds/grpc/xds_metadata_parser.h +2 -0
  283. data/src/core/xds/grpc/xds_route_config.cc +2 -0
  284. data/src/core/xds/grpc/xds_route_config.h +3 -1
  285. data/src/core/xds/grpc/xds_route_config_parser.cc +13 -79
  286. data/src/core/xds/grpc/xds_route_config_parser.h +0 -3
  287. data/src/core/xds/grpc/xds_routing.cc +116 -69
  288. data/src/core/xds/grpc/xds_routing.h +19 -8
  289. data/src/core/xds/grpc/xds_tls_context.cc +117 -0
  290. data/src/core/xds/grpc/xds_tls_context.h +76 -0
  291. data/src/core/xds/grpc/xds_tls_context_parser.cc +275 -0
  292. data/src/core/xds/grpc/xds_tls_context_parser.h +35 -0
  293. data/src/core/xds/grpc/xds_transport_grpc.cc +41 -38
  294. data/src/core/xds/grpc/xds_transport_grpc.h +4 -2
  295. data/src/ruby/ext/grpc/rb_call.c +26 -15
  296. data/src/ruby/ext/grpc/rb_completion_queue.c +6 -5
  297. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  298. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  299. data/src/ruby/lib/grpc/version.rb +1 -1
  300. data/src/ruby/pb/test/client.rb +5 -4
  301. data/src/ruby/spec/call_spec.rb +14 -0
  302. data/src/ruby/spec/generic/server_interceptors_spec.rb +3 -6
  303. metadata +50 -35
  304. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +0 -716
  305. data/src/core/lib/iomgr/resolve_address.cc +0 -59
  306. data/src/core/lib/iomgr/resolve_address.h +0 -125
  307. data/src/core/lib/iomgr/resolve_address_impl.h +0 -58
  308. data/src/core/lib/iomgr/resolve_address_posix.cc +0 -184
  309. data/src/core/lib/iomgr/resolve_address_posix.h +0 -78
  310. data/src/core/lib/iomgr/resolve_address_windows.cc +0 -169
  311. data/src/core/lib/iomgr/resolve_address_windows.h +0 -76
  312. data/src/core/resolver/dns/c_ares/dns_resolver_ares.cc +0 -781
  313. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +0 -93
  314. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +0 -203
  315. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +0 -838
  316. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +0 -1237
  317. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +0 -130
  318. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -35
  319. data/src/core/resolver/dns/dns_resolver_plugin.cc +0 -64
  320. data/src/core/resolver/dns/native/dns_resolver.cc +0 -173
  321. data/src/core/util/json/json_util.cc +0 -101
  322. data/src/core/util/json/json_util.h +0 -163
@@ -161,6 +161,8 @@ class XdsServerConfigFetcher::ListenerWatcher final
161
161
 
162
162
  const std::string& listening_address() const { return listening_address_; }
163
163
 
164
+ std::string ResourceName() const;
165
+
164
166
  private:
165
167
  class FilterChainMatchManager;
166
168
 
@@ -322,8 +324,14 @@ class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
322
324
  http_filters);
323
325
  ~XdsServerConfigSelector() override = default;
324
326
 
327
+ // Not used.
328
+ std::unique_ptr<ConnectionState> BuildFilterChains(
329
+ FilterChainBuilder& /*builder*/) override {
330
+ return nullptr;
331
+ }
332
+
325
333
  absl::StatusOr<CallConfig> GetCallConfig(
326
- grpc_metadata_batch* metadata) override;
334
+ const ConnectionState* /*state*/, grpc_metadata_batch* metadata) override;
327
335
 
328
336
  private:
329
337
  struct VirtualHost {
@@ -515,17 +523,6 @@ XdsServerConfigFetcher::XdsServerConfigFetcher(
515
523
  GRPC_CHECK(xds_client_ != nullptr);
516
524
  }
517
525
 
518
- std::string ListenerResourceName(absl::string_view resource_name_template,
519
- absl::string_view listening_address) {
520
- std::string tmp;
521
- if (absl::StartsWith(resource_name_template, "xdstp:")) {
522
- tmp = URI::PercentEncodePath(listening_address);
523
- listening_address = tmp;
524
- }
525
- return absl::StrReplaceAll(resource_name_template,
526
- {{"%s", listening_address}});
527
- }
528
-
529
526
  void XdsServerConfigFetcher::StartWatch(
530
527
  std::string listening_address,
531
528
  std::unique_ptr<ServerConfigFetcher::WatcherInterface> watcher) {
@@ -534,13 +531,9 @@ void XdsServerConfigFetcher::StartWatch(
534
531
  xds_client_.Ref(DEBUG_LOCATION, "ListenerWatcher"), std::move(watcher),
535
532
  serving_status_notifier_, listening_address);
536
533
  auto* listener_watcher_ptr = listener_watcher.get();
537
- XdsListenerResourceType::StartWatch(
538
- xds_client_.get(),
539
- ListenerResourceName(
540
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
541
- .server_listener_resource_name_template(),
542
- listening_address),
543
- std::move(listener_watcher));
534
+ XdsListenerResourceType::StartWatch(xds_client_.get(),
535
+ listener_watcher_ptr->ResourceName(),
536
+ std::move(listener_watcher));
544
537
  MutexLock lock(&mu_);
545
538
  listener_watchers_.emplace(watcher_ptr, listener_watcher_ptr);
546
539
  }
@@ -551,13 +544,9 @@ void XdsServerConfigFetcher::CancelWatch(
551
544
  auto it = listener_watchers_.find(watcher);
552
545
  if (it != listener_watchers_.end()) {
553
546
  // Cancel the watch on the listener before erasing
554
- XdsListenerResourceType::CancelWatch(
555
- xds_client_.get(),
556
- ListenerResourceName(
557
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
558
- .server_listener_resource_name_template(),
559
- it->second->listening_address()),
560
- it->second, false /* delay_unsubscription */);
547
+ XdsListenerResourceType::CancelWatch(xds_client_.get(),
548
+ it->second->ResourceName(), it->second,
549
+ false /* delay_unsubscription */);
561
550
  listener_watchers_.erase(it);
562
551
  }
563
552
  }
@@ -582,9 +571,8 @@ void XdsServerConfigFetcher::ListenerWatcher::OnResourceChanged(
582
571
  RefCountedPtr<ReadDelayHandle> /* read_delay_handle */) {
583
572
  if (!listener.ok()) {
584
573
  MutexLock lock(&mu_);
585
- OnFatalError(absl::Status(
586
- listener.status().code(),
587
- absl::StrCat("LDS resource: ", listener.status().message())));
574
+ OnFatalError(AddMessagePrefix(absl::StrCat("LDS resource ", ResourceName()),
575
+ listener.status()));
588
576
  return;
589
577
  }
590
578
  GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
@@ -594,14 +582,15 @@ void XdsServerConfigFetcher::ListenerWatcher::OnResourceChanged(
594
582
  std::get_if<XdsListenerResource::TcpListener>(&(*listener)->listener);
595
583
  if (tcp_listener == nullptr) {
596
584
  MutexLock lock(&mu_);
597
- OnFatalError(
598
- absl::FailedPreconditionError("LDS resource is not a TCP listener"));
585
+ OnFatalError(absl::FailedPreconditionError(absl::StrCat(
586
+ "LDS resource ", ResourceName(), " is not a TCP listener")));
599
587
  return;
600
588
  }
601
589
  if (tcp_listener->address != listening_address_) {
602
590
  MutexLock lock(&mu_);
603
591
  OnFatalError(absl::FailedPreconditionError(
604
- "Address in LDS update does not match listening address"));
592
+ absl::StrCat("LDS resource ", ResourceName(),
593
+ " address does not match listening address")));
605
594
  return;
606
595
  }
607
596
  auto new_filter_chain_match_manager = MakeRefCounted<FilterChainMatchManager>(
@@ -648,6 +637,20 @@ void XdsServerConfigFetcher::ListenerWatcher::OnFatalError(
648
637
  }
649
638
  }
650
639
 
640
+ std::string XdsServerConfigFetcher::ListenerWatcher::ResourceName() const {
641
+ absl::string_view resource_name_template =
642
+ DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
643
+ .server_listener_resource_name_template();
644
+ absl::string_view listening_address = listening_address_;
645
+ std::string tmp;
646
+ if (absl::StartsWith(resource_name_template, "xdstp:")) {
647
+ tmp = URI::PercentEncodePath(listening_address);
648
+ listening_address = tmp;
649
+ }
650
+ return absl::StrReplaceAll(resource_name_template,
651
+ {{"%s", listening_address}});
652
+ }
653
+
651
654
  void XdsServerConfigFetcher::ListenerWatcher::
652
655
  PendingFilterChainMatchManagerReadyLocked(
653
656
  XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager*
@@ -1050,14 +1053,14 @@ absl::StatusOr<ChannelArgs> XdsServerConfigFetcher::ListenerWatcher::
1050
1053
  filter_chain->http_connection_manager.http_filters) {
1051
1054
  // Find filter. This is guaranteed to succeed, because it's checked
1052
1055
  // at config validation time in the XdsApi code.
1053
- const XdsHttpFilterImpl* filter_impl =
1056
+ const XdsHttpFilterFactory* factory =
1054
1057
  http_filter_registry.GetFilterForTopLevelType(
1055
1058
  http_filter.config_proto_type);
1056
- GRPC_CHECK_NE(filter_impl, nullptr);
1059
+ GRPC_CHECK_NE(factory, nullptr);
1057
1060
  // Some filters like the router filter are no-op filters and do not have
1058
1061
  // an implementation.
1059
- if (filter_impl->channel_filter() != nullptr) {
1060
- filters.push_back(filter_impl->channel_filter());
1062
+ if (factory->channel_filter() != nullptr) {
1063
+ filters.push_back(factory->channel_filter());
1061
1064
  }
1062
1065
  }
1063
1066
  // Add config selector filter.
@@ -1166,7 +1169,8 @@ XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1166
1169
 
1167
1170
  absl::StatusOr<ServerConfigSelector::CallConfig>
1168
1171
  XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1169
- XdsServerConfigSelector::GetCallConfig(grpc_metadata_batch* metadata) {
1172
+ XdsServerConfigSelector::GetCallConfig(const ConnectionState* /*state*/,
1173
+ grpc_metadata_batch* metadata) {
1170
1174
  CallConfig call_config;
1171
1175
  if (metadata->get_pointer(HttpPathMetadata()) == nullptr) {
1172
1176
  return absl::InternalError("no path found");
@@ -18,6 +18,7 @@
18
18
  #include <cmath>
19
19
  #include <cstddef>
20
20
  #include <cstdint>
21
+ #include <type_traits>
21
22
  #include <vector>
22
23
 
23
24
  #include "src/core/util/grpc_check.h"
@@ -35,26 +36,35 @@ namespace grpc_core {
35
36
  // bounds.size() - 1 includes all values greater than bounds.back().
36
37
  //
37
38
  // The bucket layout must be sorted in ascending order.
38
- using HistogramBuckets = absl::Span<const int64_t>;
39
+ using Int64HistogramBuckets = absl::Span<const int64_t>;
40
+ using DoubleHistogramBuckets = absl::Span<const double>;
39
41
 
40
42
  // Returns the bucket index for the given value in the given bounds.
41
43
  // The bounds must be sorted in ascending order.
42
44
  // The bounds array holds the upper bound of the bucket with the given index.
43
- inline int64_t BucketInBoundsFor(absl::Span<const int64_t> bounds,
44
- int64_t value) {
45
+ template <typename T>
46
+ size_t BucketInBoundsFor(absl::Span<const T> bounds, T value) {
45
47
  GRPC_CHECK(!bounds.empty());
48
+ if constexpr (std::is_floating_point_v<T>) {
49
+ if (std::isnan(value)) {
50
+ LOG_EVERY_N_SEC(WARNING, 1)
51
+ << "Attempted to add a NaN value in a DoubleHistogram. Adding it to "
52
+ "the last bucket.";
53
+ return bounds.size() - 1;
54
+ }
55
+ }
46
56
  if (value < bounds[0]) return 0;
47
57
  if (value > bounds.back()) return bounds.size() - 1;
48
58
  // Find the first element in bounds strictly greater than value
49
59
  auto it = std::upper_bound(bounds.begin(), bounds.end(), value);
50
60
  if (it == bounds.end()) return bounds.size() - 1;
51
61
  // The bucket index is the index of the element just before it.
52
- return std::distance(bounds.begin(), it);
62
+ return static_cast<size_t>(std::distance(bounds.begin(), it));
53
63
  }
54
64
 
55
- class LinearHistogramShape {
65
+ class LinearInt64HistogramShape {
56
66
  public:
57
- LinearHistogramShape(int64_t min, int64_t max) : min_(min), max_(max) {}
67
+ LinearInt64HistogramShape(int64_t min, int64_t max) : min_(min), max_(max) {}
58
68
 
59
69
  size_t buckets() const { return max_ - min_ + 1; }
60
70
  size_t BucketFor(int64_t value) const {
@@ -68,9 +78,39 @@ class LinearHistogramShape {
68
78
  int64_t max_;
69
79
  };
70
80
 
71
- class ExponentialHistogramShape {
81
+ class LinearDoubleHistogramShape {
82
+ public:
83
+ LinearDoubleHistogramShape(double min, double max, size_t buckets) {
84
+ GRPC_CHECK_GT(buckets, 0u);
85
+ GRPC_CHECK_GT(max, min);
86
+ bounds_.reserve(buckets);
87
+ double step = (max - min) / static_cast<double>(buckets);
88
+ for (size_t i = 1; i < buckets; ++i) {
89
+ bounds_.push_back(min + static_cast<double>(i) * step);
90
+ }
91
+ bounds_.push_back(max);
92
+ }
93
+
94
+ LinearDoubleHistogramShape(const LinearDoubleHistogramShape&) = delete;
95
+ LinearDoubleHistogramShape& operator=(const LinearDoubleHistogramShape&) =
96
+ delete;
97
+ LinearDoubleHistogramShape(LinearDoubleHistogramShape&&) = default;
98
+ LinearDoubleHistogramShape& operator=(LinearDoubleHistogramShape&&) = default;
99
+
100
+ size_t buckets() const { return bounds_.size(); }
101
+ size_t BucketFor(double value) const {
102
+ return BucketInBoundsFor(absl::MakeConstSpan(bounds_), value);
103
+ }
104
+
105
+ DoubleHistogramBuckets bounds() const { return bounds_; }
106
+
107
+ private:
108
+ std::vector<double> bounds_;
109
+ };
110
+
111
+ class ExponentialInt64HistogramShape {
72
112
  public:
73
- ExponentialHistogramShape(int64_t max, size_t buckets) {
113
+ ExponentialInt64HistogramShape(int64_t max, size_t buckets) {
74
114
  GRPC_CHECK_GT(max, 0);
75
115
  // Increase if needed. As of June 2026, the maximum we are using is 100.
76
116
  // Note that the BucketFor has to do a binary search, so it's better to
@@ -104,23 +144,63 @@ class ExponentialHistogramShape {
104
144
  GRPC_CHECK_EQ(bounds_.size(), buckets);
105
145
  }
106
146
 
107
- ExponentialHistogramShape(const ExponentialHistogramShape&) = delete;
108
- ExponentialHistogramShape& operator=(const ExponentialHistogramShape&) =
147
+ ExponentialInt64HistogramShape(const ExponentialInt64HistogramShape&) =
109
148
  delete;
110
- ExponentialHistogramShape(ExponentialHistogramShape&&) = default;
111
- ExponentialHistogramShape& operator=(ExponentialHistogramShape&&) = default;
149
+ ExponentialInt64HistogramShape& operator=(
150
+ const ExponentialInt64HistogramShape&) = delete;
151
+ ExponentialInt64HistogramShape(ExponentialInt64HistogramShape&&) = default;
152
+ ExponentialInt64HistogramShape& operator=(ExponentialInt64HistogramShape&&) =
153
+ default;
112
154
 
113
155
  size_t buckets() const { return bounds_.size(); }
114
156
  size_t BucketFor(int64_t value) const {
115
- return BucketInBoundsFor(bounds_, value);
157
+ return BucketInBoundsFor(absl::MakeConstSpan(bounds_), value);
116
158
  }
117
159
 
118
- HistogramBuckets bounds() const { return bounds_; }
160
+ Int64HistogramBuckets bounds() const { return bounds_; }
119
161
 
120
162
  private:
121
163
  std::vector<int64_t> bounds_;
122
164
  };
123
165
 
166
+ class ExponentialDoubleHistogramShape {
167
+ public:
168
+ ExponentialDoubleHistogramShape(double max, size_t buckets,
169
+ double min = 1.0) {
170
+ GRPC_CHECK_GT(min, 0.0);
171
+ GRPC_CHECK_GT(max, min);
172
+ GRPC_CHECK_GT(buckets, 0u);
173
+ bounds_.reserve(buckets);
174
+ if (buckets == 1) {
175
+ bounds_.push_back(max);
176
+ return;
177
+ }
178
+ double factor = std::pow(max / min, 1.0 / static_cast<double>(buckets - 1));
179
+ for (size_t i = 0; i < buckets - 1; ++i) {
180
+ bounds_.push_back(min * std::pow(factor, static_cast<double>(i)));
181
+ }
182
+ bounds_.push_back(max);
183
+ }
184
+
185
+ ExponentialDoubleHistogramShape(const ExponentialDoubleHistogramShape&) =
186
+ delete;
187
+ ExponentialDoubleHistogramShape& operator=(
188
+ const ExponentialDoubleHistogramShape&) = delete;
189
+ ExponentialDoubleHistogramShape(ExponentialDoubleHistogramShape&&) = default;
190
+ ExponentialDoubleHistogramShape& operator=(
191
+ ExponentialDoubleHistogramShape&&) = default;
192
+
193
+ size_t buckets() const { return bounds_.size(); }
194
+ size_t BucketFor(double value) const {
195
+ return BucketInBoundsFor(absl::MakeConstSpan(bounds_), value);
196
+ }
197
+
198
+ DoubleHistogramBuckets bounds() const { return bounds_; }
199
+
200
+ private:
201
+ std::vector<double> bounds_;
202
+ };
203
+
124
204
  } // namespace grpc_core
125
205
 
126
206
  #endif // GRPC_SRC_CORE_TELEMETRY_HISTOGRAM_H
@@ -112,28 +112,32 @@ std::string InstrumentLabelList::DebugString() const {
112
112
  }
113
113
 
114
114
  namespace {
115
+ template <typename T>
115
116
  struct Hook {
116
- HistogramCollectionHook hook;
117
- Hook* next;
117
+ InstrumentCollectionHook<T> hook;
118
+ Hook<T>* next;
118
119
  };
119
120
 
120
- std::atomic<Hook*> hooks = nullptr;
121
+ template <typename T>
122
+ std::atomic<Hook<T>*> hooks = nullptr;
121
123
  } // namespace
122
124
 
123
- void RegisterHistogramCollectionHook(HistogramCollectionHook hook) {
124
- Hook* new_hook =
125
- new Hook{std::move(hook), hooks.load(std::memory_order_acquire)};
126
- while (!hooks.compare_exchange_weak(new_hook->next, new_hook,
127
- std::memory_order_acq_rel)) {
125
+ template <typename T>
126
+ void RegisterInstrumentCollectionHook(InstrumentCollectionHook<T> hook) {
127
+ auto* new_hook =
128
+ new Hook<T>{std::move(hook), hooks<T>.load(std::memory_order_acquire)};
129
+ while (!hooks<T>.compare_exchange_weak(new_hook->next, new_hook,
130
+ std::memory_order_acq_rel)) {
128
131
  }
129
132
  }
130
133
 
131
134
  namespace instrument_detail {
132
135
 
133
- void CallHistogramCollectionHooks(
136
+ template <typename T>
137
+ void CallInstrumentCollectionHooks(
134
138
  const InstrumentMetadata::Description* instrument,
135
- absl::Span<const std::string> labels, int64_t value) {
136
- Hook* hook = hooks.load(std::memory_order_acquire);
139
+ absl::Span<const std::string> labels, T value) {
140
+ Hook<T>* hook = hooks<T>.load(std::memory_order_acquire);
137
141
  while (GPR_UNLIKELY(hook != nullptr)) {
138
142
  hook->hook(instrument, labels, value);
139
143
  hook = hook->next;
@@ -358,14 +362,23 @@ void MetricsQuery::Run(RefCountedPtr<CollectionScope> scope,
358
362
  sink.UpDownCounter(label_keys, label_values, metric->name,
359
363
  storage->SumCounter(metric->offset));
360
364
  },
361
- [metric, &sink, storage, &label_values,
362
- &label_keys](InstrumentMetadata::HistogramShape bounds) {
365
+ [metric, &sink, storage, &label_values, &label_keys](
366
+ InstrumentMetadata::Int64HistogramShape bounds) {
367
+ std::vector<uint64_t> counts(bounds.size());
368
+ for (size_t i = 0; i < bounds.size(); ++i) {
369
+ counts[i] = storage->SumCounter(metric->offset + i);
370
+ }
371
+ sink.Int64Histogram(label_keys, label_values, metric->name,
372
+ bounds, counts);
373
+ },
374
+ [metric, &sink, storage, &label_values, &label_keys](
375
+ InstrumentMetadata::DoubleHistogramShape bounds) {
363
376
  std::vector<uint64_t> counts(bounds.size());
364
377
  for (size_t i = 0; i < bounds.size(); ++i) {
365
378
  counts[i] = storage->SumCounter(metric->offset + i);
366
379
  }
367
- sink.Histogram(label_keys, label_values, metric->name,
368
- bounds, counts);
380
+ sink.DoubleHistogram(label_keys, label_values, metric->name,
381
+ bounds, counts);
369
382
  },
370
383
  [metric, &sink, &gauge_storage, &label_values,
371
384
  &label_keys](InstrumentMetadata::DoubleGaugeShape) {
@@ -435,10 +448,10 @@ void MetricsQuery::Apply(InstrumentLabelList label_names,
435
448
  uint64_up_down_counters_[ConstructKey(label_values, name)] += value;
436
449
  }
437
450
 
438
- void Histogram(InstrumentLabelList /* label_keys */,
439
- absl::Span<const std::string> label_values,
440
- absl::string_view name, HistogramBuckets bounds,
441
- absl::Span<const uint64_t> counts) override {
451
+ void Int64Histogram(InstrumentLabelList /* label_keys */,
452
+ absl::Span<const std::string> label_values,
453
+ absl::string_view name, Int64HistogramBuckets bounds,
454
+ absl::Span<const uint64_t> counts) override {
442
455
  GRPC_CHECK_EQ(counts.size(), bounds.size());
443
456
  auto it = histograms_.find(ConstructKey(label_values, name));
444
457
  if (it == histograms_.end()) {
@@ -457,6 +470,28 @@ void MetricsQuery::Apply(InstrumentLabelList label_names,
457
470
  }
458
471
  }
459
472
 
473
+ void DoubleHistogram(InstrumentLabelList /* label_keys */,
474
+ absl::Span<const std::string> label_values,
475
+ absl::string_view name, DoubleHistogramBuckets bounds,
476
+ absl::Span<const uint64_t> counts) override {
477
+ GRPC_CHECK_EQ(counts.size(), bounds.size());
478
+ auto it = double_histograms_.find(ConstructKey(label_values, name));
479
+ if (it == double_histograms_.end()) {
480
+ double_histograms_.emplace(std::piecewise_construct,
481
+ std::tuple(ConstructKey(label_values, name)),
482
+ std::tuple(bounds, counts));
483
+ } else {
484
+ if (it->second.bounds != bounds) {
485
+ LOG(FATAL) << "Double histogram bounds mismatch for metric '" << name
486
+ << "': {" << absl::StrJoin(it->second.bounds, ",")
487
+ << "} vs {" << absl::StrJoin(bounds, ",") << "}";
488
+ }
489
+ for (size_t i = 0; i < counts.size(); ++i) {
490
+ it->second.counts[i] += counts[i];
491
+ }
492
+ }
493
+ }
494
+
460
495
  void DoubleGauge(InstrumentLabelList /* label_keys */,
461
496
  absl::Span<const std::string>, absl::string_view,
462
497
  double) override {
@@ -482,8 +517,12 @@ void MetricsQuery::Apply(InstrumentLabelList label_names,
482
517
  value);
483
518
  }
484
519
  for (const auto& [key, value] : histograms_) {
485
- sink.Histogram(label_keys_, std::get<0>(key), std::get<1>(key),
486
- value.bounds, value.counts);
520
+ sink.Int64Histogram(label_keys_, std::get<0>(key), std::get<1>(key),
521
+ value.bounds, value.counts);
522
+ }
523
+ for (const auto& [key, value] : double_histograms_) {
524
+ sink.DoubleHistogram(label_keys_, std::get<0>(key), std::get<1>(key),
525
+ value.bounds, value.counts);
487
526
  }
488
527
  }
489
528
 
@@ -507,15 +546,26 @@ void MetricsQuery::Apply(InstrumentLabelList label_names,
507
546
  absl::flat_hash_map<std::tuple<std::vector<std::string>, absl::string_view>,
508
547
  uint64_t>
509
548
  uint64_up_down_counters_;
510
- struct HistogramValue {
511
- HistogramValue(HistogramBuckets bounds, absl::Span<const uint64_t> counts)
549
+ struct Int64HistogramValue {
550
+ Int64HistogramValue(Int64HistogramBuckets bounds,
551
+ absl::Span<const uint64_t> counts)
512
552
  : bounds(bounds), counts(counts.begin(), counts.end()) {}
513
- HistogramBuckets bounds;
553
+ Int64HistogramBuckets bounds;
514
554
  std::vector<uint64_t> counts;
515
555
  };
516
556
  absl::flat_hash_map<std::tuple<std::vector<std::string>, absl::string_view>,
517
- HistogramValue>
557
+ Int64HistogramValue>
518
558
  histograms_;
559
+ struct DoubleHistogramValue {
560
+ DoubleHistogramValue(DoubleHistogramBuckets bounds,
561
+ absl::Span<const uint64_t> counts)
562
+ : bounds(bounds), counts(counts.begin(), counts.end()) {}
563
+ DoubleHistogramBuckets bounds;
564
+ std::vector<uint64_t> counts;
565
+ };
566
+ absl::flat_hash_map<std::tuple<std::vector<std::string>, absl::string_view>,
567
+ DoubleHistogramValue>
568
+ double_histograms_;
519
569
  };
520
570
  Filter filter(include_labels, label_keys);
521
571
  ApplyLabelChecks(label_names, fn, filter);
@@ -562,12 +612,20 @@ void MetricsQuery::ApplyLabelChecks(InstrumentLabelList label_names,
562
612
  sink_.UpDownCounter(label_keys, label_values, name, value);
563
613
  }
564
614
 
565
- void Histogram(InstrumentLabelList label_keys,
566
- absl::Span<const std::string> label_values,
567
- absl::string_view name, HistogramBuckets bounds,
568
- absl::Span<const uint64_t> counts) override {
615
+ void Int64Histogram(InstrumentLabelList label_keys,
616
+ absl::Span<const std::string> label_values,
617
+ absl::string_view name, Int64HistogramBuckets bounds,
618
+ absl::Span<const uint64_t> counts) override {
569
619
  if (!Matches(label_values)) return;
570
- sink_.Histogram(label_keys, label_values, name, bounds, counts);
620
+ sink_.Int64Histogram(label_keys, label_values, name, bounds, counts);
621
+ }
622
+
623
+ void DoubleHistogram(InstrumentLabelList label_keys,
624
+ absl::Span<const std::string> label_values,
625
+ absl::string_view name, DoubleHistogramBuckets bounds,
626
+ absl::Span<const uint64_t> counts) override {
627
+ if (!Matches(label_values)) return;
628
+ sink_.DoubleHistogram(label_keys, label_values, name, bounds, counts);
571
629
  }
572
630
 
573
631
  void DoubleGauge(InstrumentLabelList label_keys,
@@ -699,7 +757,18 @@ void DomainStorage::AddData(channelz::DataSink sink) {
699
757
  channelz::PropertyList().Set(
700
758
  "value", storage.GetUint(metric->offset)));
701
759
  },
702
- [&](const InstrumentMetadata::HistogramShape& h) {
760
+ [&](const InstrumentMetadata::Int64HistogramShape& h) {
761
+ channelz::PropertyTable table;
762
+ for (size_t i = 0; i < h.size(); ++i) {
763
+ table.AppendRow(
764
+ channelz::PropertyList()
765
+ .Set("bucket_max", h[i])
766
+ .Set("count", SumCounter(metric->offset + i)));
767
+ }
768
+ grid.SetRow(metric->name, channelz::PropertyList().Set(
769
+ "value", std::move(table)));
770
+ },
771
+ [&](const InstrumentMetadata::DoubleHistogramShape& h) {
703
772
  channelz::PropertyTable table;
704
773
  for (size_t i = 0; i < h.size(); ++i) {
705
774
  table.AppendRow(
@@ -727,41 +796,48 @@ void QueryableDomain::AddData(channelz::DataSink sink) {
727
796
  .Set("allocated_int_gauge_slots", allocated_int_gauge_slots_)
728
797
  .Set("allocated_uint_gauge_slots", allocated_uint_gauge_slots_)
729
798
  .Set("map_shards", map_shards_size_)
730
- .Set("metrics",
731
- [this]() {
732
- channelz::PropertyGrid grid;
733
- for (auto* metric : metrics_) {
734
- grid.SetRow(
735
- metric->name,
736
- channelz::PropertyList()
737
- .Set("description", metric->description)
738
- .Set("unit", metric->unit)
739
- .Set("offset", metric->offset)
740
- .Set("shape",
741
- Match(
742
- metric->shape,
743
- [](InstrumentMetadata::CounterShape)
744
- -> std::string { return "counter"; },
745
- [](InstrumentMetadata::UpDownCounterShape)
746
- -> std::string {
747
- return "up_down_counter";
748
- },
749
- [](InstrumentMetadata::DoubleGaugeShape)
750
- -> std::string {
751
- return "double_gauge";
752
- },
753
- [](InstrumentMetadata::IntGaugeShape)
754
- -> std::string { return "int_gauge"; },
755
- [](InstrumentMetadata::UintGaugeShape)
756
- -> std::string { return "uint_gauge"; },
757
- [](const InstrumentMetadata::HistogramShape&
758
- h) -> std::string {
759
- return absl::StrCat(
760
- "histogram:", absl::StrJoin(h, ","));
761
- })));
762
- }
763
- return grid;
764
- }())
799
+ .Set(
800
+ "metrics",
801
+ [this]() {
802
+ channelz::PropertyGrid grid;
803
+ for (auto* metric : metrics_) {
804
+ grid.SetRow(
805
+ metric->name,
806
+ channelz::PropertyList()
807
+ .Set("description", metric->description)
808
+ .Set("unit", metric->unit)
809
+ .Set("offset", metric->offset)
810
+ .Set(
811
+ "shape",
812
+ Match(
813
+ metric->shape,
814
+ [](InstrumentMetadata::CounterShape)
815
+ -> std::string { return "counter"; },
816
+ [](InstrumentMetadata::UpDownCounterShape)
817
+ -> std::string {
818
+ return "up_down_counter";
819
+ },
820
+ [](InstrumentMetadata::DoubleGaugeShape)
821
+ -> std::string { return "double_gauge"; },
822
+ [](InstrumentMetadata::IntGaugeShape)
823
+ -> std::string { return "int_gauge"; },
824
+ [](InstrumentMetadata::UintGaugeShape)
825
+ -> std::string { return "uint_gauge"; },
826
+ [](const InstrumentMetadata::
827
+ Int64HistogramShape& h)
828
+ -> std::string {
829
+ return absl::StrCat("histogram:",
830
+ absl::StrJoin(h, ","));
831
+ },
832
+ [](const InstrumentMetadata::
833
+ DoubleHistogramShape& h)
834
+ -> std::string {
835
+ return absl::StrCat("double_histogram:",
836
+ absl::StrJoin(h, ","));
837
+ })));
838
+ }
839
+ return grid;
840
+ }())
765
841
  .Set("labels", absl::StrJoin(label_names_, ",")));
766
842
  }
767
843
 
@@ -832,9 +908,19 @@ const InstrumentMetadata::Description* QueryableDomain::AllocateUpDownCounter(
832
908
  return desc;
833
909
  }
834
910
 
835
- const InstrumentMetadata::Description* QueryableDomain::AllocateHistogram(
911
+ const InstrumentMetadata::Description* QueryableDomain::AllocateInt64Histogram(
912
+ absl::string_view name, absl::string_view description,
913
+ absl::string_view unit, Int64HistogramBuckets bounds) {
914
+ const size_t offset = AllocateCounterSlots(bounds.size());
915
+ auto* desc = InstrumentIndex::Get().Register(this, offset, name, description,
916
+ unit, bounds);
917
+ metrics_.push_back(desc);
918
+ return desc;
919
+ }
920
+
921
+ const InstrumentMetadata::Description* QueryableDomain::AllocateDoubleHistogram(
836
922
  absl::string_view name, absl::string_view description,
837
- absl::string_view unit, HistogramBuckets bounds) {
923
+ absl::string_view unit, DoubleHistogramBuckets bounds) {
838
924
  const size_t offset = AllocateCounterSlots(bounds.size());
839
925
  auto* desc = InstrumentIndex::Get().Register(this, offset, name, description,
840
926
  unit, bounds);
@@ -1047,15 +1133,34 @@ RefCountedPtr<CollectionScope> GlobalCollectionScope() {
1047
1133
  }
1048
1134
 
1049
1135
  void TestOnlyResetInstruments() {
1050
- Hook* hook = hooks.load(std::memory_order_acquire);
1051
- while (hook != nullptr) {
1052
- Hook* next = hook->next;
1053
- delete hook;
1054
- hook = next;
1136
+ Hook<int64_t>* int64_hook = hooks<int64_t>.load(std::memory_order_acquire);
1137
+ while (int64_hook != nullptr) {
1138
+ Hook<int64_t>* next = int64_hook->next;
1139
+ delete int64_hook;
1140
+ int64_hook = next;
1055
1141
  }
1056
- hooks.store(nullptr, std::memory_order_release);
1142
+ hooks<int64_t>.store(nullptr, std::memory_order_release);
1143
+ Hook<double>* double_hook = hooks<double>.load(std::memory_order_acquire);
1144
+ while (double_hook != nullptr) {
1145
+ Hook<double>* next = double_hook->next;
1146
+ delete double_hook;
1147
+ double_hook = next;
1148
+ }
1149
+ hooks<double>.store(nullptr, std::memory_order_release);
1057
1150
  instrument_detail::QueryableDomain::TestOnlyResetAll();
1058
1151
  GlobalCollectionScopeManager::Get().TestOnlyReset();
1059
1152
  }
1060
1153
 
1154
+ template void RegisterInstrumentCollectionHook<int64_t>(
1155
+ InstrumentCollectionHook<int64_t> hook);
1156
+ template void RegisterInstrumentCollectionHook<double>(
1157
+ InstrumentCollectionHook<double> hook);
1158
+ namespace instrument_detail {
1159
+ template void CallInstrumentCollectionHooks<int64_t>(
1160
+ const InstrumentMetadata::Description* instrument,
1161
+ absl::Span<const std::string> labels, int64_t value);
1162
+ template void CallInstrumentCollectionHooks<double>(
1163
+ const InstrumentMetadata::Description* instrument,
1164
+ absl::Span<const std::string> labels, double value);
1165
+ } // namespace instrument_detail
1061
1166
  } // namespace grpc_core