1+ import _defineProperty from "@babel/runtime/helpers/defineProperty" ;
2+
3+ function ownKeys ( object , enumerableOnly ) { var keys = Object . keys ( object ) ; if ( Object . getOwnPropertySymbols ) { var symbols = Object . getOwnPropertySymbols ( object ) ; if ( enumerableOnly ) symbols = symbols . filter ( function ( sym ) { return Object . getOwnPropertyDescriptor ( object , sym ) . enumerable ; } ) ; keys . push . apply ( keys , symbols ) ; } return keys ; }
4+
5+ function _objectSpread ( target ) { for ( var i = 1 ; i < arguments . length ; i ++ ) { var source = arguments [ i ] != null ? arguments [ i ] : { } ; if ( i % 2 ) { ownKeys ( Object ( source ) , true ) . forEach ( function ( key ) { _defineProperty ( target , key , source [ key ] ) ; } ) ; } else if ( Object . getOwnPropertyDescriptors ) { Object . defineProperties ( target , Object . getOwnPropertyDescriptors ( source ) ) ; } else { ownKeys ( Object ( source ) ) . forEach ( function ( key ) { Object . defineProperty ( target , key , Object . getOwnPropertyDescriptor ( source , key ) ) ; } ) ; } } return target ; }
6+
7+ import Axios from 'axios' ;
8+ var defaultConfig = {
9+ maxRequests : 5 ,
10+ retryLimit : 5 ,
11+ retryDelay : 300
12+ } ;
13+ export function ConcurrencyQueue ( _ref ) {
14+ var _this = this ;
15+
16+ var axios = _ref . axios ,
17+ config = _ref . config ;
18+
19+ if ( ! axios ) {
20+ throw Error ( 'Axios instance is not present' ) ;
21+ }
22+
23+ if ( config ) {
24+ if ( config . maxRequests && config . maxRequests <= 0 ) {
25+ throw Error ( 'Concurrency Manager Error: minimum concurrent requests is 1' ) ;
26+ } else if ( config . retryLimit && config . retryLimit <= 0 ) {
27+ throw Error ( 'Retry Policy Error: minimum retry limit is 1' ) ;
28+ } else if ( config . retryDelay && config . retryDelay < 300 ) {
29+ throw Error ( 'Retry Policy Error: minimum retry delay for requests is 300' ) ;
30+ }
31+ }
32+
33+ this . config = Object . assign ( { } , defaultConfig , config ) ;
34+ this . queue = [ ] ;
35+ this . running = [ ] ;
36+ this . paused = false ; // Initial shift will check running request,
37+ // and adds request to running queue if max requests are not running
38+
39+ this . initialShift = function ( ) {
40+ if ( _this . running . length < _this . config . maxRequests && ! _this . paused ) {
41+ shift ( ) ;
42+ }
43+ } ; // INTERNAL: Shift the queued item to running queue
44+
45+
46+ var shift = function shift ( ) {
47+ if ( _this . queue . length && ! _this . paused ) {
48+ var queueItem = _this . queue . shift ( ) ;
49+
50+ queueItem . resolve ( queueItem . request ) ;
51+
52+ _this . running . push ( queueItem ) ;
53+ }
54+ } ; // Append the request at start of queue
55+
56+
57+ this . unshift = function ( requestPromise ) {
58+ _this . queue . unshift ( requestPromise ) ;
59+ } ;
60+
61+ this . push = function ( requestPromise ) {
62+ _this . queue . push ( requestPromise ) ;
63+
64+ _this . initialShift ( ) ;
65+ } ;
66+
67+ this . clear = function ( ) {
68+ var requests = _this . queue . splice ( 0 , _this . queue . length ) ;
69+
70+ requests . forEach ( function ( element ) {
71+ element . request . source . cancel ( ) ;
72+ } ) ;
73+ } ; // Detach the interceptors
74+
75+
76+ this . detach = function ( ) {
77+ axios . interceptors . request . eject ( _this . interceptors . request ) ;
78+ axios . interceptors . response . eject ( _this . interceptors . response ) ;
79+ _this . interceptors = {
80+ request : null ,
81+ response : null
82+ } ;
83+ } ; // Request interseptor to queue the request
84+
85+
86+ var requestHandler = function requestHandler ( request ) {
87+ request . retryCount = request . retryCount || 0 ;
88+
89+ if ( request . headers . authorization && request . headers . authorization !== undefined ) {
90+ delete request . headers . authtoken ;
91+ }
92+
93+ if ( request . cancelToken === undefined ) {
94+ var source = Axios . CancelToken . source ( ) ;
95+ request . cancelToken = source . token ;
96+ request . source = source ;
97+ }
98+
99+ if ( _this . paused && request . retryCount > 0 ) {
100+ return new Promise ( function ( resolve ) {
101+ _this . unshift ( {
102+ request : request ,
103+ resolve : resolve
104+ } ) ;
105+ } ) ;
106+ } else if ( request . retryCount > 0 ) {
107+ return request ;
108+ }
109+
110+ return new Promise ( function ( resolve ) {
111+ _this . push ( {
112+ request : request ,
113+ resolve : resolve
114+ } ) ;
115+ } ) ;
116+ } ;
117+
118+ var delay = function delay ( time ) {
119+ if ( ! _this . paused ) {
120+ _this . paused = true ; // Check for current running request.
121+ // Wait for running queue to complete.
122+ // Wait and prosed the Queued request.
123+
124+ if ( _this . running . length > 0 ) {
125+ setTimeout ( function ( ) {
126+ delay ( time ) ;
127+ } , time ) ;
128+ }
129+
130+ return new Promise ( function ( resolve ) {
131+ return setTimeout ( function ( ) {
132+ _this . paused = false ;
133+
134+ for ( var i = 0 ; i < _this . config . maxRequests ; i ++ ) {
135+ _this . initialShift ( ) ;
136+ }
137+ } , time ) ;
138+ } ) ;
139+ }
140+ } ; // Response interceptor used for
141+
142+
143+ var responseHandler = function responseHandler ( response ) {
144+ _this . running . shift ( ) ;
145+
146+ shift ( ) ;
147+ return response ;
148+ } ;
149+
150+ var responseErrorHandler = function responseErrorHandler ( error ) {
151+ var networkError = error . config . retryCount ;
152+ var retryErrorType = null ;
153+
154+ if ( ! _this . config . retryOnError || networkError > _this . config . retryLimit ) {
155+ return Promise . reject ( responseHandler ( error ) ) ;
156+ } // Error handling
157+
158+
159+ var wait = _this . config . retryDelay ;
160+ var response = error . response ;
161+
162+ if ( ! response ) {
163+ if ( error . code === 'ECONNABORTED' ) {
164+ error . response = _objectSpread ( _objectSpread ( { } , error . response ) , { } , {
165+ status : 408 ,
166+ statusText : "timeout of " . concat ( _this . config . timeout , "ms exceeded" )
167+ } ) ;
168+ } else {
169+ return Promise . reject ( responseHandler ( error ) ) ;
170+ }
171+ } else if ( response . status === 429 ) {
172+ retryErrorType = "Error with status: " . concat ( response . status ) ;
173+ networkError ++ ;
174+
175+ if ( networkError > _this . config . retryLimit ) {
176+ return Promise . reject ( responseHandler ( error ) ) ;
177+ }
178+
179+ _this . running . shift ( ) ;
180+
181+ wait = 1000 ; // Cooldown the running requests
182+
183+ delay ( wait ) ;
184+ error . config . retryCount = networkError ;
185+ return axios ( updateRequestConfig ( error , retryErrorType , wait ) ) ;
186+ } else if ( _this . config . retryCondition && _this . config . retryCondition ( error ) ) {
187+ retryErrorType = "Error with status: " . concat ( response . status ) ;
188+ networkError ++ ;
189+
190+ if ( networkError > _this . config . retryLimit ) {
191+ return Promise . reject ( responseHandler ( error ) ) ;
192+ }
193+
194+ if ( _this . config . retryDelayOptions ) {
195+ if ( _this . config . retryDelayOptions . customBackoff ) {
196+ wait = _this . config . retryDelayOptions . customBackoff ( networkError , error ) ;
197+
198+ if ( wait && wait <= 0 ) {
199+ return Promise . reject ( responseHandler ( error ) ) ;
200+ }
201+ } else if ( _this . config . retryDelayOptions . base ) {
202+ wait = _this . config . retryDelayOptions . base * networkError ;
203+ }
204+ } else {
205+ wait = _this . config . retryDelay ;
206+ }
207+
208+ error . config . retryCount = networkError ;
209+ return new Promise ( function ( resolve ) {
210+ return setTimeout ( function ( ) {
211+ return resolve ( axios ( updateRequestConfig ( error , retryErrorType , wait ) ) ) ;
212+ } , wait ) ;
213+ } ) ;
214+ }
215+
216+ return Promise . reject ( responseHandler ( error ) ) ;
217+ } ;
218+
219+ this . interceptors = {
220+ request : null ,
221+ response : null
222+ } ;
223+
224+ var updateRequestConfig = function updateRequestConfig ( error , retryErrorType , wait ) {
225+ var requestConfig = error . config ;
226+
227+ _this . config . logHandler ( 'warning' , "" . concat ( retryErrorType , " error occurred. Waiting for " ) . concat ( wait , " ms before retrying..." ) ) ;
228+
229+ if ( axios !== undefined && axios . defaults !== undefined ) {
230+ if ( axios . defaults . agent === requestConfig . agent ) {
231+ delete requestConfig . agent ;
232+ }
233+
234+ if ( axios . defaults . httpAgent === requestConfig . httpAgent ) {
235+ delete requestConfig . httpAgent ;
236+ }
237+
238+ if ( axios . defaults . httpsAgent === requestConfig . httpsAgent ) {
239+ delete requestConfig . httpsAgent ;
240+ }
241+ }
242+
243+ requestConfig . transformRequest = [ function ( data ) {
244+ return data ;
245+ } ] ;
246+ return requestConfig ;
247+ } ; // Adds interseptors in axios to queue request
248+
249+
250+ this . interceptors . request = axios . interceptors . request . use ( requestHandler ) ;
251+ this . interceptors . response = axios . interceptors . response . use ( responseHandler , responseErrorHandler ) ;
252+ }
0 commit comments