1
1
import axios , { AxiosInstance , AxiosRequestConfig , AxiosResponse , CreateAxiosDefaults } from 'axios' ;
2
2
import { OAuthClient } from './oauth/oauth-client' ;
3
3
import { RestError } from './rest-error' ;
4
+ import axiosRetry from "axios-retry" ;
4
5
/*
5
6
* Confluent-Schema-Registry-TypeScript - Node.js wrapper for Confluent Schema Registry
6
7
*
@@ -33,7 +34,6 @@ export interface BearerAuthCredentials {
33
34
identityPoolId ?: string ,
34
35
}
35
36
36
- //TODO: Consider retry policy, may need additional libraries on top of Axios
37
37
export interface ClientConfig {
38
38
baseURLs : string [ ] ,
39
39
cacheCapacity ?: number ,
@@ -42,6 +42,9 @@ export interface ClientConfig {
42
42
createAxiosDefaults ?: CreateAxiosDefaults ,
43
43
basicAuthCredentials ?: BasicAuthCredentials ,
44
44
bearerAuthCredentials ?: BearerAuthCredentials ,
45
+ maxRetries ?: number ,
46
+ retriesWaitMs ?: number ,
47
+ retriesMaxWaitMs ?: number ,
45
48
}
46
49
47
50
const toBase64 = ( str : string ) : string => Buffer . from ( str ) . toString ( 'base64' ) ;
@@ -53,19 +56,38 @@ export class RestService {
53
56
private oauthBearer : boolean = false ;
54
57
55
58
constructor ( baseURLs : string [ ] , isForward ?: boolean , axiosDefaults ?: CreateAxiosDefaults ,
56
- basicAuthCredentials ?: BasicAuthCredentials , bearerAuthCredentials ?: BearerAuthCredentials ) {
59
+ basicAuthCredentials ?: BasicAuthCredentials , bearerAuthCredentials ?: BearerAuthCredentials ,
60
+ maxRetries ?: number , retriesWaitMs ?: number , retriesMaxWaitMs ?: number ) {
57
61
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
+ } ) ;
58
71
this . baseURLs = baseURLs ;
59
72
60
73
if ( isForward ) {
61
74
this . setHeaders ( { 'X-Forward' : 'true' } ) ;
62
75
}
63
76
this . setHeaders ( { 'Content-Type' : 'application/vnd.schemaregistry.v1+json' } ) ;
64
-
77
+
65
78
this . handleBasicAuth ( basicAuthCredentials ) ;
66
79
this . handleBearerAuth ( bearerAuthCredentials ) ;
67
80
}
68
81
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
+
69
91
handleBasicAuth ( basicAuthCredentials ?: BasicAuthCredentials ) : void {
70
92
if ( basicAuthCredentials ) {
71
93
switch ( basicAuthCredentials . credentialsSource ) {
0 commit comments