mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +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 { GristServer } from "app/server/lib/GristServer"; | ||||
| 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 | ||||
| @ -101,7 +102,7 @@ export class DocApiForwarder { | ||||
| 
 | ||||
|     // 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.)
 | ||||
|     req.on('close', () => controller.abort()); | ||||
|     addAbortHandler(req, res, () => controller.abort()); | ||||
| 
 | ||||
|     const options: RequestInit = { | ||||
|       method: req.method, | ||||
|  | ||||
| @ -14,6 +14,7 @@ | ||||
| import {ActiveDoc} from 'app/server/lib/ActiveDoc'; | ||||
| import {ActiveDocSource, ActiveDocSourceDirect, DownloadOptions, ExportParameters} from 'app/server/lib/Export'; | ||||
| import log from 'app/server/lib/log'; | ||||
| import {addAbortHandler} from 'app/server/lib/requestUtils'; | ||||
| import * as express from 'express'; | ||||
| import contentDisposition from 'content-disposition'; | ||||
| import {Rpc} from 'grain-rpc'; | ||||
| @ -78,7 +79,7 @@ export async function streamXLSX(activeDoc: ActiveDoc, req: express.Request, | ||||
|       req.off('close', cancelWorker); | ||||
|     }); | ||||
| 
 | ||||
|     req.on('close', cancelWorker); | ||||
|     addAbortHandler(req, outputStream, cancelWorker); | ||||
| 
 | ||||
|     const run = (method: string, ...args: any[]) => exportPool.run({port: port2, testDates, args}, { | ||||
|       name: method, | ||||
|  | ||||
| @ -9,6 +9,7 @@ import log from 'app/server/lib/log'; | ||||
| import {Permit} from 'app/server/lib/Permit'; | ||||
| import {Request, Response} from 'express'; | ||||
| import _ from 'lodash'; | ||||
| import {Writable} from 'stream'; | ||||
| 
 | ||||
| // log api details outside of dev environment (when GRIST_HOSTED_VERSION is set)
 | ||||
| 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); | ||||
| } | ||||
| 
 | ||||
| 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