mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) tweak handler for aborted connections to work on modern node
Summary: It became hard to detect aborted connections in node 16. In node 14, req.on('close', ...) did the job. Thid diff adds a work-around, until a better way is discovered or added. Aborting a req will typically lead to 'close' being called on the response, without writableFinished being set. - https://github.com/nodejs/node/issues/38924 - https://github.com/nodejs/node/issues/40775 Test Plan: existing DocApiForwarder test passes; manually checking on various node versions. Reviewers: JakubSerafin Reviewed By: JakubSerafin Differential Revision: https://phab.getgrist.com/D3923
This commit is contained in:
parent
52469c5a7e
commit
7e50467396
@ -10,6 +10,7 @@ import { IDocWorkerMap } from "app/server/lib/DocWorkerMap";
|
|||||||
import { expressWrap } from "app/server/lib/expressWrap";
|
import { expressWrap } from "app/server/lib/expressWrap";
|
||||||
import { GristServer } from "app/server/lib/GristServer";
|
import { GristServer } from "app/server/lib/GristServer";
|
||||||
import { getAssignmentId } from "app/server/lib/idUtils";
|
import { getAssignmentId } from "app/server/lib/idUtils";
|
||||||
|
import { addAbortHandler } from "app/server/lib/requestUtils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forwards all /api/docs/:docId/tables requests to the doc worker handling the :docId document. Makes
|
* Forwards all /api/docs/:docId/tables requests to the doc worker handling the :docId document. Makes
|
||||||
@ -101,7 +102,7 @@ export class DocApiForwarder {
|
|||||||
|
|
||||||
// If the original request is aborted, abort the forwarded request too. (Currently this only
|
// If the original request is aborted, abort the forwarded request too. (Currently this only
|
||||||
// affects some export/download requests which can abort long-running work.)
|
// affects some export/download requests which can abort long-running work.)
|
||||||
req.on('close', () => controller.abort());
|
addAbortHandler(req, res, () => controller.abort());
|
||||||
|
|
||||||
const options: RequestInit = {
|
const options: RequestInit = {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import {ActiveDoc} from 'app/server/lib/ActiveDoc';
|
import {ActiveDoc} from 'app/server/lib/ActiveDoc';
|
||||||
import {ActiveDocSource, ActiveDocSourceDirect, DownloadOptions, ExportParameters} from 'app/server/lib/Export';
|
import {ActiveDocSource, ActiveDocSourceDirect, DownloadOptions, ExportParameters} from 'app/server/lib/Export';
|
||||||
import log from 'app/server/lib/log';
|
import log from 'app/server/lib/log';
|
||||||
|
import {addAbortHandler} from 'app/server/lib/requestUtils';
|
||||||
import * as express from 'express';
|
import * as express from 'express';
|
||||||
import contentDisposition from 'content-disposition';
|
import contentDisposition from 'content-disposition';
|
||||||
import {Rpc} from 'grain-rpc';
|
import {Rpc} from 'grain-rpc';
|
||||||
@ -78,7 +79,7 @@ export async function streamXLSX(activeDoc: ActiveDoc, req: express.Request,
|
|||||||
req.off('close', cancelWorker);
|
req.off('close', cancelWorker);
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on('close', cancelWorker);
|
addAbortHandler(req, outputStream, cancelWorker);
|
||||||
|
|
||||||
const run = (method: string, ...args: any[]) => exportPool.run({port: port2, testDates, args}, {
|
const run = (method: string, ...args: any[]) => exportPool.run({port: port2, testDates, args}, {
|
||||||
name: method,
|
name: method,
|
||||||
|
@ -9,6 +9,7 @@ import log from 'app/server/lib/log';
|
|||||||
import {Permit} from 'app/server/lib/Permit';
|
import {Permit} from 'app/server/lib/Permit';
|
||||||
import {Request, Response} from 'express';
|
import {Request, Response} from 'express';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import {Writable} from 'stream';
|
||||||
|
|
||||||
// log api details outside of dev environment (when GRIST_HOSTED_VERSION is set)
|
// log api details outside of dev environment (when GRIST_HOSTED_VERSION is set)
|
||||||
const shouldLogApiDetails = Boolean(process.env.GRIST_HOSTED_VERSION);
|
const shouldLogApiDetails = Boolean(process.env.GRIST_HOSTED_VERSION);
|
||||||
@ -335,3 +336,19 @@ export function clearSessionCacheIfNeeded(req: Request, options?: {
|
|||||||
}) {
|
}) {
|
||||||
(req as RequestWithGrist).gristServer?.getSessions().clearCacheIfNeeded(options);
|
(req as RequestWithGrist).gristServer?.getSessions().clearCacheIfNeeded(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addAbortHandler(req: Request, res: Writable, op: () => void) {
|
||||||
|
// It became hard to detect aborted connections in node 16.
|
||||||
|
// In node 14, req.on('close', ...) did the job.
|
||||||
|
// The following is a work-around, until a better way is discovered
|
||||||
|
// or added. Aborting a req will typically lead to 'close' being called
|
||||||
|
// on the response, without writableFinished being set.
|
||||||
|
// https://github.com/nodejs/node/issues/38924
|
||||||
|
// https://github.com/nodejs/node/issues/40775
|
||||||
|
res.on('close', () => {
|
||||||
|
const aborted = !res.writableFinished;
|
||||||
|
if (aborted) {
|
||||||
|
op();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user