grpc 1.39.0.pre1 → 1.40.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +34 -18
  3. data/include/grpc/event_engine/event_engine.h +10 -14
  4. data/include/grpc/event_engine/slice_allocator.h +8 -33
  5. data/include/grpc/impl/codegen/grpc_types.h +18 -8
  6. data/include/grpc/impl/codegen/port_platform.h +24 -0
  7. data/src/core/ext/filters/client_channel/client_channel.cc +413 -247
  8. data/src/core/ext/filters/client_channel/client_channel.h +42 -18
  9. data/src/core/ext/filters/client_channel/config_selector.h +19 -6
  10. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +7 -8
  11. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +12 -21
  12. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +3 -5
  13. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +17 -38
  14. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -15
  15. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +3 -6
  16. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +8 -12
  17. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +14 -22
  18. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +2 -9
  19. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +5 -8
  20. data/src/core/ext/filters/client_channel/lb_policy.cc +1 -15
  21. data/src/core/ext/filters/client_channel/lb_policy.h +70 -46
  22. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +101 -73
  23. data/src/core/ext/filters/client_channel/retry_filter.cc +392 -243
  24. data/src/core/ext/filters/client_channel/retry_service_config.cc +36 -26
  25. data/src/core/ext/filters/client_channel/retry_service_config.h +1 -1
  26. data/src/core/ext/filters/client_channel/service_config_call_data.h +45 -5
  27. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +0 -6
  28. data/src/core/ext/filters/http/client/http_client_filter.cc +5 -2
  29. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +5 -1
  30. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +1 -1
  31. data/src/core/{lib/event_engine/slice_allocator.cc → ext/transport/chttp2/transport/chttp2_slice_allocator.cc} +15 -38
  32. data/src/core/ext/transport/chttp2/transport/chttp2_slice_allocator.h +74 -0
  33. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -6
  34. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -1
  35. data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
  36. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +8 -8
  37. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +5 -5
  38. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +639 -752
  39. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +190 -69
  40. data/src/core/ext/transport/chttp2/transport/internal.h +1 -1
  41. data/src/core/ext/transport/chttp2/transport/parsing.cc +70 -54
  42. data/src/core/ext/transport/chttp2/transport/varint.cc +6 -4
  43. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c +56 -35
  44. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.h +180 -76
  45. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +35 -27
  46. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +97 -48
  47. data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c +45 -9
  48. data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h +67 -7
  49. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +66 -9
  50. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +227 -0
  51. data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.c +46 -0
  52. data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.h +121 -0
  53. data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c +1 -0
  54. data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.c +35 -0
  55. data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.h +90 -0
  56. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +32 -24
  57. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +120 -73
  58. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c +4 -2
  59. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h +15 -0
  60. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.c +48 -0
  61. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.h +171 -0
  62. data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c +8 -6
  63. data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h +27 -19
  64. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +1 -0
  65. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c +24 -7
  66. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h +57 -0
  67. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +29 -17
  68. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +72 -0
  69. data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c +3 -2
  70. data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.h +4 -0
  71. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c +6 -5
  72. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h +15 -11
  73. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +85 -43
  74. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +274 -91
  75. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c +11 -8
  76. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h +30 -13
  77. data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c +33 -5
  78. data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.h +115 -0
  79. data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.c +60 -0
  80. data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.h +181 -0
  81. data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c +1 -0
  82. data/src/core/ext/upb-generated/validate/validate.upb.c +82 -66
  83. data/src/core/ext/upb-generated/validate/validate.upb.h +220 -124
  84. data/src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c +15 -7
  85. data/src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c +53 -52
  86. data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +318 -277
  87. data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.h +5 -0
  88. data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c +437 -410
  89. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c +198 -170
  90. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.h +10 -0
  91. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c +9 -8
  92. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c +219 -163
  93. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.h +15 -0
  94. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/resolver.upbdefs.c +59 -0
  95. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/resolver.upbdefs.h +40 -0
  96. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c +29 -25
  97. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/udp_socket_config.upbdefs.c +52 -0
  98. data/src/core/ext/upbdefs-generated/envoy/config/core/v3/udp_socket_config.upbdefs.h +35 -0
  99. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c +135 -125
  100. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.h +5 -0
  101. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c +131 -123
  102. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/quic_config.upbdefs.c +90 -0
  103. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/quic_config.upbdefs.h +35 -0
  104. data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c +32 -24
  105. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c +69 -55
  106. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.h +5 -0
  107. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c +684 -664
  108. data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.h +5 -0
  109. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c +13 -10
  110. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c +13 -10
  111. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +441 -375
  112. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h +10 -0
  113. data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c +122 -114
  114. data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c +1 -1
  115. data/src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.c +112 -79
  116. data/src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.h +5 -0
  117. data/src/core/ext/upbdefs-generated/envoy/type/http/v3/path_transformation.upbdefs.c +64 -0
  118. data/src/core/ext/upbdefs-generated/envoy/type/http/v3/path_transformation.upbdefs.h +50 -0
  119. data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c +35 -32
  120. data/src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c +4 -4
  121. data/src/core/ext/upbdefs-generated/validate/validate.upbdefs.c +182 -160
  122. data/src/core/ext/xds/certificate_provider_store.h +1 -1
  123. data/src/core/ext/xds/xds_api.cc +320 -121
  124. data/src/core/ext/xds/xds_api.h +31 -2
  125. data/src/core/ext/xds/xds_bootstrap.cc +4 -1
  126. data/src/core/ext/xds/xds_client.cc +66 -43
  127. data/src/core/ext/xds/xds_client.h +0 -4
  128. data/src/core/ext/xds/xds_http_filters.cc +3 -2
  129. data/src/core/ext/xds/xds_http_filters.h +3 -0
  130. data/src/core/lib/channel/call_tracer.h +85 -0
  131. data/src/core/lib/channel/channel_stack.h +1 -1
  132. data/src/core/lib/channel/context.h +3 -0
  133. data/src/core/lib/channel/status_util.h +4 -0
  134. data/src/core/lib/compression/stream_compression.h +1 -1
  135. data/src/core/lib/compression/stream_compression_gzip.h +1 -1
  136. data/src/core/lib/compression/stream_compression_identity.h +1 -1
  137. data/src/core/lib/debug/stats.h +1 -1
  138. data/src/core/lib/gpr/murmur_hash.cc +4 -2
  139. data/src/core/lib/gprpp/manual_constructor.h +1 -1
  140. data/src/core/lib/gprpp/orphanable.h +3 -3
  141. data/src/core/lib/gprpp/sync.h +2 -30
  142. data/src/core/lib/iomgr/buffer_list.cc +1 -1
  143. data/src/core/lib/iomgr/ev_apple.h +1 -1
  144. data/src/core/lib/iomgr/event_engine/endpoint.cc +6 -8
  145. data/src/core/lib/iomgr/event_engine/tcp.cc +30 -10
  146. data/src/core/lib/iomgr/python_util.h +1 -1
  147. data/src/core/lib/iomgr/resource_quota.cc +2 -0
  148. data/src/core/lib/iomgr/tcp_client_windows.cc +2 -0
  149. data/src/core/lib/iomgr/tcp_server_posix.cc +1 -0
  150. data/src/core/lib/iomgr/timer_manager.cc +1 -1
  151. data/src/core/lib/json/json_reader.cc +1 -2
  152. data/src/core/lib/matchers/matchers.cc +8 -20
  153. data/src/core/lib/matchers/matchers.h +2 -1
  154. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +49 -0
  155. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +7 -0
  156. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +6 -18
  157. data/src/core/lib/security/transport/security_handshaker.cc +12 -4
  158. data/src/core/lib/security/transport/server_auth_filter.cc +0 -7
  159. data/src/core/lib/slice/slice_internal.h +1 -0
  160. data/src/core/lib/surface/call.cc +5 -6
  161. data/src/core/lib/surface/server.cc +3 -1
  162. data/src/core/lib/surface/server.h +3 -3
  163. data/src/core/lib/surface/version.cc +2 -4
  164. data/src/ruby/ext/grpc/extconf.rb +1 -1
  165. data/src/ruby/lib/grpc/version.rb +1 -1
  166. data/third_party/xxhash/xxhash.h +77 -195
  167. metadata +57 -40
  168. data/src/core/lib/gpr/arena.h +0 -47
@@ -387,12 +387,9 @@ void WeightedTargetLb::UpdateStateLocked() {
387
387
  absl::make_unique<QueuePicker>(Ref(DEBUG_LOCATION, "QueuePicker"));
388
388
  break;
389
389
  default:
390
- grpc_error_handle error = grpc_error_set_int(
391
- GRPC_ERROR_CREATE_FROM_STATIC_STRING(
392
- "weighted_target: all children report state TRANSIENT_FAILURE"),
393
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
394
- status = grpc_error_to_absl_status(error);
395
- picker = absl::make_unique<TransientFailurePicker>(error);
390
+ status = absl::UnavailableError(
391
+ "weighted_target: all children report state TRANSIENT_FAILURE");
392
+ picker = absl::make_unique<TransientFailurePicker>(status);
396
393
  }
397
394
  channel_control_helper()->UpdateState(connectivity_state, status,
398
395
  std::move(picker));
@@ -536,12 +536,12 @@ void CdsLb::OnError(const std::string& name, grpc_error_handle error) {
536
536
  // policy (i.e., we have not yet received data from xds). Otherwise,
537
537
  // we keep running with the data we had previously.
538
538
  if (child_policy_ == nullptr) {
539
+ absl::Status status = grpc_error_to_absl_status(error);
539
540
  channel_control_helper()->UpdateState(
540
- GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
541
- absl::make_unique<TransientFailurePicker>(error));
542
- } else {
543
- GRPC_ERROR_UNREF(error);
541
+ GRPC_CHANNEL_TRANSIENT_FAILURE, status,
542
+ absl::make_unique<TransientFailurePicker>(status));
544
543
  }
544
+ GRPC_ERROR_UNREF(error);
545
545
  }
546
546
 
547
547
  void CdsLb::OnResourceDoesNotExist(const std::string& name) {
@@ -549,15 +549,11 @@ void CdsLb::OnResourceDoesNotExist(const std::string& name) {
549
549
  "[cdslb %p] CDS resource for %s does not exist -- reporting "
550
550
  "TRANSIENT_FAILURE",
551
551
  this, name.c_str());
552
- grpc_error_handle error =
553
- grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
554
- absl::StrCat("CDS resource \"", config_->cluster(),
555
- "\" does not exist")
556
- .c_str()),
557
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
552
+ absl::Status status = absl::UnavailableError(
553
+ absl::StrCat("CDS resource \"", config_->cluster(), "\" does not exist"));
558
554
  channel_control_helper()->UpdateState(
559
- GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
560
- absl::make_unique<TransientFailurePicker>(error));
555
+ GRPC_CHANNEL_TRANSIENT_FAILURE, status,
556
+ absl::make_unique<TransientFailurePicker>(status));
561
557
  MaybeDestroyChildPolicyLocked();
562
558
  }
563
559
 
@@ -284,59 +284,51 @@ LoadBalancingPolicy::PickResult XdsClusterImplLb::Picker::Pick(
284
284
  const std::string* drop_category;
285
285
  if (drop_config_->ShouldDrop(&drop_category)) {
286
286
  if (drop_stats_ != nullptr) drop_stats_->AddCallDropped(*drop_category);
287
- PickResult result;
288
- result.type = PickResult::PICK_COMPLETE;
289
- return result;
287
+ return PickResult::Drop(absl::UnavailableError(
288
+ absl::StrCat("EDS-configured drop: ", *drop_category)));
290
289
  }
291
290
  // Handle circuit breaking.
292
291
  uint32_t current = call_counter_->Load();
293
292
  // Check and see if we exceeded the max concurrent requests count.
294
293
  if (current >= max_concurrent_requests_) {
295
294
  if (drop_stats_ != nullptr) drop_stats_->AddUncategorizedDrops();
296
- PickResult result;
297
- result.type = PickResult::PICK_COMPLETE;
298
- return result;
295
+ return PickResult::Drop(absl::UnavailableError("circuit breaker drop"));
299
296
  }
300
297
  call_counter_->Increment();
301
298
  // If we're not dropping the call, we should always have a child picker.
302
299
  if (picker_ == nullptr) { // Should never happen.
303
- PickResult result;
304
- result.type = PickResult::PICK_FAILED;
305
- result.error = grpc_error_set_int(
306
- GRPC_ERROR_CREATE_FROM_STATIC_STRING(
307
- "xds_cluster_impl picker not given any child picker"),
308
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
309
300
  call_counter_->Decrement();
310
- return result;
301
+ return PickResult::Fail(absl::InternalError(
302
+ "xds_cluster_impl picker not given any child picker"));
311
303
  }
312
304
  // Not dropping, so delegate to child picker.
313
305
  PickResult result = picker_->Pick(args);
314
- if (result.type == result.PICK_COMPLETE && result.subchannel != nullptr) {
306
+ auto* complete_pick = absl::get_if<PickResult::Complete>(&result.result);
307
+ if (complete_pick != nullptr) {
315
308
  XdsClusterLocalityStats* locality_stats = nullptr;
316
309
  if (drop_stats_ != nullptr) { // If load reporting is enabled.
317
310
  auto* subchannel_wrapper =
318
- static_cast<StatsSubchannelWrapper*>(result.subchannel.get());
311
+ static_cast<StatsSubchannelWrapper*>(complete_pick->subchannel.get());
319
312
  // Handle load reporting.
320
313
  locality_stats = subchannel_wrapper->locality_stats()->Ref().release();
321
314
  // Record a call started.
322
315
  locality_stats->AddCallStarted();
323
316
  // Unwrap subchannel to pass back up the stack.
324
- result.subchannel = subchannel_wrapper->wrapped_subchannel();
317
+ complete_pick->subchannel = subchannel_wrapper->wrapped_subchannel();
325
318
  }
326
319
  // Intercept the recv_trailing_metadata op to record call completion.
327
320
  auto* call_counter = call_counter_->Ref(DEBUG_LOCATION, "call").release();
328
321
  auto original_recv_trailing_metadata_ready =
329
- result.recv_trailing_metadata_ready;
330
- result.recv_trailing_metadata_ready =
322
+ complete_pick->recv_trailing_metadata_ready;
323
+ complete_pick->recv_trailing_metadata_ready =
331
324
  // Note: This callback does not run in either the control plane
332
325
  // work serializer or in the data plane mutex.
333
326
  [locality_stats, original_recv_trailing_metadata_ready, call_counter](
334
- grpc_error_handle error, MetadataInterface* metadata,
327
+ absl::Status status, MetadataInterface* metadata,
335
328
  CallState* call_state) {
336
329
  // Record call completion for load reporting.
337
330
  if (locality_stats != nullptr) {
338
- const bool call_failed = error != GRPC_ERROR_NONE;
339
- locality_stats->AddCallFinished(call_failed);
331
+ locality_stats->AddCallFinished(!status.ok());
340
332
  locality_stats->Unref(DEBUG_LOCATION, "LocalityStats+call");
341
333
  }
342
334
  // Decrement number of calls in flight.
@@ -344,7 +336,7 @@ LoadBalancingPolicy::PickResult XdsClusterImplLb::Picker::Pick(
344
336
  call_counter->Unref(DEBUG_LOCATION, "call");
345
337
  // Invoke the original recv_trailing_metadata_ready callback, if any.
346
338
  if (original_recv_trailing_metadata_ready != nullptr) {
347
- original_recv_trailing_metadata_ready(error, metadata, call_state);
339
+ original_recv_trailing_metadata_ready(status, metadata, call_state);
348
340
  }
349
341
  };
350
342
  } else {
@@ -212,15 +212,8 @@ XdsClusterManagerLb::PickResult XdsClusterManagerLb::ClusterPicker::Pick(
212
212
  if (it != cluster_map_.end()) {
213
213
  return it->second->Pick(args);
214
214
  }
215
- PickResult result;
216
- result.type = PickResult::PICK_FAILED;
217
- result.error = grpc_error_set_int(
218
- GRPC_ERROR_CREATE_FROM_COPIED_STRING(
219
- absl::StrCat("xds cluster manager picker: unknown cluster \"",
220
- cluster_name, "\"")
221
- .c_str()),
222
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
223
- return result;
215
+ return PickResult::Fail(absl::InternalError(absl::StrCat(
216
+ "xds cluster manager picker: unknown cluster \"", cluster_name, "\"")));
224
217
  }
225
218
 
226
219
  //
@@ -1027,15 +1027,12 @@ XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
1027
1027
  "config -- "
1028
1028
  "will put channel in TRANSIENT_FAILURE: %s",
1029
1029
  this, grpc_error_std_string(error).c_str());
1030
- error = grpc_error_set_int(
1031
- grpc_error_add_child(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
1032
- "xds_cluster_resolver LB policy: error "
1033
- "parsing generated child policy config"),
1034
- error),
1035
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
1030
+ absl::Status status = absl::InternalError(
1031
+ "xds_cluster_resolver LB policy: error parsing generated child policy "
1032
+ "config");
1036
1033
  channel_control_helper()->UpdateState(
1037
- GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
1038
- absl::make_unique<TransientFailurePicker>(error));
1034
+ GRPC_CHANNEL_TRANSIENT_FAILURE, status,
1035
+ absl::make_unique<TransientFailurePicker>(status));
1039
1036
  return nullptr;
1040
1037
  }
1041
1038
  return config;
@@ -125,21 +125,7 @@ LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick(
125
125
  parent, nullptr),
126
126
  GRPC_ERROR_NONE);
127
127
  }
128
- PickResult result;
129
- result.type = PickResult::PICK_QUEUE;
130
- return result;
131
- }
132
-
133
- //
134
- // LoadBalancingPolicy::TransientFailurePicker
135
- //
136
-
137
- LoadBalancingPolicy::PickResult
138
- LoadBalancingPolicy::TransientFailurePicker::Pick(PickArgs /*args*/) {
139
- PickResult result;
140
- result.type = PickResult::PICK_FAILED;
141
- result.error = GRPC_ERROR_REF(error_);
142
- return result;
128
+ return PickResult::Queue();
143
129
  }
144
130
 
145
131
  } // namespace grpc_core
@@ -26,6 +26,7 @@
26
26
 
27
27
  #include "absl/status/status.h"
28
28
  #include "absl/strings/string_view.h"
29
+ #include "absl/types/variant.h"
29
30
 
30
31
  #include "src/core/ext/filters/client_channel/server_address.h"
31
32
  #include "src/core/ext/filters/client_channel/service_config.h"
@@ -204,47 +205,69 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
204
205
 
205
206
  /// The result of picking a subchannel for a call.
206
207
  struct PickResult {
207
- enum ResultType {
208
- /// Pick complete. If \a subchannel is non-null, the client channel
209
- /// will immediately proceed with the call on that subchannel;
210
- /// otherwise, it will drop the call.
211
- PICK_COMPLETE,
212
- /// Pick cannot be completed until something changes on the control
213
- /// plane. The client channel will queue the pick and try again the
214
- /// next time the picker is updated.
215
- PICK_QUEUE,
216
- /// Pick failed. If the call is wait_for_ready, the client channel
217
- /// will wait for the next picker and try again; otherwise, it
218
- /// will immediately fail the call with the status indicated via
219
- /// \a error (although the call may be retried if the client channel
220
- /// is configured to do so).
221
- PICK_FAILED,
208
+ /// A successful pick.
209
+ struct Complete {
210
+ /// The subchannel to be used for the call. Must be non-null.
211
+ RefCountedPtr<SubchannelInterface> subchannel;
212
+
213
+ /// Callback set by LB policy to be notified of trailing metadata.
214
+ /// If non-null, the client channel will invoke the callback
215
+ /// when trailing metadata is returned.
216
+ /// The metadata may be modified by the callback. However, the callback
217
+ /// does not take ownership, so any data that needs to be used after
218
+ /// returning must be copied.
219
+ /// The call state can be used to obtain backend metric data.
220
+ // TODO(roth): The arguments to this callback should be moved into a
221
+ // struct, so that we can later add new fields without breaking
222
+ // existing implementations.
223
+ std::function<void(absl::Status, MetadataInterface*, CallState*)>
224
+ recv_trailing_metadata_ready;
225
+
226
+ explicit Complete(
227
+ RefCountedPtr<SubchannelInterface> sc,
228
+ std::function<void(absl::Status, MetadataInterface*, CallState*)> cb =
229
+ nullptr)
230
+ : subchannel(std::move(sc)),
231
+ recv_trailing_metadata_ready(std::move(cb)) {}
222
232
  };
223
- ResultType type;
224
-
225
- /// Used only if type is PICK_COMPLETE. Will be set to the selected
226
- /// subchannel, or nullptr if the LB policy decides to drop the call.
227
- RefCountedPtr<SubchannelInterface> subchannel;
228
-
229
- /// Used only if type is PICK_FAILED.
230
- /// Error to be set when returning a failure.
231
- // TODO(roth): Replace this with something similar to grpc::Status,
232
- // so that we don't expose grpc_error to this API.
233
- grpc_error_handle error = GRPC_ERROR_NONE;
234
-
235
- /// Used only if type is PICK_COMPLETE.
236
- /// Callback set by LB policy to be notified of trailing metadata.
237
- /// If set by LB policy, the client channel will invoke the callback
238
- /// when trailing metadata is returned.
239
- /// The metadata may be modified by the callback. However, the callback
240
- /// does not take ownership, so any data that needs to be used after
241
- /// returning must be copied.
242
- /// The call state can be used to obtain backend metric data.
243
- // TODO(roth): The arguments to this callback should be moved into a
244
- // struct, so that we can later add new fields without breaking
245
- // existing implementations.
246
- std::function<void(grpc_error_handle, MetadataInterface*, CallState*)>
247
- recv_trailing_metadata_ready;
233
+
234
+ /// Pick cannot be completed until something changes on the control
235
+ /// plane. The client channel will queue the pick and try again the
236
+ /// next time the picker is updated.
237
+ struct Queue {};
238
+
239
+ /// Pick failed. If the call is wait_for_ready, the client channel
240
+ /// will wait for the next picker and try again; otherwise, it
241
+ /// will immediately fail the call with the status indicated (although
242
+ /// the call may be retried if the client channel is configured to do so).
243
+ struct Fail {
244
+ absl::Status status;
245
+
246
+ explicit Fail(absl::Status s) : status(s) {}
247
+ };
248
+
249
+ /// Pick will be dropped with the status specified.
250
+ /// Unlike FailPick, the call will be dropped even if it is
251
+ /// wait_for_ready, and retries (if configured) will be inhibited.
252
+ struct Drop {
253
+ absl::Status status;
254
+
255
+ explicit Drop(absl::Status s) : status(s) {}
256
+ };
257
+
258
+ // A pick result must be one of these types.
259
+ // Default to Queue, just to allow default construction.
260
+ absl::variant<Complete, Queue, Fail, Drop> result = Queue();
261
+
262
+ PickResult() = default;
263
+ // NOLINTNEXTLINE(google-explicit-constructor)
264
+ PickResult(Complete complete) : result(std::move(complete)) {}
265
+ // NOLINTNEXTLINE(google-explicit-constructor)
266
+ PickResult(Queue queue) : result(queue) {}
267
+ // NOLINTNEXTLINE(google-explicit-constructor)
268
+ PickResult(Fail fail) : result(std::move(fail)) {}
269
+ // NOLINTNEXTLINE(google-explicit-constructor)
270
+ PickResult(Drop drop) : result(std::move(drop)) {}
248
271
  };
249
272
 
250
273
  /// A subchannel picker is the object used to pick the subchannel to
@@ -367,7 +390,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
367
390
  // Note: This must be invoked while holding the work_serializer.
368
391
  void Orphan() override;
369
392
 
370
- // A picker that returns PICK_QUEUE for all picks.
393
+ // A picker that returns PickResult::Queue for all picks.
371
394
  // Also calls the parent LB policy's ExitIdleLocked() method when the
372
395
  // first pick is seen.
373
396
  class QueuePicker : public SubchannelPicker {
@@ -384,16 +407,17 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
384
407
  bool exit_idle_called_ = false;
385
408
  };
386
409
 
387
- // A picker that returns PICK_TRANSIENT_FAILURE for all picks.
410
+ // A picker that returns PickResult::Fail for all picks.
388
411
  class TransientFailurePicker : public SubchannelPicker {
389
412
  public:
390
- explicit TransientFailurePicker(grpc_error_handle error) : error_(error) {}
391
- ~TransientFailurePicker() override { GRPC_ERROR_UNREF(error_); }
413
+ explicit TransientFailurePicker(absl::Status status) : status_(status) {}
392
414
 
393
- PickResult Pick(PickArgs args) override;
415
+ PickResult Pick(PickArgs /*args*/) override {
416
+ return PickResult::Fail(status_);
417
+ }
394
418
 
395
419
  private:
396
- grpc_error_handle error_;
420
+ absl::Status status_;
397
421
  };
398
422
 
399
423
  protected:
@@ -34,7 +34,6 @@
34
34
  #include "src/core/lib/channel/channel_args.h"
35
35
  #include "src/core/lib/iomgr/closure.h"
36
36
  #include "src/core/lib/iomgr/exec_ctx.h"
37
- #include "src/core/lib/surface/lame_client.h"
38
37
  #include "src/core/lib/transport/timeout_encoding.h"
39
38
 
40
39
  namespace grpc_core {
@@ -130,23 +129,68 @@ class XdsResolver : public Resolver {
130
129
  RefCountedPtr<XdsResolver> resolver_;
131
130
  };
132
131
 
133
- class ClusterState
134
- : public RefCounted<ClusterState, PolymorphicRefCount, kUnrefNoDelete> {
132
+ // An entry in the map of clusters that need to be present in the LB
133
+ // policy config. The map holds a weak ref. One strong ref is held by
134
+ // the ConfigSelector, and another is held by each call assigned to
135
+ // the cluster by the ConfigSelector. The ref for each call is held
136
+ // until the call is committed. When the strong refs go away, we hop
137
+ // back into the WorkSerializer to remove the entry from the map.
138
+ class ClusterState : public DualRefCounted<ClusterState> {
135
139
  public:
136
140
  using ClusterStateMap =
137
- std::map<std::string, std::unique_ptr<ClusterState>>;
141
+ std::map<std::string, WeakRefCountedPtr<ClusterState>>;
138
142
 
139
- ClusterState(const std::string& cluster_name,
140
- ClusterStateMap* cluster_state_map)
141
- : it_(cluster_state_map
142
- ->emplace(cluster_name, std::unique_ptr<ClusterState>(this))
143
+ ClusterState(RefCountedPtr<XdsResolver> resolver,
144
+ const std::string& cluster_name)
145
+ : resolver_(std::move(resolver)),
146
+ it_(resolver_->cluster_state_map_.emplace(cluster_name, WeakRef())
143
147
  .first) {}
148
+
149
+ void Orphan() override {
150
+ auto* resolver = resolver_.release();
151
+ resolver->work_serializer_->Run(
152
+ [resolver]() {
153
+ resolver->MaybeRemoveUnusedClusters();
154
+ resolver->Unref();
155
+ },
156
+ DEBUG_LOCATION);
157
+ }
158
+
144
159
  const std::string& cluster() const { return it_->first; }
145
160
 
146
161
  private:
162
+ RefCountedPtr<XdsResolver> resolver_;
147
163
  ClusterStateMap::iterator it_;
148
164
  };
149
165
 
166
+ // Call dispatch controller, created for each call handled by the
167
+ // ConfigSelector. Holds a ref to the ClusterState object until the
168
+ // call is committed.
169
+ class XdsCallDispatchController
170
+ : public ConfigSelector::CallDispatchController {
171
+ public:
172
+ explicit XdsCallDispatchController(
173
+ RefCountedPtr<ClusterState> cluster_state)
174
+ : cluster_state_(std::move(cluster_state)) {}
175
+
176
+ bool ShouldRetry() override {
177
+ // TODO(donnadionne): Implement the retry circuit breaker here.
178
+ return true;
179
+ }
180
+
181
+ void Commit() override {
182
+ // TODO(donnadionne): If ShouldRetry() was called previously,
183
+ // decrement the retry circuit breaker counter.
184
+ cluster_state_.reset();
185
+ }
186
+
187
+ private:
188
+ // Note: The XdsCallDispatchController object is never actually destroyed,
189
+ // so do not add any data members that require destruction unless you have
190
+ // some other way to clean them up.
191
+ RefCountedPtr<ClusterState> cluster_state_;
192
+ };
193
+
150
194
  class XdsConfigSelector : public ConfigSelector {
151
195
  public:
152
196
  XdsConfigSelector(RefCountedPtr<XdsResolver> resolver,
@@ -198,7 +242,6 @@ class XdsResolver : public Resolver {
198
242
  RouteTable route_table_;
199
243
  std::map<absl::string_view, RefCountedPtr<ClusterState>> clusters_;
200
244
  std::vector<const grpc_channel_filter*> filters_;
201
- grpc_error_handle filter_error_ = GRPC_ERROR_NONE;
202
245
  };
203
246
 
204
247
  void OnListenerUpdate(XdsApi::LdsUpdate listener);
@@ -377,16 +420,8 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector(
377
420
  }
378
421
  }
379
422
  // Populate filter list.
380
- bool found_router = false;
381
423
  for (const auto& http_filter :
382
424
  resolver_->current_listener_.http_connection_manager.http_filters) {
383
- // Stop at the router filter. It's a no-op for us, and we ignore
384
- // anything that may come after it, for compatibility with Envoy.
385
- if (http_filter.config.config_proto_type_name ==
386
- kXdsHttpRouterFilterConfigName) {
387
- found_router = true;
388
- break;
389
- }
390
425
  // Find filter. This is guaranteed to succeed, because it's checked
391
426
  // at config validation time in the XdsApi code.
392
427
  const XdsHttpFilterImpl* filter_impl =
@@ -394,16 +429,9 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector(
394
429
  http_filter.config.config_proto_type_name);
395
430
  GPR_ASSERT(filter_impl != nullptr);
396
431
  // Add C-core filter to list.
397
- filters_.push_back(filter_impl->channel_filter());
398
- }
399
- // For compatibility with Envoy, if the router filter is not
400
- // configured, we fail all RPCs.
401
- if (!found_router) {
402
- filter_error_ =
403
- grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
404
- "no xDS HTTP router filter configured"),
405
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
406
- filters_.push_back(&grpc_lame_filter);
432
+ if (filter_impl->channel_filter() != nullptr) {
433
+ filters_.push_back(filter_impl->channel_filter());
434
+ }
407
435
  }
408
436
  }
409
437
 
@@ -414,7 +442,6 @@ XdsResolver::XdsConfigSelector::~XdsConfigSelector() {
414
442
  }
415
443
  clusters_.clear();
416
444
  resolver_->MaybeRemoveUnusedClusters();
417
- GRPC_ERROR_UNREF(filter_error_);
418
445
  }
419
446
 
420
447
  const XdsHttpFilterImpl::FilterConfig* FindFilterConfigOverride(
@@ -441,6 +468,42 @@ grpc_error_handle XdsResolver::XdsConfigSelector::CreateMethodConfig(
441
468
  const XdsApi::Route::ClusterWeight* cluster_weight,
442
469
  RefCountedPtr<ServiceConfig>* method_config) {
443
470
  std::vector<std::string> fields;
471
+ // Set retry policy if any.
472
+ if (route.retry_policy.has_value()) {
473
+ std::vector<std::string> retry_parts;
474
+ retry_parts.push_back(absl::StrFormat(
475
+ "\"retryPolicy\": {\n"
476
+ " \"maxAttempts\": %d,\n"
477
+ " \"initialBackoff\": \"%d.%09ds\",\n"
478
+ " \"maxBackoff\": \"%d.%09ds\",\n"
479
+ " \"backoffMultiplier\": 2,\n",
480
+ route.retry_policy->num_retries + 1,
481
+ route.retry_policy->retry_back_off.base_interval.seconds,
482
+ route.retry_policy->retry_back_off.base_interval.nanos,
483
+ route.retry_policy->retry_back_off.max_interval.seconds,
484
+ route.retry_policy->retry_back_off.max_interval.nanos));
485
+ std::vector<std::string> code_parts;
486
+ if (route.retry_policy->retry_on.Contains(GRPC_STATUS_CANCELLED)) {
487
+ code_parts.push_back(" \"CANCELLED\"");
488
+ }
489
+ if (route.retry_policy->retry_on.Contains(GRPC_STATUS_DEADLINE_EXCEEDED)) {
490
+ code_parts.push_back(" \"DEADLINE_EXCEEDED\"");
491
+ }
492
+ if (route.retry_policy->retry_on.Contains(GRPC_STATUS_INTERNAL)) {
493
+ code_parts.push_back(" \"INTERNAL\"");
494
+ }
495
+ if (route.retry_policy->retry_on.Contains(GRPC_STATUS_RESOURCE_EXHAUSTED)) {
496
+ code_parts.push_back(" \"RESOURCE_EXHAUSTED\"");
497
+ }
498
+ if (route.retry_policy->retry_on.Contains(GRPC_STATUS_UNAVAILABLE)) {
499
+ code_parts.push_back(" \"UNAVAILABLE\"");
500
+ }
501
+ retry_parts.push_back(
502
+ absl::StrFormat(" \"retryableStatusCodes\": [\n %s ]\n",
503
+ absl::StrJoin(code_parts, ",\n")));
504
+ retry_parts.push_back(absl::StrFormat(" }"));
505
+ fields.emplace_back(absl::StrJoin(retry_parts, ""));
506
+ }
444
507
  // Set timeout.
445
508
  if (route.max_stream_duration.has_value() &&
446
509
  (route.max_stream_duration->seconds != 0 ||
@@ -454,18 +517,15 @@ grpc_error_handle XdsResolver::XdsConfigSelector::CreateMethodConfig(
454
517
  grpc_channel_args* args = grpc_channel_args_copy(resolver_->args_);
455
518
  for (const auto& http_filter :
456
519
  resolver_->current_listener_.http_connection_manager.http_filters) {
457
- // Stop at the router filter. It's a no-op for us, and we ignore
458
- // anything that may come after it, for compatibility with Envoy.
459
- if (http_filter.config.config_proto_type_name ==
460
- kXdsHttpRouterFilterConfigName) {
461
- break;
462
- }
463
520
  // Find filter. This is guaranteed to succeed, because it's checked
464
521
  // at config validation time in the XdsApi code.
465
522
  const XdsHttpFilterImpl* filter_impl =
466
523
  XdsHttpFilterRegistry::GetFilterForType(
467
524
  http_filter.config.config_proto_type_name);
468
525
  GPR_ASSERT(filter_impl != nullptr);
526
+ // If there is not actually any C-core filter associated with this
527
+ // xDS filter, then it won't need any config, so skip it.
528
+ if (filter_impl->channel_filter() == nullptr) continue;
469
529
  // Allow filter to add channel args that may affect service config
470
530
  // parsing.
471
531
  args = filter_impl->ModifyChannelArgs(args);
@@ -513,20 +573,14 @@ grpc_error_handle XdsResolver::XdsConfigSelector::CreateMethodConfig(
513
573
 
514
574
  grpc_channel_args* XdsResolver::XdsConfigSelector::ModifyChannelArgs(
515
575
  grpc_channel_args* args) {
516
- if (filter_error_ == GRPC_ERROR_NONE) return args;
517
- grpc_arg error_arg = MakeLameClientErrorArg(filter_error_);
518
- grpc_channel_args* new_args =
519
- grpc_channel_args_copy_and_add(args, &error_arg, 1);
520
- grpc_channel_args_destroy(args);
521
- return new_args;
576
+ return args;
522
577
  }
523
578
 
524
579
  void XdsResolver::XdsConfigSelector::MaybeAddCluster(const std::string& name) {
525
580
  if (clusters_.find(name) == clusters_.end()) {
526
581
  auto it = resolver_->cluster_state_map_.find(name);
527
582
  if (it == resolver_->cluster_state_map_.end()) {
528
- auto new_cluster_state =
529
- MakeRefCounted<ClusterState>(name, &resolver_->cluster_state_map_);
583
+ auto new_cluster_state = MakeRefCounted<ClusterState>(resolver_, name);
530
584
  clusters_[new_cluster_state->cluster()] = std::move(new_cluster_state);
531
585
  } else {
532
586
  clusters_[it->second->cluster()] = it->second->Ref();
@@ -641,10 +695,7 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
641
695
  }
642
696
  auto it = clusters_.find(cluster_name);
643
697
  GPR_ASSERT(it != clusters_.end());
644
- XdsResolver* resolver =
645
- static_cast<XdsResolver*>(resolver_->Ref().release());
646
- ClusterState* cluster_state = it->second->Ref().release();
647
- // Generate a hash
698
+ // Generate a hash.
648
699
  absl::optional<uint64_t> hash;
649
700
  for (const auto& hash_policy : entry.route.hash_policies) {
650
701
  absl::optional<uint64_t> new_hash;
@@ -653,8 +704,8 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
653
704
  new_hash = HeaderHashHelper(hash_policy, args.initial_metadata);
654
705
  break;
655
706
  case XdsApi::Route::HashPolicy::CHANNEL_ID:
656
- new_hash =
657
- static_cast<uint64_t>(reinterpret_cast<uintptr_t>(resolver));
707
+ new_hash = static_cast<uint64_t>(
708
+ reinterpret_cast<uintptr_t>(resolver_.get()));
658
709
  break;
659
710
  default:
660
711
  GPR_ASSERT(0);
@@ -694,31 +745,8 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
694
745
  memcpy(hash_value, hash_string.c_str(), hash_string.size());
695
746
  hash_value[hash_string.size()] = '\0';
696
747
  call_config.call_attributes[kRequestRingHashAttribute] = hash_value;
697
- call_config.on_call_committed = [resolver, cluster_state]() {
698
- cluster_state->Unref();
699
- ExecCtx::Run(
700
- // TODO(roth): This hop into the ExecCtx is being done to avoid
701
- // entering the WorkSerializer while holding the client channel data
702
- // plane mutex, since that can lead to deadlocks. However, we should
703
- // not have to solve this problem in each individual ConfigSelector
704
- // implementation. When we have time, we should fix the client channel
705
- // code to avoid this by not invoking the
706
- // CallConfig::on_call_committed callback until after it has released
707
- // the data plane mutex.
708
- DEBUG_LOCATION,
709
- GRPC_CLOSURE_CREATE(
710
- [](void* arg, grpc_error_handle /*error*/) {
711
- auto* resolver = static_cast<XdsResolver*>(arg);
712
- resolver->work_serializer_->Run(
713
- [resolver]() {
714
- resolver->MaybeRemoveUnusedClusters();
715
- resolver->Unref();
716
- },
717
- DEBUG_LOCATION);
718
- },
719
- resolver, nullptr),
720
- GRPC_ERROR_NONE);
721
- };
748
+ call_config.call_dispatch_controller =
749
+ args.arena->New<XdsCallDispatchController>(it->second->Ref());
722
750
  return call_config;
723
751
  }
724
752
  return CallConfig();