28 using namespace folly;
33 template <
typename D,
typename F>
39 vector<thread>
threads(num_tries);
40 vector<D> durations(num_tries,
D::min());
41 for (
size_t i = 0;
i < num_tries; ++
i) {
42 threads[
i] = thread([&,
i] {
48 for (
auto&
t : threads) {
51 sort(durations.begin(), durations.end());
52 for (
auto d : durations) {
58 TEST(RetryingTest, has_op_call) {
60 auto policy_raw = [](
size_t n,
const ew&) {
return n < 3; };
61 auto policy_fut = [](
size_t n,
const ew&) {
return makeFuture(n < 3); };
62 using namespace futures::detail;
71 return n < 2 ? makeFuture<size_t>(runtime_error(
"ha"))
78 TEST(RetryingTest, future_factory_throws) {
79 struct ReturnedException : exception {};
80 struct ThrownException : exception {};
86 return makeFuture<size_t>(
87 make_exception_wrapper<ReturnedException>());
89 throw ThrownException();
99 TEST(RetryingTest, policy_throws) {
100 struct eggs : exception {};
103 [](size_t) ->
Future<size_t> {
throw std::runtime_error(
"ha"); });
107 TEST(RetryingTest, policy_future) {
108 atomic<size_t> sleeps{0};
113 ?
makeFuture(++sleeps).thenValue([](
auto&&) {
return true; })
117 return n < 2 ? makeFuture<size_t>(runtime_error(
"ha"))
125 TEST(RetryingTest, policy_basic) {
129 return n < 2 ? makeFuture<size_t>(runtime_error(
"ha"))
136 TEST(RetryingTest, policy_capped_jittered_exponential_backoff) {
138 using ms = milliseconds;
148 return n < 2 ? makeFuture<size_t>(runtime_error(
"ha"))
156 TEST(RetryingTest, policy_capped_jittered_exponential_backoff_many_retries) {
157 using namespace futures::detail;
163 80, min_backoff, max_backoff, 0, rng);
168 63, min_backoff, max_backoff, 0, rng);
173 64, min_backoff, max_backoff, 0, rng);
177 TEST(RetryingTest, policy_sleep_defaults) {
180 using ms = milliseconds;
183 3, ms(100), ms(1000), 0.1),
185 return n < 2 ? makeFuture<size_t>(runtime_error(
"ha"))
193 TEST(RetryingTest, large_retries) {
196 PCHECK(getrlimit(RLIMIT_AS, &oldMemLimit) == 0);
199 newMemLimit.rlim_cur =
200 std::min(static_cast<rlim_t>(1UL << 30), oldMemLimit.rlim_max);
201 newMemLimit.rlim_max = oldMemLimit.rlim_max;
203 PCHECK(setrlimit(RLIMIT_AS, &newMemLimit) == 0);
206 PCHECK(setrlimit(RLIMIT_AS, &oldMemLimit) == 0);
212 using LargeReturn = array<uint64_t, 16000>;
214 return via(&executor).thenValue([retryNum](
auto&&) {
215 return retryNum < 10000
216 ? makeFuture<LargeReturn>(
217 make_exception_wrapper<std::runtime_error>(
"keep trying"))
218 : makeFuture<LargeReturn>(LargeReturn());
222 vector<Future<LargeReturn>>
futures;
223 for (
auto idx = 0; idx < 40; ++idx) {
226 return via(&executor).thenValue([](
auto&&) {
return true; });
233 for (
auto&
f : futures) {
#define EXPECT_LE(val1, val2)
std::function< Future< bool >size_t, const exception_wrapper &)> retryingPolicyCappedJitteredExponentialBackoff(size_t max_tries, Duration backoff_min, Duration backoff_max, double jitter_param, URNG &&rng, Policy &&p)
#define EXPECT_THROW(statement, expected_exception)
Duration retryingJitteredExponentialBackoffDur(size_t n, Duration backoff_min, Duration backoff_max, double jitter_param, URNG &rng)
#define EXPECT_EQ(val1, val2)
constexpr detail::Map< Move > move
std::chrono::steady_clock::time_point now()
constexpr bool kIsSanitizeAddress
TEST(RetryingTest, has_op_call)
—— Concurrent Priority Queue Implementation ——
#define EXPECT_GE(val1, val2)
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
PUSHMI_INLINE_VAR constexpr detail::via_fn via
std::vector< std::thread::id > threads
std::chrono::milliseconds Duration
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
static const char *const value
void multiAttemptExpectDurationWithin(size_t num_tries, D min_duration, D max_duration, const F &func)
#define EXPECT_TRUE(condition)
static eggs_t eggs("eggs")
StatsClock::duration Duration
std::function< bool(size_t, const exception_wrapper &)> retryingPolicyBasic(size_t max_tries)
#define EXPECT_LT(val1, val2)
Future< typename std::decay< T >::type > makeFuture(T &&t)
invoke_result_t< FF, size_t > retrying(Policy &&p, FF &&ff)