retry_throttle.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include <map>
24 #include <string>
25 #include <utility>
26 
27 #include <grpc/support/atm.h>
28 
29 namespace grpc_core {
30 namespace internal {
31 
32 //
33 // ServerRetryThrottleData
34 //
35 
37  intptr_t max_milli_tokens, intptr_t milli_token_ratio,
38  ServerRetryThrottleData* old_throttle_data)
39  : max_milli_tokens_(max_milli_tokens),
40  milli_token_ratio_(milli_token_ratio) {
41  intptr_t initial_milli_tokens = max_milli_tokens;
42  // If there was a pre-existing entry for this server name, initialize
43  // the token count by scaling proportionately to the old data. This
44  // ensures that if we're already throttling retries on the old scale,
45  // we will start out doing the same thing on the new one.
46  if (old_throttle_data != nullptr) {
47  double token_fraction =
48  static_cast<intptr_t>(
49  gpr_atm_acq_load(&old_throttle_data->milli_tokens_)) /
50  static_cast<double>(old_throttle_data->max_milli_tokens_);
51  initial_milli_tokens =
52  static_cast<intptr_t>(token_fraction * max_milli_tokens);
53  }
54  gpr_atm_rel_store(&milli_tokens_, static_cast<gpr_atm>(initial_milli_tokens));
55  // If there was a pre-existing entry, mark it as stale and give it a
56  // pointer to the new entry, which is its replacement.
57  if (old_throttle_data != nullptr) {
58  Ref().release(); // Ref held by pre-existing entry.
59  gpr_atm_rel_store(&old_throttle_data->replacement_,
60  reinterpret_cast<gpr_atm>(this));
61  }
62 }
63 
65  ServerRetryThrottleData* replacement =
66  reinterpret_cast<ServerRetryThrottleData*>(
68  if (replacement != nullptr) {
69  replacement->Unref();
70  }
71 }
72 
74  ServerRetryThrottleData** throttle_data) {
75  while (true) {
76  ServerRetryThrottleData* new_throttle_data =
77  reinterpret_cast<ServerRetryThrottleData*>(
78  gpr_atm_acq_load(&(*throttle_data)->replacement_));
79  if (new_throttle_data == nullptr) return;
80  *throttle_data = new_throttle_data;
81  }
82 }
83 
85  // First, check if we are stale and need to be replaced.
86  ServerRetryThrottleData* throttle_data = this;
87  GetReplacementThrottleDataIfNeeded(&throttle_data);
88  // We decrement milli_tokens by 1000 (1 token) for each failure.
89  const intptr_t new_value =
91  &throttle_data->milli_tokens_, static_cast<gpr_atm>(-1000),
92  static_cast<gpr_atm>(0),
93  static_cast<gpr_atm>(throttle_data->max_milli_tokens_)));
94  // Retries are allowed as long as the new value is above the threshold
95  // (max_milli_tokens / 2).
96  return new_value > throttle_data->max_milli_tokens_ / 2;
97 }
98 
100  // First, check if we are stale and need to be replaced.
101  ServerRetryThrottleData* throttle_data = this;
102  GetReplacementThrottleDataIfNeeded(&throttle_data);
103  // We increment milli_tokens by milli_token_ratio for each success.
105  &throttle_data->milli_tokens_,
106  static_cast<gpr_atm>(throttle_data->milli_token_ratio_),
107  static_cast<gpr_atm>(0),
108  static_cast<gpr_atm>(throttle_data->max_milli_tokens_));
109 }
110 
111 //
112 // ServerRetryThrottleMap
113 //
114 
117  return m;
118 }
119 
121  const std::string& server_name, intptr_t max_milli_tokens,
122  intptr_t milli_token_ratio) {
123  MutexLock lock(&mu_);
124  auto it = map_.find(server_name);
125  ServerRetryThrottleData* throttle_data =
126  it == map_.end() ? nullptr : it->second.get();
127  if (throttle_data == nullptr ||
128  throttle_data->max_milli_tokens() != max_milli_tokens ||
129  throttle_data->milli_token_ratio() != milli_token_ratio) {
130  // Entry not found, or found with old parameters. Create a new one.
131  it = map_.emplace(server_name,
132  MakeRefCounted<ServerRetryThrottleData>(
133  max_milli_tokens, milli_token_ratio, throttle_data))
134  .first;
135  throttle_data = it->second.get();
136  }
137  return throttle_data->Ref();
138 }
139 
140 } // namespace internal
141 } // namespace grpc_core
regen-readme.it
it
Definition: regen-readme.py:15
grpc_core::internal::ServerRetryThrottleData::milli_token_ratio
intptr_t milli_token_ratio() const
Definition: retry_throttle.h:54
grpc_core::internal::ServerRetryThrottleData::ServerRetryThrottleData
ServerRetryThrottleData(intptr_t max_milli_tokens, intptr_t milli_token_ratio, ServerRetryThrottleData *old_throttle_data)
Definition: retry_throttle.cc:36
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::MutexLock
Definition: src/core/lib/gprpp/sync.h:88
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc_core::internal::ServerRetryThrottleData::RecordFailure
bool RecordFailure()
Records a failure. Returns true if it's okay to send a retry.
Definition: retry_throttle.cc:84
grpc_core::internal::ServerRetryThrottleMap::mu_
Mutex mu_
Definition: retry_throttle.h:84
grpc_core::internal::ServerRetryThrottleData::replacement_
gpr_atm replacement_
Definition: retry_throttle.h:66
grpc_core::RefCounted::Unref
void Unref()
Definition: ref_counted.h:302
grpc_core::internal::ServerRetryThrottleMap::Get
static ServerRetryThrottleMap * Get()
Definition: retry_throttle.cc:115
grpc_core::RefCountedPtr
Definition: ref_counted_ptr.h:35
gpr_atm_acq_load
#define gpr_atm_acq_load(p)
Definition: impl/codegen/atm_gcc_atomic.h:52
gpr_atm_no_barrier_clamped_add
gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm *value, gpr_atm delta, gpr_atm min, gpr_atm max)
Definition: atm.cc:25
gpr_atm_rel_store
#define gpr_atm_rel_store(p, value)
Definition: impl/codegen/atm_gcc_atomic.h:54
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
grpc_core::internal::ServerRetryThrottleData::milli_tokens_
gpr_atm milli_tokens_
Definition: retry_throttle.h:62
grpc_core::internal::ServerRetryThrottleMap::GetDataForServer
RefCountedPtr< ServerRetryThrottleData > GetDataForServer(const std::string &server_name, intptr_t max_milli_tokens, intptr_t milli_token_ratio)
Definition: retry_throttle.cc:120
grpc_core::internal::ServerRetryThrottleMap
Global map of server name to retry throttle data.
Definition: retry_throttle.h:70
grpc_core::internal::ServerRetryThrottleData::max_milli_tokens_
const intptr_t max_milli_tokens_
Definition: retry_throttle.h:60
retry_throttle.h
grpc_core::internal::ServerRetryThrottleData
Tracks retry throttling data for an individual server name.
Definition: retry_throttle.h:41
gpr_atm
intptr_t gpr_atm
Definition: impl/codegen/atm_gcc_atomic.h:32
grpc_core::internal::ServerRetryThrottleData::milli_token_ratio_
const intptr_t milli_token_ratio_
Definition: retry_throttle.h:61
grpc_core::internal::ServerRetryThrottleData::RecordSuccess
void RecordSuccess()
Records a success.
Definition: retry_throttle.cc:99
internal
Definition: benchmark/test/output_test_helper.cc:20
grpc_core::internal::ServerRetryThrottleData::max_milli_tokens
intptr_t max_milli_tokens() const
Definition: retry_throttle.h:53
atm.h
regress.m
m
Definition: regress/regress.py:25
grpc_core::internal::ServerRetryThrottleData::~ServerRetryThrottleData
~ServerRetryThrottleData() override
Definition: retry_throttle.cc:64
grpc_core::RefCounted< ServerRetryThrottleData >::Ref
RefCountedPtr< ServerRetryThrottleData > Ref() GRPC_MUST_USE_RESULT
Definition: ref_counted.h:287
run_interop_tests.server_name
server_name
Definition: run_interop_tests.py:1510
grpc_core::internal::ServerRetryThrottleData::GetReplacementThrottleDataIfNeeded
void GetReplacementThrottleDataIfNeeded(ServerRetryThrottleData **throttle_data)
Definition: retry_throttle.cc:73
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:05