C++ 通用指数退避重试机制C++;11
我在C++11中编写了一个通用的指数回退重试循环。我正在使用C++ 通用指数退避重试机制C++;11,c++,c++11,C++,C++11,我在C++11中编写了一个通用的指数回退重试循环。我正在使用std::function传递可调用重试循环callable #include <algorithm> #include <cassert> #include <chrono> #include <functional> #include <iostream> #include <thread> constexpr int64_t max_backoff_mill
std::function
传递可调用重试循环<如果isRetrable
函数返回true,则将重试code>callable
#include <algorithm>
#include <cassert>
#include <chrono>
#include <functional>
#include <iostream>
#include <thread>
constexpr int64_t max_backoff_milliseconds = 30000; // 30 seconds
template <class R, class... Args>
R Retry(int max_retry_count, int64_t initial_dealy_milliseconds,
const std::function<bool(R)> &isRetriable,
const std::function<R(Args...)> &callable, Args &&... args)
{
int retry_count = 0;
while (true) {
auto status = callable(std::forward<Args>(args)...);
if (!IsRetriable(status)) {
return status;
}
if (retry_count >= max_retry_count) {
// Return status and abort retry
return status;
}
int64_t delay_milliseconds = 0;
if (initial_dealy_milliseconds > 0) {
delay_milliseconds =
std::min(initial_dealy_milliseconds << retry_count,
max_backoff_milliseconds);
}
std::cout << "Callable execution failed. Retry Count:"
<< retry_count + 1 << std::endl;
std::this_thread::sleep_for(
std::chrono::milliseconds(delay_milliseconds));
retry_count++;
}
}
bool isRetriable(int status) {
if (status == 5)
return true;
return false;
}
int foo(int x, int y) {
static int a = 1;
a += (x + y);
return a / 6;
}
int main() {
auto result = Retry(1000, 100, isRetriable, foo, 1, 3);
std::cout << result << std::endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
constexpr int64\u t max\u backoff\u毫秒=30000;//30秒
模板
R重试(整数最大重试计数,整数初始延迟毫秒,
常量标准::函数和可测量,
常量std::函数和可调用参数(Args&&…Args)
{
int重试次数=0;
while(true){
自动状态=可调用(std::forward(args)…);
如果(!isRetrable(状态)){
返回状态;
}
如果(重试次数>=最大重试次数){
//返回状态并中止重试
返回状态;
}
int64_t延迟_毫秒=0;
如果(初始时间>0毫秒){
延迟(毫秒)=
std::min(初始时间-毫秒我确信这有一个很好的副本,但是
这是一个简短的复制:
template <typename T> void foo(std::function<bool(T)> ) { }
bool maybe(int ) { return false; }
foo(maybe); // error: no matching function call to 'foo(bool (&)(int))'
基本上,试图推断一个std::function
几乎总是错误的。首先,它是错误的,因为它不起作用。其次,它是错误的,因为即使它起作用,你也会在你可能不需要它的上下文中发生类型擦除
相反,您要做的是推断任意可调用项,然后确定这些其他参数基于这些可调用项。当您使用Args…
调用callable
时,callable
的返回类型就是您得到的,并且您要确保isRetriable
是该类型的谓词
一种方法是:
template <typename Predicate, typename Callable, typename... Args,
// figure out what the callable returns
typename R = std::decay_t<std::invoke_result_t<Callable&, Args...>>,
// require that Predicate is actually a Predicate
std::enable_if_t<
std::is_convertible_v<std::invoke_result_t<Predicate&, R>, bool>,
int> = 0>
R Retry(int max_retry_count, int64_t initial_dealy_milliseconds,
Predicate&& isRetriable,
Callable&& callable,
Args&&... args)
{
// ....
}
template=0>
R重试(整数最大重试计数,整数初始延迟毫秒,
谓词可度量(&I),
可调用&&Callable,
Args&&…Args)
{
// ....
}
您正在(尝试)调用一个签名与现有签名不同的函数。在C++14中,删除所有的enable_if和invoke_result内容,只需返回auto
,即可完成90%的功能,完成10%的工作。@Yakk AdamNevraumont-您能为问题中所示的重试机制提供C++14解决方案吗?想知道函数的签名吗以及如何称呼它。
foo([](int ) { return true; }); // also error
template <typename Predicate, typename Callable, typename... Args,
// figure out what the callable returns
typename R = std::decay_t<std::invoke_result_t<Callable&, Args...>>,
// require that Predicate is actually a Predicate
std::enable_if_t<
std::is_convertible_v<std::invoke_result_t<Predicate&, R>, bool>,
int> = 0>
R Retry(int max_retry_count, int64_t initial_dealy_milliseconds,
Predicate&& isRetriable,
Callable&& callable,
Args&&... args)
{
// ....
}