I have some Deno server code that looks roughly like this:
Deno.serve((req) => {
let asyncIterator = getChunkIterator(req.url);
const stream = new ReadableStream({
async pull(controller) {
try {
const { value, done } = await asyncIterator.next();
if (done) {
controller.close();
return;
}
controller.enqueue(value);
} catch (err) {
controller.error(err);
}
}
});
let response = new Response(stream);
return response;
});
The response streaming can take several seconds, and the client may disconnect half-way through. I need to detect this so that I can stop the (separate) "worker" server that is producing the chunks of data for that client.
I have no idea how to do this, since with Deno.serve
you just return
the Response
object, rather than being given a stream to write to.
You need to implement cancel
method of the ReadableStream
Starting from Deno version 1.36.4, connection drops will be accurately detected when responding with a ReadableStream
, and the cancel
method will be called with the reason "resource closed"
(implemented in this commit)
Deno.serve((req) => {
let asyncIterator = getChunkIterator(req.url);
const stream = new ReadableStream({
async pull(controller) {
/* ... */
},
cancel(reason) {
// reason === 'resource closed' when connection drops
// cleanup your resource
}
});
let response = new Response(stream);
return response;
});