11import axios , { AxiosInstance , AxiosRequestConfig , AxiosResponse , CreateAxiosDefaults } from 'axios' ;
22import { OAuthClient } from './oauth/oauth-client' ;
33import { RestError } from './rest-error' ;
4+ import axiosRetry from "axios-retry" ;
45/*
56 * Confluent-Schema-Registry-TypeScript - Node.js wrapper for Confluent Schema Registry
67 *
@@ -33,7 +34,6 @@ export interface BearerAuthCredentials {
3334 identityPoolId ?: string ,
3435}
3536
36- //TODO: Consider retry policy, may need additional libraries on top of Axios
3737export interface ClientConfig {
3838 baseURLs : string [ ] ,
3939 cacheCapacity ?: number ,
@@ -42,6 +42,9 @@ export interface ClientConfig {
4242 createAxiosDefaults ?: CreateAxiosDefaults ,
4343 basicAuthCredentials ?: BasicAuthCredentials ,
4444 bearerAuthCredentials ?: BearerAuthCredentials ,
45+ maxRetries ?: number ,
46+ retriesWaitMs ?: number ,
47+ retriesMaxWaitMs ?: number ,
4548}
4649
4750const toBase64 = ( str : string ) : string => Buffer . from ( str ) . toString ( 'base64' ) ;
@@ -53,19 +56,38 @@ export class RestService {
5356 private oauthBearer : boolean = false ;
5457
5558 constructor ( baseURLs : string [ ] , isForward ?: boolean , axiosDefaults ?: CreateAxiosDefaults ,
56- basicAuthCredentials ?: BasicAuthCredentials , bearerAuthCredentials ?: BearerAuthCredentials ) {
59+ basicAuthCredentials ?: BasicAuthCredentials , bearerAuthCredentials ?: BearerAuthCredentials ,
60+ maxRetries ?: number , retriesWaitMs ?: number , retriesMaxWaitMs ?: number ) {
5761 this . client = axios . create ( axiosDefaults ) ;
62+ axiosRetry ( this . client , {
63+ retries : maxRetries ?? 2 ,
64+ retryDelay : ( retryCount ) => {
65+ return this . fullJitter ( retriesWaitMs ?? 1000 , retriesMaxWaitMs ?? 20000 , retryCount - 1 )
66+ } ,
67+ retryCondition : ( error ) => {
68+ return this . isRetriable ( error . response ?. status ?? 0 ) ;
69+ }
70+ } ) ;
5871 this . baseURLs = baseURLs ;
5972
6073 if ( isForward ) {
6174 this . setHeaders ( { 'X-Forward' : 'true' } ) ;
6275 }
6376 this . setHeaders ( { 'Content-Type' : 'application/vnd.schemaregistry.v1+json' } ) ;
64-
77+
6578 this . handleBasicAuth ( basicAuthCredentials ) ;
6679 this . handleBearerAuth ( bearerAuthCredentials ) ;
6780 }
6881
82+ isRetriable ( statusCode : number ) : boolean {
83+ return statusCode == 408 || statusCode == 429
84+ || statusCode == 500 || statusCode == 502 || statusCode == 503 || statusCode == 504 ;
85+ }
86+
87+ fullJitter ( baseDelayMs : number , maxDelayMs : number , retriesAttempted : number ) : number {
88+ return Math . random ( ) * Math . min ( maxDelayMs , baseDelayMs * 2 ** retriesAttempted )
89+ }
90+
6991 handleBasicAuth ( basicAuthCredentials ?: BasicAuthCredentials ) : void {
7092 if ( basicAuthCredentials ) {
7193 switch ( basicAuthCredentials . credentialsSource ) {
0 commit comments