[context] Move ServiceConfigCallData to arena based context (#36779)

Closes #36779

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36779 from ctiller:ctx5 be0be931da
PiperOrigin-RevId: 639195392
pull/36794/head
Craig Tiller 9 months ago committed by Copybara-Service
parent d26a878e83
commit 05af32503c
  1. 2
      src/core/client_channel/client_channel.cc
  2. 20
      src/core/client_channel/client_channel_filter.cc
  3. 10
      src/core/client_channel/client_channel_internal.h
  4. 7
      src/core/client_channel/retry_filter.cc
  5. 3
      src/core/client_channel/retry_filter.h
  6. 15
      src/core/client_channel/retry_filter_legacy_call_data.cc
  7. 5
      src/core/ext/filters/fault_injection/fault_injection_filter.cc
  8. 3
      src/core/ext/filters/http/message_compress/compression_filter.cc
  9. 10
      src/core/ext/filters/message_size/message_size_filter.cc
  10. 3
      src/core/ext/filters/message_size/message_size_filter.h
  11. 5
      src/core/ext/filters/rbac/rbac_filter.cc
  12. 5
      src/core/ext/filters/stateful_session/stateful_session_filter.cc
  13. 9
      src/core/lib/channel/context.h
  14. 4
      src/core/lib/resource_quota/arena.h
  15. 5
      src/core/resolver/xds/xds_resolver.cc
  16. 3
      src/core/server/server_config_selector_filter.cc
  17. 23
      src/core/service_config/service_config_call_data.h
  18. 3
      src/core/service_config/service_config_channel_arg_filter.cc

@ -1350,7 +1350,7 @@ absl::Status ClientChannel::ApplyServiceConfigToCall(
// below us in the stack, and it will be cleaned up when the call ends.
auto* service_config_call_data =
GetContext<Arena>()->New<ClientChannelServiceConfigCallData>(
GetContext<Arena>(), GetContext<grpc_call_context_element>());
GetContext<Arena>());
// Use the ConfigSelector to determine the config for the call.
absl::Status call_config_status = config_selector.GetCallConfig(
{&client_initial_metadata, GetContext<Arena>(),

@ -444,10 +444,9 @@ const grpc_channel_filter ClientChannelFilter::kFilterVtableWithoutPromises = {
namespace {
ClientChannelServiceConfigCallData* GetServiceConfigCallData(
grpc_call_context_element* context) {
return static_cast<ClientChannelServiceConfigCallData*>(
context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
ClientChannelServiceConfigCallData* GetServiceConfigCallData(Arena* arena) {
return DownCast<ClientChannelServiceConfigCallData*>(
arena->GetContext<ServiceConfigCallData>());
}
class DynamicTerminationFilter final {
@ -482,7 +481,7 @@ class DynamicTerminationFilter final {
std::move(call_args),
[]() {
auto* service_config_call_data =
GetServiceConfigCallData(GetContext<grpc_call_context_element>());
GetServiceConfigCallData(GetContext<Arena>());
service_config_call_data->Commit();
},
/*is_transparent_retry=*/false);
@ -535,8 +534,7 @@ class DynamicTerminationFilter::CallData final {
calld->call_context_, calld->path_,
/*start_time=*/0, calld->deadline_,
calld->arena_, calld->call_combiner_};
auto* service_config_call_data =
GetServiceConfigCallData(calld->call_context_);
auto* service_config_call_data = GetServiceConfigCallData(calld->arena_);
calld->lb_call_ = client_channel->CreateLoadBalancedCall(
args, pollent, nullptr,
[service_config_call_data]() { service_config_call_data->Commit(); },
@ -2066,7 +2064,7 @@ grpc_error_handle ClientChannelFilter::CallData::ApplyServiceConfigToCallLocked(
// itself in the call context, so that it can be accessed by filters
// below us in the stack, and it will be cleaned up when the call ends.
auto* service_config_call_data =
arena()->New<ClientChannelServiceConfigCallData>(arena(), call_context());
arena()->New<ClientChannelServiceConfigCallData>(arena());
// Use the ConfigSelector to determine the config for the call.
absl::Status call_config_status =
(*config_selector)
@ -2546,8 +2544,7 @@ void ClientChannelFilter::FilterBasedCallData::
void* arg, grpc_error_handle error) {
auto* calld = static_cast<FilterBasedCallData*>(arg);
auto* chand = calld->chand();
auto* service_config_call_data =
GetServiceConfigCallData(calld->call_context());
auto* service_config_call_data = GetServiceConfigCallData(calld->arena());
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: got recv_trailing_metadata_ready: error=%s "
@ -2667,8 +2664,7 @@ class ClientChannelFilter::LoadBalancedCall::Metadata final
ServiceConfigCallData::CallAttributeInterface*
ClientChannelFilter::LoadBalancedCall::LbCallState::GetCallAttribute(
UniqueTypeName type) const {
auto* service_config_call_data =
GetServiceConfigCallData(lb_call_->call_context_);
auto* service_config_call_data = GetServiceConfigCallData(lb_call_->arena_);
return service_config_call_data->GetCallAttribute(type);
}

@ -58,9 +58,8 @@ class ClientChannelLbCallState : public LoadBalancingPolicy::CallState {
// Internal type for ServiceConfigCallData. Handles call commits.
class ClientChannelServiceConfigCallData final : public ServiceConfigCallData {
public:
ClientChannelServiceConfigCallData(Arena* arena,
grpc_call_context_element* call_context)
: ServiceConfigCallData(arena, call_context) {}
explicit ClientChannelServiceConfigCallData(Arena* arena)
: ServiceConfigCallData(arena) {}
void SetOnCommit(absl::AnyInvocable<void()> on_commit) {
CHECK(on_commit_ == nullptr);
@ -76,6 +75,11 @@ class ClientChannelServiceConfigCallData final : public ServiceConfigCallData {
absl::AnyInvocable<void()> on_commit_;
};
template <>
struct ContextSubclass<ClientChannelServiceConfigCallData> {
using Base = ServiceConfigCallData;
};
class SubchannelInterfaceWithCallDestination : public SubchannelInterface {
public:
using SubchannelInterface::SubchannelInterface;

@ -130,11 +130,8 @@ RetryFilter::RetryFilter(const ChannelArgs& args, grpc_error_handle* error)
server_name, config->max_milli_tokens(), config->milli_token_ratio());
}
const RetryMethodConfig* RetryFilter::GetRetryPolicy(
const grpc_call_context_element* context) {
if (context == nullptr) return nullptr;
auto* svc_cfg_call_data = static_cast<ServiceConfigCallData*>(
context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
const RetryMethodConfig* RetryFilter::GetRetryPolicy(Arena* arena) {
auto* svc_cfg_call_data = arena->GetContext<ServiceConfigCallData>();
if (svc_cfg_call_data == nullptr) return nullptr;
return static_cast<const RetryMethodConfig*>(
svc_cfg_call_data->GetMethodParsedConfig(service_config_parser_index_));

@ -66,8 +66,7 @@ class RetryFilter final {
// any even moderately compelling reason to do so.
static double BackoffJitter() { return 0.2; }
const internal::RetryMethodConfig* GetRetryPolicy(
const grpc_call_context_element* context);
const internal::RetryMethodConfig* GetRetryPolicy(Arena* arena);
RefCountedPtr<internal::ServerRetryThrottleData> retry_throttle_data() const {
return retry_throttle_data_;

@ -137,9 +137,8 @@ RetryFilter::LegacyCallData::CallAttempt::CallAttempt(
lb_call_committed_ = true;
if (calld_->retry_committed_) {
auto* service_config_call_data =
static_cast<ClientChannelServiceConfigCallData*>(
calld_->call_context_[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA]
.value);
DownCast<ClientChannelServiceConfigCallData*>(
calld_->arena_->GetContext<ServiceConfigCallData>());
service_config_call_data->Commit();
}
},
@ -1545,7 +1544,7 @@ RetryFilter::LegacyCallData::LegacyCallData(RetryFilter* chand,
const grpc_call_element_args& args)
: chand_(chand),
retry_throttle_data_(chand->retry_throttle_data()),
retry_policy_(chand->GetRetryPolicy(args.context)),
retry_policy_(chand->GetRetryPolicy(args.arena)),
retry_backoff_(
BackOff::Options()
.set_initial_backoff(retry_policy_ == nullptr
@ -1685,8 +1684,8 @@ void RetryFilter::LegacyCallData::StartTransportStreamOpBatch(
}
PendingBatchClear(pending);
auto* service_config_call_data =
static_cast<ClientChannelServiceConfigCallData*>(
call_context_[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
DownCast<ClientChannelServiceConfigCallData*>(
arena_->GetContext<ServiceConfigCallData>());
committed_call_ = CreateLoadBalancedCall(
[service_config_call_data]() { service_config_call_data->Commit(); },
/*is_transparent_retry=*/false);
@ -1976,8 +1975,8 @@ void RetryFilter::LegacyCallData::RetryCommit(CallAttempt* call_attempt) {
// problem anymore.
if (call_attempt->lb_call_committed()) {
auto* service_config_call_data =
static_cast<ClientChannelServiceConfigCallData*>(
call_context_[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
DownCast<ClientChannelServiceConfigCallData*>(
arena_->GetContext<ServiceConfigCallData>());
service_config_call_data->Commit();
}
// Free cached send ops.

@ -167,10 +167,7 @@ FaultInjectionFilter::MakeInjectionDecision(
const ClientMetadata& initial_metadata) {
// Fetch the fault injection policy from the service config, based on the
// relative index for which policy should this CallData use.
auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
GetContext<
grpc_call_context_element>()[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA]
.value);
auto* service_config_call_data = GetContext<ServiceConfigCallData>();
auto* method_params = static_cast<FaultInjectionMethodParsedConfig*>(
service_config_call_data->GetMethodParsedConfig(
service_config_parser_index_));

@ -232,8 +232,7 @@ ChannelCompression::DecompressArgs ChannelCompression::HandleIncomingMetadata(
auto max_recv_message_length = max_recv_size_;
const MessageSizeParsedConfig* limits =
MessageSizeParsedConfig::GetFromCallContext(
GetContext<grpc_call_context_element>(),
message_size_service_config_parser_index_);
GetContext<Arena>(), message_size_service_config_parser_index_);
if (limits != nullptr && limits->max_recv_size().has_value() &&
(!max_recv_message_length.has_value() ||
*limits->max_recv_size() < *max_recv_message_length)) {

@ -64,11 +64,8 @@ const NoInterceptor ServerMessageSizeFilter::Call::OnFinalize;
//
const MessageSizeParsedConfig* MessageSizeParsedConfig::GetFromCallContext(
const grpc_call_context_element* context,
size_t service_config_parser_index) {
if (context == nullptr) return nullptr;
auto* svc_cfg_call_data = static_cast<ServiceConfigCallData*>(
context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
Arena* arena, size_t service_config_parser_index) {
auto* svc_cfg_call_data = arena->GetContext<ServiceConfigCallData>();
if (svc_cfg_call_data == nullptr) return nullptr;
return static_cast<const MessageSizeParsedConfig*>(
svc_cfg_call_data->GetMethodParsedConfig(service_config_parser_index));
@ -188,8 +185,7 @@ ClientMessageSizeFilter::Call::Call(ClientMessageSizeFilter* filter)
// size to the receive limit.
const MessageSizeParsedConfig* config_from_call_context =
MessageSizeParsedConfig::GetFromCallContext(
GetContext<grpc_call_context_element>(),
filter->service_config_parser_index_);
GetContext<Arena>(), filter->service_config_parser_index_);
if (config_from_call_context != nullptr) {
absl::optional<uint32_t> max_send_size = limits_.max_send_size();
absl::optional<uint32_t> max_recv_size = limits_.max_recv_size();

@ -55,8 +55,7 @@ class MessageSizeParsedConfig : public ServiceConfigParser::ParsedConfig {
: max_send_size_(max_send_size), max_recv_size_(max_recv_size) {}
static const MessageSizeParsedConfig* GetFromCallContext(
const grpc_call_context_element* context,
size_t service_config_parser_index);
Arena* arena, size_t service_config_parser_index);
static MessageSizeParsedConfig GetFromChannelArgs(const ChannelArgs& args);

@ -53,10 +53,7 @@ const NoInterceptor RbacFilter::Call::OnFinalize;
absl::Status RbacFilter::Call::OnClientInitialMetadata(ClientMetadata& md,
RbacFilter* filter) {
// Fetch and apply the rbac policy from the service config.
auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
GetContext<
grpc_call_context_element>()[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA]
.value);
auto* service_config_call_data = GetContext<ServiceConfigCallData>();
auto* method_params = static_cast<RbacMethodParsedConfig*>(
service_config_call_data->GetMethodParsedConfig(
filter->service_config_parser_index_));

@ -225,10 +225,7 @@ bool IsConfiguredPath(absl::string_view configured_path,
void StatefulSessionFilter::Call::OnClientInitialMetadata(
ClientMetadata& md, StatefulSessionFilter* filter) {
// Get config.
auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
GetContext<
grpc_call_context_element>()[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA]
.value);
auto* service_config_call_data = GetContext<ServiceConfigCallData>();
CHECK_NE(service_config_call_data, nullptr);
auto* method_params = static_cast<StatefulSessionMethodParsedConfig*>(
service_config_call_data->GetMethodParsedConfig(

@ -29,9 +29,6 @@
/// This enum represents the indexes into the array, where each index
/// contains a different type of value.
typedef enum {
/// Holds a pointer to ServiceConfigCallData associated with this call.
GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA,
GRPC_CONTEXT_COUNT
} grpc_context_index;
@ -54,12 +51,6 @@ namespace promise_detail {
template <typename T>
struct OldStyleContext;
template <>
struct OldStyleContext<ServiceConfigCallData> {
static constexpr grpc_context_index kIndex =
GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA;
};
template <typename T>
class Context<T, absl::void_t<decltype(OldStyleContext<T>::kIndex)>> {
public:

@ -266,6 +266,10 @@ class Arena final : public RefCounted<Arena, NonPolymorphicRefCount,
delete p;
}
// Context accessors
// Prefer to use the free-standing `GetContext<>` and `SetContext<>` functions
// for modern promise-based code -- however legacy filter stack based code
// often needs to access these directly.
template <typename T>
T* GetContext() {
return static_cast<T*>(

@ -854,10 +854,7 @@ const grpc_channel_filter XdsResolver::ClusterSelectionFilter::kFilter =
void XdsResolver::ClusterSelectionFilter::Call::OnClientInitialMetadata(
ClientMetadata&) {
auto* service_config_call_data =
static_cast<ClientChannelServiceConfigCallData*>(
GetContext<grpc_call_context_element>()
[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA]
.value);
GetContext<ClientChannelServiceConfigCallData>();
CHECK_NE(service_config_call_data, nullptr);
auto* route_state_attribute = static_cast<XdsRouteStateAttributeImpl*>(
service_config_call_data->GetCallAttribute<XdsRouteStateAttribute>());

@ -149,8 +149,7 @@ absl::Status ServerConfigSelectorFilter::Call::OnClientInitialMetadata(
return absl::UnavailableError(StatusToString(call_config.status()));
}
auto* service_config_call_data =
GetContext<Arena>()->New<ServiceConfigCallData>(
GetContext<Arena>(), GetContext<grpc_call_context_element>());
GetContext<Arena>()->New<ServiceConfigCallData>(GetContext<Arena>());
service_config_call_data->SetServiceConfig(
std::move(call_config->service_config), call_config->method_configs);
return absl::OkStatus();

@ -49,11 +49,7 @@ class ServiceConfigCallData {
virtual UniqueTypeName type() const = 0;
};
ServiceConfigCallData(Arena* arena, grpc_call_context_element* call_context)
: call_attributes_(arena) {
call_context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value = this;
call_context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].destroy = Destroy;
}
explicit ServiceConfigCallData(Arena* arena);
virtual ~ServiceConfigCallData() = default;
@ -101,16 +97,23 @@ class ServiceConfigCallData {
}
private:
static void Destroy(void* ptr) {
auto* self = static_cast<ServiceConfigCallData*>(ptr);
self->~ServiceConfigCallData();
}
RefCountedPtr<ServiceConfig> service_config_;
const ServiceConfigParser::ParsedConfigVector* method_configs_ = nullptr;
ChunkedVector<CallAttributeInterface*, 4> call_attributes_;
};
template <>
struct ArenaContextType<ServiceConfigCallData> {
static void Destroy(ServiceConfigCallData* ptr) {
ptr->~ServiceConfigCallData();
}
};
inline ServiceConfigCallData::ServiceConfigCallData(Arena* arena)
: call_attributes_(arena) {
arena->SetContext<ServiceConfigCallData>(this);
}
} // namespace grpc_core
#endif // GRPC_SRC_CORE_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H

@ -113,8 +113,7 @@ void ServiceConfigChannelArgFilter::Call::OnClientInitialMetadata(
md.get_pointer(HttpPathMetadata())->c_slice());
}
auto* arena = GetContext<Arena>();
auto* service_config_call_data = arena->New<ServiceConfigCallData>(
arena, GetContext<grpc_call_context_element>());
auto* service_config_call_data = arena->New<ServiceConfigCallData>(arena);
service_config_call_data->SetServiceConfig(filter->service_config_,
method_configs);
}

Loading…
Cancel
Save