blob: 733130a30ce0d6df461bf9340fed11f4a6d55b02 [file] [log] [blame]
//
// Copyright 2021 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_CLIENT_CHANNEL_RETRY_FILTER_H
#define GRPC_SRC_CORE_CLIENT_CHANNEL_RETRY_FILTER_H
#include <grpc/support/port_platform.h>
#include <limits.h>
#include <stddef.h>
#include <new>
#include "absl/types/optional.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>
#include <grpc/impl/channel_arg_names.h>
#include <grpc/support/log.h>
#include "src/core/client_channel/client_channel_filter.h"
#include "src/core/client_channel/retry_service_config.h"
#include "src/core/client_channel/retry_throttle.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_fwd.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/context.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/transport/transport.h"
extern grpc_core::TraceFlag grpc_retry_trace;
namespace grpc_core {
class RetryFilter final {
public:
static const grpc_channel_filter kVtable;
private:
// Old filter-stack style call implementation, in
// retry_filter_legacy_call_data.{h,cc}
class LegacyCallData;
grpc_event_engine::experimental::EventEngine* event_engine() const {
return event_engine_;
}
// This value was picked arbitrarily. It can be changed if there is
// any even moderately compelling reason to do so.
static double BackoffJitter() { return 0.2; }
const internal::RetryMethodConfig* GetRetryPolicy(
const grpc_call_context_element* context);
RefCountedPtr<internal::ServerRetryThrottleData> retry_throttle_data() const {
return retry_throttle_data_;
}
ClientChannelFilter* client_channel() const { return client_channel_; }
size_t per_rpc_retry_buffer_size() const {
return per_rpc_retry_buffer_size_;
}
static size_t GetMaxPerRpcRetryBufferSize(const ChannelArgs& args) {
// By default, we buffer 256 KiB per RPC for retries.
// TODO(roth): Do we have any data to suggest a better value?
static constexpr int kDefaultPerRpcRetryBufferSize = (256 << 10);
return Clamp(args.GetInt(GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE)
.value_or(kDefaultPerRpcRetryBufferSize),
0, INT_MAX);
}
RetryFilter(const ChannelArgs& args, grpc_error_handle* error);
static grpc_error_handle Init(grpc_channel_element* elem,
grpc_channel_element_args* args) {
GPR_ASSERT(args->is_last);
GPR_ASSERT(elem->filter == &kVtable);
grpc_error_handle error;
new (elem->channel_data) RetryFilter(args->channel_args, &error);
return error;
}
static void Destroy(grpc_channel_element* elem) {
auto* chand = static_cast<RetryFilter*>(elem->channel_data);
chand->~RetryFilter();
}
// Will never be called.
static void StartTransportOp(grpc_channel_element* /*elem*/,
grpc_transport_op* /*op*/) {}
static void GetChannelInfo(grpc_channel_element* /*elem*/,
const grpc_channel_info* /*info*/) {}
ClientChannelFilter* client_channel_;
grpc_event_engine::experimental::EventEngine* const event_engine_;
size_t per_rpc_retry_buffer_size_;
RefCountedPtr<internal::ServerRetryThrottleData> retry_throttle_data_;
const size_t service_config_parser_index_;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_CLIENT_CHANNEL_RETRY_FILTER_H