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