Skip to content

Commit c2a5595

Browse files
kuhetrivikr
andauthored
chore: switch to platform AbortController & Signal implementations after dropping Node.js 14 (#1308)
* backwards compatibility for waiter abortController * rename variable, widen input interfaces * update unit test * comment preferred vs legacy control flow --------- Co-authored-by: Trivikram Kamat <[email protected]>
1 parent c16e014 commit c2a5595

File tree

12 files changed

+78
-25
lines changed

12 files changed

+78
-25
lines changed

.changeset/spotty-cars-do.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@smithy/fetch-http-handler": minor
3+
"@smithy/node-http-handler": minor
4+
"@smithy/abort-controller": minor
5+
"@smithy/util-waiter": minor
6+
"@smithy/types": minor
7+
---
8+
9+
use platform AbortController|AbortSignal implementations

packages/abort-controller/src/AbortController.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
import { AbortController as IAbortController } from "@smithy/types";
1+
import { AbortController as DeprecatedAbortController } from "@smithy/types";
22

33
import { AbortSignal } from "./AbortSignal";
44

5-
export { IAbortController };
5+
/**
6+
* @public
7+
*/
8+
export { DeprecatedAbortController as IAbortController };
69

710
/**
8-
* This implementation was added as Node.js didn't support AbortController prior to 15.x
11+
* @deprecated This implementation was added as Node.js didn't support AbortController prior to 15.x
912
* Use native implementation in browsers or Node.js \>=15.4.0.
1013
*
1114
* @public
1215
*/
13-
export class AbortController implements IAbortController {
16+
export class AbortController implements DeprecatedAbortController {
1417
public readonly signal: AbortSignal = new AbortSignal();
1518

1619
abort(): void {

packages/abort-controller/src/AbortSignal.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { AbortHandler, AbortSignal as IAbortSignal } from "@smithy/types";
1+
import { AbortHandler, AbortSignal as DeprecatedAbortSignal } from "@smithy/types";
22

3-
export { AbortHandler, IAbortSignal };
3+
/**
4+
* @public
5+
*/
6+
export { AbortHandler, DeprecatedAbortSignal as IAbortSignal };
47

58
/**
69
* @public
710
*/
8-
export class AbortSignal implements IAbortSignal {
11+
export class AbortSignal implements DeprecatedAbortSignal {
912
public onabort: AbortHandler | null = null;
1013
private _aborted = false;
1114

packages/fetch-http-handler/src/fetch-http-handler.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,18 @@ export class FetchHttpHandler implements HttpHandler<FetchHttpHandlerConfig> {
164164
if (abortSignal) {
165165
raceOfPromises.push(
166166
new Promise<never>((resolve, reject) => {
167-
abortSignal.onabort = () => {
167+
const onAbort = () => {
168168
const abortError = new Error("Request aborted");
169169
abortError.name = "AbortError";
170170
reject(abortError);
171171
};
172+
if (typeof (abortSignal as AbortSignal).addEventListener === "function") {
173+
// preferred.
174+
(abortSignal as AbortSignal).addEventListener("abort", onAbort);
175+
} else {
176+
// backwards compatibility
177+
abortSignal.onabort = onAbort;
178+
}
172179
})
173180
);
174181
}

packages/node-http-handler/src/node-http-handler.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,12 @@ describe("NodeHttpHandler", () => {
619619
};
620620
mockHttpsServer.addListener("request", createResponseFunction(mockResponse));
621621
let httpRequest: http.ClientRequest;
622-
let reqAbortSpy: any;
622+
let reqDestroySpy: any;
623623
const spy = jest.spyOn(https, "request").mockImplementationOnce(() => {
624624
const calls = spy.mock.calls;
625625
const currentIndex = calls.length - 1;
626626
httpRequest = https.request(calls[currentIndex][0], calls[currentIndex][1]);
627-
reqAbortSpy = jest.spyOn(httpRequest, "abort");
627+
reqDestroySpy = jest.spyOn(httpRequest, "destroy");
628628
return httpRequest;
629629
});
630630
const nodeHttpHandler = new NodeHttpHandler();
@@ -650,7 +650,7 @@ describe("NodeHttpHandler", () => {
650650
)
651651
).rejects.toHaveProperty("name", "AbortError");
652652

653-
expect(reqAbortSpy.mock.calls.length).toBe(1);
653+
expect(reqDestroySpy.mock.calls.length).toBe(1);
654654
});
655655
});
656656

packages/node-http-handler/src/node-http-handler.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,20 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
243243

244244
// wire-up abort logic
245245
if (abortSignal) {
246-
abortSignal.onabort = () => {
246+
const onAbort = () => {
247247
// ensure request is destroyed
248-
req.abort();
248+
req.destroy();
249249
const abortError = new Error("Request aborted");
250250
abortError.name = "AbortError";
251251
reject(abortError);
252252
};
253+
if (typeof (abortSignal as AbortSignal).addEventListener === "function") {
254+
// preferred.
255+
(abortSignal as AbortSignal).addEventListener("abort", onAbort);
256+
} else {
257+
// backwards compatibility
258+
abortSignal.onabort = onAbort;
259+
}
253260
}
254261

255262
// Workaround for bug report in Node.js https://github.com/nodejs/node/issues/47137

packages/node-http-handler/src/node-http2-handler.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,19 @@ export class NodeHttp2Handler implements HttpHandler<NodeHttp2HandlerOptions> {
181181
}
182182

183183
if (abortSignal) {
184-
abortSignal.onabort = () => {
184+
const onAbort = () => {
185185
req.close();
186186
const abortError = new Error("Request aborted");
187187
abortError.name = "AbortError";
188188
rejectWithDestroy(abortError);
189189
};
190+
if (typeof (abortSignal as AbortSignal).addEventListener === "function") {
191+
// preferred.
192+
(abortSignal as AbortSignal).addEventListener("abort", onAbort);
193+
} else {
194+
// backwards compatibility
195+
abortSignal.onabort = onAbort;
196+
}
190197
}
191198

192199
// Set up handlers for errors

packages/types/src/abort-handler.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { AbortSignal as DeprecatedAbortSignal } from "./abort";
2+
3+
/**
4+
* @public
5+
*/
6+
export interface AbortHandler {
7+
(this: AbortSignal | DeprecatedAbortSignal, ev: any): any;
8+
}

packages/types/src/abort.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import type { AbortHandler } from "./abort-handler";
2+
13
/**
24
* @public
35
*/
4-
export interface AbortHandler {
5-
(this: AbortSignal, ev: any): any;
6-
}
6+
export { AbortHandler };
77

88
/**
99
* @public
10+
* @deprecated use platform (global) type for AbortSignal.
1011
*
1112
* Holders of an AbortSignal object may query if the associated operation has
1213
* been aborted and register an onabort handler.
@@ -28,6 +29,7 @@ export interface AbortSignal {
2829

2930
/**
3031
* @public
32+
* @deprecated use platform (global) type for AbortController.
3133
*
3234
* The AWS SDK uses a Controller/Signal model to allow for cooperative
3335
* cancellation of asynchronous operations. When initiating such an operation,

packages/types/src/http.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AbortSignal } from "./abort";
1+
import { AbortSignal as DeprecatedAbortSignal } from "./abort";
22
import { URI } from "./uri";
33

44
/**
@@ -106,7 +106,7 @@ export interface HttpMessage {
106106
* Represents the options that may be passed to an Http Handler.
107107
*/
108108
export interface HttpHandlerOptions {
109-
abortSignal?: AbortSignal;
109+
abortSignal?: AbortSignal | DeprecatedAbortSignal;
110110

111111
/**
112112
* The maximum time in milliseconds that the connection phase of a request

0 commit comments

Comments
 (0)