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/Error.h" |
17 | #include <chrono> |
18 | #include <random> |
19 | |
20 | namespace llvm { |
21 | |
22 | /// A class to help implement exponential backoff. |
23 | /// |
24 | /// Example usage: |
25 | /// \code |
26 | /// ExponentialBackoff Backoff(10s); |
27 | /// do { |
28 | /// if (tryToDoSomething()) |
29 | /// return ItWorked; |
30 | /// } while (Backoff.waitForNextAttempt()); |
31 | /// return Timeout; |
32 | /// \endcode |
33 | class ExponentialBackoff { |
34 | public: |
35 | using duration = std::chrono::steady_clock::duration; |
36 | using time_point = std::chrono::steady_clock::time_point; |
37 | |
38 | /// \param Timeout the maximum wall time this should run for starting when |
39 | /// this object is constructed. |
40 | /// \param MinWait the minimum amount of time `waitForNextAttempt` will sleep |
41 | /// for. |
42 | /// \param MaxWait the maximum amount of time `waitForNextAttempt` will sleep |
43 | /// for. |
44 | ExponentialBackoff(duration Timeout, |
45 | duration MinWait = std::chrono::milliseconds(10), |
46 | duration MaxWait = std::chrono::milliseconds(500)) |
47 | : MinWait(MinWait), MaxWait(MaxWait), |
48 | EndTime(std::chrono::steady_clock::now() + Timeout) {} |
49 | |
50 | /// Blocks while waiting for the next attempt. |
51 | /// \returns true if you should try again, false if the timeout has been |
52 | /// reached. |
53 | bool waitForNextAttempt(); |
54 | |
55 | private: |
56 | duration MinWait; |
57 | duration MaxWait; |
58 | time_point EndTime; |
59 | std::random_device RandDev; |
60 | int64_t CurrentMultiplier = 1; |
61 | }; |
62 | |
63 | } // end namespace llvm |
64 | |
65 | #endif // LLVM_EXPONENTIALBACKOFF_H |
66 | |