-
Notifications
You must be signed in to change notification settings - Fork 39
/
concurrent.fetch.ts
71 lines (58 loc) · 1.91 KB
/
concurrent.fetch.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { FetchCall, FetchPlugin, FetchPluginContext } from '../core';
/**
* Plugin to limit the number of concurrent call
* @deprecated Use the one exposed by {@link @ama-sdk/client-fetch}, will be removed in v13
*/
export class ConcurrentFetch implements FetchPlugin {
/** Maximum number of concurrent call */
public maxConcurrentPoolSize: number;
/** Pool of pending fetch calls */
public pool: FetchCall[] = [];
/** Size of the pool of concurrent calls */
private poolSize = 0;
/** List of calls waiting to start */
private readonly waitingResolvers: ((value: boolean) => void)[] = [];
/**
* Concurrent Fetch plugin
* @param maxConcurrentPoolSize Maximum number of concurrent call
*/
constructor(maxConcurrentPoolSize = 10) {
this.maxConcurrentPoolSize = maxConcurrentPoolSize;
}
/**
* Return true if a new call can start
*/
private canStart() {
return this.poolSize <= this.maxConcurrentPoolSize;
}
/**
* Unstack and resolve the promise stopping the call to start
*/
private unstackResolve() {
if (this.canStart() && this.waitingResolvers.length) {
this.waitingResolvers.shift()!(true);
}
}
/** @inheritDoc */
public load(_context: FetchPluginContext) {
this.poolSize++;
return {
canStart: () => new Promise<boolean>((resolve) => this.canStart() ? resolve(true) : this.waitingResolvers.push(resolve)),
transform: async (fetchCall: FetchCall) => {
this.pool.push(fetchCall);
try {
const fetchResponse = await fetchCall;
return fetchResponse;
// eslint-disable-next-line no-useless-catch
} catch (e) {
throw e;
} finally {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.pool = this.pool.filter((call) => call !== fetchCall);
this.poolSize--;
this.unstackResolve();
}
}
};
}
}