import Timeout = NodeJS . Timeout ; export class RetryStrategy { private _times : number ; private backoffTime : number ; private readonly maximumBackoff : number ; private readonly maxRetries : number ; constructor ( maxRetries , initialBackoff , maximumBackoff ) { this . _times = 0 ; this . maxRetries = maxRetries ; this . backoffTime = initialBackoff ; this . maximumBackoff = maximumBackoff ; } public async execute < T extends ( ... args : any [ ] ) => unknown > ( task ) { const timeout = this . nextTime ( ) ; if ( timeout ) { await this . delay ( timeout ) ; await task ( ) ; } return this . maxRetries - this . _times ; } private delay ( timeout ) { return new Promise < void > ( ( resolve ) : Timeout => setTimeout ( resolve , timeout ) ) ; } private nextTime ( ) { if ( this . _times < this . maxRetries ) { return this . increaseBackoffTime ( ) ; } } private increaseBackoffTime ( ) { this . backoffTime *= Math . pow ( 2 , ++ this . _times - 1 ) ; return Math . min ( this . backoffTime , this . maximumBackoff ) ; } }