Scarab  v3.9.4
Project 8 C++ Utility Library
exponential_backoff.hh
Go to the documentation of this file.
1 /*
2  * exponential_backoff.hh
3  *
4  * Created on: Jun 17, 2021
5  * Author: N.S. Oblath
6  */
7 
8 #ifndef SCARAB_EXPONENTIAL_BACKOFF_HH_
9 #define SCARAB_EXPONENTIAL_BACKOFF_HH_
10 
11 #include "error.hh"
12 #include "logger.hh"
13 #include "member_variables.hh"
14 #include "scarab_api.hh"
15 
16 #include <chrono>
17 #include <functional>
18 #include <thread>
19 
20 
21 LOGGER( expbacklog_hh, "exponential_backoff.hh" )
22 
23 namespace scarab
24 {
33  template< typename ... x_args >
35  {
36  public:
37  exponential_backoff( std::function< bool (x_args...) > an_action, unsigned a_max_attempts = 10, unsigned a_base_delay_ms = 100 );
38  //exponential_backoff( const exponential_backoff< x_args... >& a_orig );
39  virtual ~exponential_backoff();
40 
41  //exponential_backoff< x_args... >& operator=( const exponential_backoff< x_args... >& a_orig );
42 
44  unsigned go( x_args... args );
45 
46  mv_referrable( std::function< bool (x_args...) >, action );
47 
48  mv_accessible( unsigned, max_attempts );
49  mv_accessible( unsigned, base_delay_ms );
50  };
51 
52 
53  template< typename ... x_args >
54  exponential_backoff< x_args... >::exponential_backoff( std::function< bool (x_args...) > an_action, unsigned a_max_attempts, unsigned a_base_delay_ms ) :
55  f_action( an_action ),
56  f_max_attempts( a_max_attempts ),
57  f_base_delay_ms( a_base_delay_ms )
58  {
59  if( f_max_attempts == 0 ) throw error() << "Max attempts must be > 0";
60  }
61 
62  template< typename ... x_args >
64  {}
65 
66  template< typename ... x_args >
67  unsigned exponential_backoff< x_args... >::go( x_args... args )
68  {
69  //LDEBUG( expbacklog_hh, "doing action" );
70  unsigned t_attempts = 1;
71  bool t_success = f_action( args... );
72  LDEBUG( expbacklog_hh, "function called first time: " << t_success );
73  while( ! t_success && t_attempts < f_max_attempts )
74  {
75  LDEBUG( expbacklog_hh, "attempt: " << t_attempts + 1 << " after delay: " << (1<<t_attempts) * f_base_delay_ms );
76  std::this_thread::sleep_for( std::chrono::milliseconds( (1<<t_attempts) * f_base_delay_ms ) );
77  t_success = f_action( args... );
78  LDEBUG( expbacklog_hh, "function called: " << t_success );
79  ++t_attempts;
80  }
81 
82  return t_success ? t_attempts : 0;
83  }
84 
85 } /* namespace scarab */
86 
87 #endif /* SCARAB_EXPONENTIAL_BACKOFF_HH_ */
Class that performs an action using exponential backoff.
#define SCARAB_API
Definition: scarab_api.hh:24
#define LOGGER(I, K)
Definition: logger.hh:379
unsigned go(x_args... args)
returns the number of attempts made at calling the function (including the last, successful or not) ...
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
#define mv_referrable
#define LDEBUG(...)
Definition: logger.hh:389
#define mv_accessible