Skip to content
This repository was archived by the owner on May 5, 2023. It is now read-only.

Commit b293356

Browse files
committed
Dedup the loadResolver() function invocations
Only one "in-flight" creation / revalidation of the `FindProxyForURL()` function will be executed at a time. If two concurrent HTTP requests come in and the `FindProxyForURL()` function is still be retrieved, then they will share the same promise for the result.
1 parent 8f226c6 commit b293356

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

src/agent.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default class PacProxyAgent extends Agent {
4141
cache?: Readable;
4242
resolver?: FindProxyForURL;
4343
resolverHash: string;
44+
resolverPromise?: Promise<FindProxyForURL>;
4445

4546
constructor(uri: string, opts: PacProxyAgentOptions = {}) {
4647
super(opts);
@@ -52,19 +53,35 @@ export default class PacProxyAgent extends Agent {
5253
this.cache = undefined;
5354
this.resolver = undefined;
5455
this.resolverHash = '';
56+
this.resolverPromise = undefined;
5557

5658
// For `PacResolver`
5759
if (!this.opts.filename) {
5860
this.opts.filename = uri;
5961
}
6062
}
6163

64+
private clearResolverPromise = (): void => {
65+
this.resolverPromise = undefined;
66+
};
67+
6268
/**
6369
* Loads the PAC proxy file from the source if necessary, and returns
6470
* a generated `FindProxyForURL()` resolver function to use.
6571
*
6672
* @api private
6773
*/
74+
private getResolver(): Promise<FindProxyForURL> {
75+
if (!this.resolverPromise) {
76+
this.resolverPromise = this.loadResolver();
77+
this.resolverPromise.then(
78+
this.clearResolverPromise,
79+
this.clearResolverPromise
80+
);
81+
}
82+
return this.resolverPromise;
83+
}
84+
6885
private async loadResolver(): Promise<FindProxyForURL> {
6986
try {
7087
// (Re)load the contents of the PAC file URI
@@ -87,8 +104,7 @@ export default class PacProxyAgent extends Agent {
87104
debug('Creating new proxy resolver instance');
88105
this.resolver = createPacResolver(code, this.opts);
89106

90-
// Store that sha1 hash on the resolver instance
91-
// for future comparison purposes
107+
// Store that sha1 hash for future comparison purposes
92108
this.resolverHash = hash;
93109

94110
return this.resolver;
@@ -133,14 +149,14 @@ export default class PacProxyAgent extends Agent {
133149
const { secureEndpoint } = opts;
134150

135151
// First, get a generated `FindProxyForURL()` function,
136-
// either cached or retreived from the source
137-
const resolver = await this.loadResolver();
152+
// either cached or retrieved from the source
153+
const resolver = await this.getResolver();
138154

139155
// Calculate the `url` parameter
140156
const defaultPort = secureEndpoint ? 443 : 80;
141157
let path = req.path;
142158
let search: string | null = null;
143-
let firstQuestion = path.indexOf('?');
159+
const firstQuestion = path.indexOf('?');
144160
if (firstQuestion !== -1) {
145161
search = path.substring(firstQuestion);
146162
path = path.substring(0, firstQuestion);

0 commit comments

Comments
 (0)