Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/math/exponentialbackoff.js
2868 views
1
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
16
/**
17
* @fileoverview Utility class to manage the mathematics behind computing an
18
* exponential backoff model. Given an initial backoff value and a maximum
19
* backoff value, every call to backoff() will double the value until maximum
20
* backoff value is reached.
21
*
22
*/
23
24
25
goog.provide('goog.math.ExponentialBackoff');
26
27
goog.require('goog.asserts');
28
29
30
31
/**
32
* @struct
33
* @constructor
34
*
35
* @param {number} initialValue The initial backoff value.
36
* @param {number} maxValue The maximum backoff value.
37
* @param {number=} opt_randomFactor When set, adds randomness to the backoff
38
* and decay to avoid a thundering herd problem. Should be a number between
39
* 0 and 1, where 0 means no randomness and 1 means a factor of 0x to 2x.
40
* @param {number=} opt_backoffFactor The factor to backoff by. Defaults to 2.
41
* Should be a number greater than 1.
42
* @param {number=} opt_decayFactor The factor to decay by. Defaults to 2.
43
* Should be a number between greater than one.
44
*/
45
goog.math.ExponentialBackoff = function(
46
initialValue, maxValue, opt_randomFactor, opt_backoffFactor,
47
opt_decayFactor) {
48
goog.asserts.assert(
49
initialValue > 0, 'Initial value must be greater than zero.');
50
goog.asserts.assert(
51
maxValue >= initialValue,
52
'Max value should be at least as large as initial value.');
53
54
if (goog.isDef(opt_randomFactor)) {
55
goog.asserts.assert(
56
opt_randomFactor >= 0 && opt_randomFactor <= 1,
57
'Randomness factor should be between 0 and 1.');
58
}
59
60
if (goog.isDef(opt_backoffFactor)) {
61
goog.asserts.assert(
62
opt_backoffFactor > 1, 'Backoff factor should be greater than 1');
63
}
64
65
if (goog.isDef(opt_decayFactor)) {
66
goog.asserts.assert(
67
opt_decayFactor >= 1, 'Decay factor should be greater than 1');
68
}
69
70
/**
71
* @type {number}
72
* @private
73
*/
74
this.initialValue_ = initialValue;
75
76
/**
77
* @type {number}
78
* @private
79
*/
80
this.maxValue_ = maxValue;
81
82
/**
83
* The current backoff value.
84
* @type {number}
85
* @private
86
*/
87
this.currValue_ = initialValue;
88
89
/**
90
* The current backoff value minus the random wait (if there is any).
91
* @type {number}
92
* @private
93
*/
94
this.currBaseValue_ = initialValue;
95
96
/**
97
* The random factor to apply to the backoff value to avoid a thundering herd
98
* problem. Should be a number between 0 and 1, where 0 means no randomness
99
* and 1 means a factor of 0x to 2x.
100
* @type {number}
101
* @private
102
*/
103
this.randomFactor_ = opt_randomFactor || 0;
104
105
/**
106
* Factor to backoff by.
107
* @type {number}
108
* @private
109
*/
110
this.backoffFactor_ = opt_backoffFactor || 2;
111
112
/**
113
* Factor to decay by.
114
* @type {number}
115
* @private
116
*/
117
this.decayFactor_ = opt_decayFactor || 2;
118
};
119
120
121
/**
122
* The number of backoffs that have happened.
123
* @type {number}
124
* @private
125
*/
126
goog.math.ExponentialBackoff.prototype.currBackoffCount_ = 0;
127
128
129
/**
130
* The number of decays that have happened.
131
* @type {number}
132
* @private
133
*/
134
goog.math.ExponentialBackoff.prototype.currDecayCount_ = 0;
135
136
137
/**
138
* Resets the backoff value to its initial value.
139
*/
140
goog.math.ExponentialBackoff.prototype.reset = function() {
141
this.currValue_ = this.initialValue_;
142
this.currBaseValue_ = this.initialValue_;
143
this.currBackoffCount_ = 0;
144
this.currDecayCount_ = 0;
145
};
146
147
148
/**
149
* @return {number} The current backoff value.
150
*/
151
goog.math.ExponentialBackoff.prototype.getValue = function() {
152
return this.currValue_;
153
};
154
155
156
/**
157
* @return {number} The number of times this class has backed off.
158
*/
159
goog.math.ExponentialBackoff.prototype.getBackoffCount = function() {
160
return this.currBackoffCount_;
161
};
162
163
164
/**
165
* @return {number} The number of times this class has decayed.
166
*/
167
goog.math.ExponentialBackoff.prototype.getDecayCount = function() {
168
return this.currDecayCount_;
169
};
170
171
172
/**
173
* Initiates a backoff.
174
*/
175
goog.math.ExponentialBackoff.prototype.backoff = function() {
176
// If we haven't hit the maximum value yet, keep increasing the base value.
177
this.currBaseValue_ =
178
Math.min(this.maxValue_, this.currBaseValue_ * this.backoffFactor_);
179
180
var randomWait = this.randomFactor_ ?
181
Math.round(
182
this.randomFactor_ * (Math.random() - 0.5) * 2 *
183
this.currBaseValue_) :
184
0;
185
this.currValue_ = Math.min(this.maxValue_, this.currBaseValue_ + randomWait);
186
this.currBackoffCount_++;
187
};
188
189
190
/**
191
* Initiates a decay.
192
*/
193
goog.math.ExponentialBackoff.prototype.decay = function() {
194
// If we haven't hit the initial value yet, keep decreasing the base value.
195
this.currBaseValue_ =
196
Math.max(this.initialValue_, this.currBaseValue_ / this.decayFactor_);
197
198
var randomWait = this.randomFactor_ ?
199
Math.round(
200
this.randomFactor_ * (Math.random() - 0.5) * 2 *
201
this.currBaseValue_) :
202
0;
203
this.currValue_ =
204
Math.max(this.initialValue_, this.currBaseValue_ + randomWait);
205
this.currDecayCount_++;
206
};
207
208