1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System. |
3 |
|
|
* |
4 |
|
|
* Exponential backoff (sleep) with cutoff. |
5 |
|
|
*/ |
6 |
|
|
|
7 |
|
|
#include "cvmfs_config.h" |
8 |
|
|
#include "backoff.h" |
9 |
|
|
|
10 |
|
|
#include <ctime> |
11 |
|
|
|
12 |
|
|
#include "logging.h" |
13 |
|
|
#include "smalloc.h" |
14 |
|
|
#include "util/posix.h" |
15 |
|
|
|
16 |
|
|
using namespace std; // NOLINT |
17 |
|
|
|
18 |
|
315 |
void BackoffThrottle::Init(const unsigned init_delay_ms, |
19 |
|
|
const unsigned max_delay_ms, |
20 |
|
|
const unsigned reset_after_ms) |
21 |
|
|
{ |
22 |
|
315 |
init_delay_ms_ = init_delay_ms; |
23 |
|
315 |
max_delay_ms_ = max_delay_ms; |
24 |
|
315 |
reset_after_ms_ = reset_after_ms; |
25 |
|
315 |
prng_.InitLocaltime(); |
26 |
|
|
|
27 |
|
|
lock_ = |
28 |
|
315 |
reinterpret_cast<pthread_mutex_t *>(smalloc(sizeof(pthread_mutex_t))); |
29 |
|
315 |
int retval = pthread_mutex_init(lock_, NULL); |
30 |
✗✓ |
315 |
assert(retval == 0); |
31 |
|
|
|
32 |
|
315 |
Reset(); |
33 |
|
315 |
} |
34 |
|
|
|
35 |
|
|
|
36 |
|
315 |
BackoffThrottle::~BackoffThrottle() { |
37 |
|
315 |
pthread_mutex_destroy(lock_); |
38 |
|
315 |
free(lock_); |
39 |
|
315 |
} |
40 |
|
|
|
41 |
|
|
|
42 |
|
319 |
void BackoffThrottle::Reset() { |
43 |
|
319 |
pthread_mutex_lock(lock_); |
44 |
|
319 |
delay_range_ = 0; |
45 |
|
319 |
last_throttle_ = 0; |
46 |
|
319 |
pthread_mutex_unlock(lock_); |
47 |
|
319 |
} |
48 |
|
|
|
49 |
|
|
|
50 |
|
29 |
void BackoffThrottle::Throttle() { |
51 |
|
29 |
time_t now = time(NULL); |
52 |
|
|
|
53 |
|
29 |
pthread_mutex_lock(lock_); |
54 |
✓✓ |
29 |
if (unsigned(now - last_throttle_) < reset_after_ms_/1000) { |
55 |
✓✗ |
5 |
if (delay_range_ < max_delay_ms_) { |
56 |
✓✗ |
5 |
if (delay_range_ == 0) |
57 |
|
5 |
delay_range_ = init_delay_ms_; |
58 |
|
|
else |
59 |
|
|
delay_range_ *= 2; |
60 |
|
|
} |
61 |
|
5 |
unsigned delay = prng_.Next(delay_range_) + 1; |
62 |
✗✓ |
5 |
if (delay > max_delay_ms_) |
63 |
|
|
delay = max_delay_ms_; |
64 |
|
|
|
65 |
|
5 |
pthread_mutex_unlock(lock_); |
66 |
|
5 |
LogCvmfs(kLogCvmfs, kLogDebug, "backoff throttle %d ms", delay); |
67 |
|
5 |
SafeSleepMs(delay); |
68 |
|
5 |
pthread_mutex_lock(lock_); |
69 |
|
|
} |
70 |
|
29 |
last_throttle_ = now; |
71 |
|
29 |
pthread_mutex_unlock(lock_); |
72 |
|
29 |
} |