@anderspitman/fetch-handler 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/canceled/main.js +43 -0
- package/fetch_handler.js +20 -4
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { serve } from '../../fetch_handler.js';
|
|
2
|
+
|
|
3
|
+
const handler = async (req) => {
|
|
4
|
+
|
|
5
|
+
const abortedPromise = new Promise((resolve, reject) => {
|
|
6
|
+
req.signal.addEventListener('abort', (evt) => {
|
|
7
|
+
reject("canceled");
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const { resPromise, cancelJob } = longrunningJob();
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const res = await Promise.race([ resPromise, abortedPromise ]);
|
|
15
|
+
return res;
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
cancelJob();
|
|
19
|
+
console.warn(e);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function longrunningJob() {
|
|
24
|
+
|
|
25
|
+
let timeoutId;
|
|
26
|
+
|
|
27
|
+
const resPromise = new Promise((resolve, reject) => {
|
|
28
|
+
timeoutId = setTimeout(() => {
|
|
29
|
+
resolve(new Response("Hi there"));
|
|
30
|
+
}, 3000);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
function cancelJob() {
|
|
34
|
+
clearTimeout(timeoutId);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
resPromise,
|
|
39
|
+
cancelJob,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
serve({ handler, port: 3000 });
|
package/fetch_handler.js
CHANGED
|
@@ -19,12 +19,26 @@ async function serve(opt) {
|
|
|
19
19
|
|
|
20
20
|
const hasBody = req.method !== "GET" && req.method !== "HEAD";
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// TODO: might need to make sure this gets cleaned up after normal
|
|
23
|
+
// responses.
|
|
24
|
+
const abortController = new AbortController();
|
|
25
|
+
|
|
26
|
+
req.on('close', () => {
|
|
27
|
+
abortController.abort();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const webReq = new Request(url, {
|
|
23
31
|
method: req.method,
|
|
24
32
|
headers: req.headers,
|
|
25
33
|
body: hasBody ? Readable.toWeb(req) : undefined,
|
|
26
34
|
duplex: hasBody ? "half" : undefined,
|
|
35
|
+
signal: abortController.signal,
|
|
27
36
|
});
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
req: webReq,
|
|
40
|
+
abortSignal: abortController.signal,
|
|
41
|
+
};
|
|
28
42
|
}
|
|
29
43
|
|
|
30
44
|
function sendResponse(nodeRes, res) {
|
|
@@ -49,11 +63,13 @@ async function serve(opt) {
|
|
|
49
63
|
|
|
50
64
|
http.createServer(async (nodeReq, nodeRes) => {
|
|
51
65
|
|
|
52
|
-
const req = incomingToRequest(nodeReq);
|
|
66
|
+
const { req, abortSignal } = incomingToRequest(nodeReq);
|
|
53
67
|
|
|
54
|
-
const res = await opt.handler(req);
|
|
68
|
+
const res = await opt.handler(req, nodeReq, nodeRes);
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
if (res && !abortSignal.aborted) {
|
|
71
|
+
sendResponse(nodeRes, res);
|
|
72
|
+
}
|
|
57
73
|
|
|
58
74
|
}).listen(opt.port);
|
|
59
75
|
|