xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/ExponentialBackoff.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- llvm/Support/ExponentialBackoff.h ------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a helper class for implementing exponential backoff.
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_EXPONENTIALBACKOFF_H
13 #define LLVM_EXPONENTIALBACKOFF_H
14 
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/Error.h"
18 #include <chrono>
19 #include <random>
20 
21 namespace llvm {
22 
23 /// A class to help implement exponential backoff.
24 ///
25 /// Example usage:
26 /// \code
27 ///   ExponentialBackoff Backoff(10s);
28 ///   do {
29 ///     if (tryToDoSomething())
30 ///       return ItWorked;
31 ///   } while (Backoff.waitForNextAttempt());
32 ///   return Timeout;
33 /// \endcode
34 class ExponentialBackoff {
35 public:
36   using duration = std::chrono::steady_clock::duration;
37   using time_point = std::chrono::steady_clock::time_point;
38 
39   /// \param Timeout the maximum wall time this should run for starting when
40   ///        this object is constructed.
41   /// \param MinWait the minimum amount of time `waitForNextAttempt` will sleep
42   ///        for.
43   /// \param MaxWait the maximum amount of time `waitForNextAttempt` will sleep
44   ///        for.
45   ExponentialBackoff(duration Timeout,
46                      duration MinWait = std::chrono::milliseconds(10),
47                      duration MaxWait = std::chrono::milliseconds(500))
MinWait(MinWait)48       : MinWait(MinWait), MaxWait(MaxWait),
49         EndTime(std::chrono::steady_clock::now() + Timeout) {}
50 
51   /// Blocks while waiting for the next attempt.
52   /// \returns true if you should try again, false if the timeout has been
53   /// reached.
54   LLVM_ABI bool waitForNextAttempt();
55 
56 private:
57   duration MinWait;
58   duration MaxWait;
59   time_point EndTime;
60   std::random_device RandDev;
61   int64_t CurrentMultiplier = 1;
62 };
63 
64 } // end namespace llvm
65 
66 #endif // LLVM_EXPONENTIALBACKOFF_H
67