mirror of https://github.com/grpc/grpc.git
[metadata] Expose metadata limits and annotation info to filter stack (#35970)
<!--
If you know who should review your pull request, please assign it to that
person, otherwise the pull request would get assigned randomly.
If your pull request is for a specific language, please add the appropriate
lang label.
-->
Closes #35970
COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35970 from ananda1066:client_metadata b62a9ae146
PiperOrigin-RevId: 610830228
pull/36015/head
parent
338fc05c21
commit
fa2bae473a
21 changed files with 190 additions and 84 deletions
@ -0,0 +1,55 @@ |
||||
// Copyright 2023 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/transport/metadata_info.h" |
||||
|
||||
#include "src/core/lib/slice/slice.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
class MetadataSizesAnnotation::MetadataSizeEncoder { |
||||
public: |
||||
explicit MetadataSizeEncoder(std::string& summary) : summary_(summary) {} |
||||
|
||||
void Encode(const Slice& key, const Slice& value) { |
||||
AddToSummary(key.as_string_view(), value.size()); |
||||
} |
||||
|
||||
template <typename Key, typename Value> |
||||
void Encode(Key, const Value& value) { |
||||
AddToSummary(Key::key(), EncodedSizeOfKey(Key(), value)); |
||||
} |
||||
|
||||
private: |
||||
void AddToSummary(absl::string_view key, |
||||
size_t value_length) GPR_ATTRIBUTE_NOINLINE { |
||||
absl::StrAppend(&summary_, key, ":", |
||||
hpack_constants::SizeForEntry(key.size(), value_length), |
||||
","); |
||||
} |
||||
std::string& summary_; |
||||
}; |
||||
|
||||
std::string MetadataSizesAnnotation::ToString() const { |
||||
std::string metadata_annotation = |
||||
absl::StrCat("gRPC metadata soft_limit:", soft_limit_, |
||||
",hard_limit:", hard_limit_, ","); |
||||
MetadataSizeEncoder encoder(metadata_annotation); |
||||
metadata_buffer_->Encode(&encoder); |
||||
return metadata_annotation; |
||||
} |
||||
|
||||
} // namespace grpc_core
|
@ -0,0 +1,85 @@ |
||||
// Copyright 2023 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H |
||||
#define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/chttp2/transport/hpack_constants.h" |
||||
#include "src/core/lib/channel/call_tracer.h" |
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/transport/metadata_batch.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024) |
||||
#define DEFAULT_MAX_HEADER_LIST_SIZE_SOFT_LIMIT (8 * 1024) |
||||
|
||||
inline uint32_t GetSoftLimitFromChannelArgs(const ChannelArgs& args) { |
||||
const int soft_limit = args.GetInt(GRPC_ARG_MAX_METADATA_SIZE).value_or(-1); |
||||
if (soft_limit < 0) { |
||||
// Set soft limit to 0.8 * hard limit if this is larger than
|
||||
// `DEFAULT_MAX_HEADER_LIST_SIZE_SOFT_LIMIT` and
|
||||
// `GRPC_ARG_MAX_METADATA_SIZE` is not set.
|
||||
return std::max( |
||||
DEFAULT_MAX_HEADER_LIST_SIZE_SOFT_LIMIT, |
||||
static_cast<int>( |
||||
0.8 * |
||||
args.GetInt(GRPC_ARG_ABSOLUTE_MAX_METADATA_SIZE).value_or(-1))); |
||||
} else { |
||||
return soft_limit; |
||||
} |
||||
} |
||||
|
||||
inline uint32_t GetHardLimitFromChannelArgs(const ChannelArgs& args) { |
||||
int hard_limit = |
||||
args.GetInt(GRPC_ARG_ABSOLUTE_MAX_METADATA_SIZE).value_or(-1); |
||||
if (hard_limit >= 0) { |
||||
return hard_limit; |
||||
} else { |
||||
// Set value to 1.25 * soft limit if this is larger than
|
||||
// `DEFAULT_MAX_HEADER_LIST_SIZE` and
|
||||
// `GRPC_ARG_ABSOLUTE_MAX_METADATA_SIZE` is not set.
|
||||
const int soft_limit = args.GetInt(GRPC_ARG_MAX_METADATA_SIZE).value_or(-1); |
||||
const int value = (soft_limit >= 0 && soft_limit < (INT_MAX / 1.25)) |
||||
? static_cast<int>(soft_limit * 1.25) |
||||
: soft_limit; |
||||
return std::max(value, DEFAULT_MAX_HEADER_LIST_SIZE); |
||||
} |
||||
} |
||||
|
||||
class MetadataSizesAnnotation |
||||
: public CallTracerAnnotationInterface::Annotation { |
||||
public: |
||||
MetadataSizesAnnotation(grpc_metadata_batch* metadata_buffer, |
||||
uint64_t soft_limit, uint64_t hard_limit) |
||||
: CallTracerAnnotationInterface::Annotation( |
||||
CallTracerAnnotationInterface::AnnotationType::kMetadataSizes), |
||||
metadata_buffer_(metadata_buffer), |
||||
soft_limit_(soft_limit), |
||||
hard_limit_(hard_limit) {} |
||||
|
||||
std::string ToString() const override; |
||||
|
||||
private: |
||||
class MetadataSizeEncoder; |
||||
grpc_metadata_batch* metadata_buffer_; |
||||
uint64_t soft_limit_; |
||||
uint64_t hard_limit_; |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H
|
Loading…
Reference in new issue