unilink  0.4.3
A simple C++ library for unified async communication
reconnect_decider.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2025 Jinwoo Sung
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <algorithm>
20 #include <chrono>
21 #include <cstdint>
22 #include <optional>
23 
27 
28 namespace unilink {
29 namespace transport {
30 namespace detail {
31 
32 // Keep the existing cap used by reconnect logic to avoid runtime behavior changes.
33 constexpr auto MAX_RECONNECT_DELAY = std::chrono::milliseconds(30000);
34 
39  bool should_retry{false};
40  std::optional<std::chrono::milliseconds> delay{std::nullopt};
41 };
42 
43 inline std::chrono::milliseconds clamp_reconnect_delay(std::chrono::milliseconds delay) {
44  if (delay < std::chrono::milliseconds(0)) {
45  return std::chrono::milliseconds(0);
46  }
47  return std::min(delay, MAX_RECONNECT_DELAY);
48 }
49 
60  const diagnostics::ErrorInfo& error_info, uint32_t attempt_count,
61  const std::optional<ReconnectPolicy>& policy) {
62  if (!error_info.retryable) {
63  return {false, std::nullopt};
64  }
65 
66  if (cfg.max_retries == 0) {
67  return {false, std::nullopt};
68  }
69 
70  if (cfg.max_retries > 0 && attempt_count >= static_cast<uint32_t>(cfg.max_retries)) {
71  return {false, std::nullopt};
72  }
73 
74  if (policy) {
75  auto policy_decision = (*policy)(error_info, attempt_count);
76  if (!policy_decision.retry) {
77  return {false, std::nullopt};
78  }
79  return {true, clamp_reconnect_delay(policy_decision.delay)};
80  }
81 
82  return {true, clamp_reconnect_delay(std::chrono::milliseconds(cfg.retry_interval_ms))};
83 }
84 
85 } // namespace detail
86 } // namespace transport
87 } // namespace unilink