1111// See the License for the specific language governing permissions and
1212// limitations under the License.
1313
14- import { GaxiosError } from './common' ;
14+ import { GaxiosError , RetryConfig } from './common' ;
1515
1616export async function getRetryConfig ( err : GaxiosError ) {
1717 let config = getConfig ( err ) ;
@@ -33,6 +33,18 @@ export async function getRetryConfig(err: GaxiosError) {
3333 config . noResponseRetries === undefined || config . noResponseRetries === null
3434 ? 2
3535 : config . noResponseRetries ;
36+ config . retryDelayMultiplier = config . retryDelayMultiplier
37+ ? config . retryDelayMultiplier
38+ : 2 ;
39+ config . timeOfFirstRequest = config . timeOfFirstRequest
40+ ? config . timeOfFirstRequest
41+ : Date . now ( ) ;
42+ config . totalTimeout = config . totalTimeout
43+ ? config . totalTimeout
44+ : Number . MAX_SAFE_INTEGER ;
45+ config . maxRetryDelay = config . maxRetryDelay
46+ ? config . maxRetryDelay
47+ : Number . MAX_SAFE_INTEGER ;
3648
3749 // If this wasn't in the list of status codes where we want
3850 // to automatically retry, return.
@@ -61,12 +73,7 @@ export async function getRetryConfig(err: GaxiosError) {
6173 return { shouldRetry : false , config : err . config } ;
6274 }
6375
64- // Calculate time to wait with exponential backoff.
65- // If this is the first retry, look for a configured retryDelay.
66- const retryDelay = config . currentRetryAttempt ? 0 : config . retryDelay ?? 100 ;
67- // Formula: retryDelay + ((2^c - 1 / 2) * 1000)
68- const delay =
69- retryDelay + ( ( Math . pow ( 2 , config . currentRetryAttempt ) - 1 ) / 2 ) * 1000 ;
76+ const delay = getNextRetryDelay ( config ) ;
7077
7178 // We're going to retry! Incremenent the counter.
7279 err . config . retryConfig ! . currentRetryAttempt ! += 1 ;
@@ -157,3 +164,25 @@ function getConfig(err: GaxiosError) {
157164 }
158165 return ;
159166}
167+
168+ /**
169+ * Gets the delay to wait before the next retry.
170+ *
171+ * @param {RetryConfig } config The current set of retry options
172+ * @returns {number } the amount of ms to wait before the next retry attempt.
173+ */
174+ function getNextRetryDelay ( config : RetryConfig ) {
175+ // Calculate time to wait with exponential backoff.
176+ // If this is the first retry, look for a configured retryDelay.
177+ const retryDelay = config . currentRetryAttempt ? 0 : config . retryDelay ?? 100 ;
178+ // Formula: retryDelay + ((retryDelayMultiplier^currentRetryAttempt - 1 / 2) * 1000)
179+ const calculatedDelay =
180+ retryDelay +
181+ ( ( Math . pow ( config . retryDelayMultiplier ! , config . currentRetryAttempt ! ) - 1 ) /
182+ 2 ) *
183+ 1000 ;
184+ const maxAllowableDelay =
185+ config . totalTimeout ! - ( Date . now ( ) - config . timeOfFirstRequest ! ) ;
186+
187+ return Math . min ( calculatedDelay , maxAllowableDelay , config . maxRetryDelay ! ) ;
188+ }
0 commit comments