node-mssql
node-mssql copied to clipboard
Feature Request: Request.prototype.setTimeout()
I need a way to set different request timeouts without using multiple connection pools. Tedious has a setTimeout
function on Request
that implements this behavior, but there's not a defined way to get at the driver Request
object from a mssql.Request
object.
Expected behaviour:
That I could have a pool and request like this, and that the specified timeout would be set on the underlying tedious Request when it is created.
const pool = new ConnectionPool({options: { requestTimeout: 15_000 });
await pool.request().setTimeout(90_000).query("waitfor delay '00:01'"); // synthetic slow query
Actual behaviour:
The only supported workaround is to have different connection pools with different timeouts. This works in some limited cases, but is not very flexible and we can't have two requests in the same transaction with different timeouts.
Software versions
- NodeJS: 18
- node-mssql: 9.1.1
- SQL Server: 2019
Monkey patch
A bad implementation of this feature would be something like this patch.
declare module 'mssql' {
interface Request {
setTimeout(timeout: number | undefined): this;
}
}
const kTimeout = Symbol('request timeout');
Request.prototype.setTimeout = function (timeout: number | undefined) {
this[kTimeout] = timeout;
// for chaining like other mssql Request functions
return this;
};
// _setCurrentRequest is the only 'hook' that we can patch to get at the underlying
// tedious request before it is passed to the acquired connection
const orig = Request.prototype._setCurrentRequest as (req: any) => any;
Request.prototype._setCurrentRequest = function _setCurrentRequest(req: tedious.Request) {
if (this[kTimeout] !== undefined) {
req.setTimeout(this[kTimeout] as number);
}
return orig.call(this, req);
};