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)) MinWait(MinWait)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