@bytebase/dbhub
Version:
Token-efficient database MCP server for PostgreSQL, MySQL, MariaDB, SQL Server, Oracle, SQLite
64 lines (62 loc) • 1.95 kB
JavaScript
// src/utils/query-timeout.ts
var CLIENT_QUERY_TIMEOUT_GRACE_MS = 5e3;
var CANCEL_QUERY_TIMEOUT_MS = 5e3;
var MAX_TIMER_MS = 2147483647;
var MAX_QUERY_TIMEOUT_SECONDS = Math.floor(
(MAX_TIMER_MS - CLIENT_QUERY_TIMEOUT_GRACE_MS) / 1e3
);
function clientQueryTimeoutMs(queryTimeoutMs) {
const deadlineMs = queryTimeoutMs + CLIENT_QUERY_TIMEOUT_GRACE_MS;
if (!Number.isFinite(deadlineMs) || deadlineMs > MAX_TIMER_MS) {
throw new RangeError(
`query_timeout of ${queryTimeoutMs}ms exceeds the client-side deadline range (at most ${MAX_QUERY_TIMEOUT_SECONDS} seconds)`
);
}
return deadlineMs;
}
var CLIENT_QUERY_TIMEOUT_CODE = "DBHUB_CLIENT_QUERY_TIMEOUT";
var PG_CLIENT_TIMEOUT_MESSAGE = "Query read timeout";
var MYSQL2_CLIENT_TIMEOUT_CODE = "PROTOCOL_SEQUENCE_TIMEOUT";
var ClientQueryTimeoutError = class extends Error {
constructor(timeoutMs) {
super(`Query timed out on the client after ${timeoutMs}ms`);
this.code = CLIENT_QUERY_TIMEOUT_CODE;
this.name = "ClientQueryTimeoutError";
}
};
function isClientSideTimeout(error) {
if (typeof error !== "object" || error === null) {
return false;
}
const { code, message } = error;
return code === MYSQL2_CLIENT_TIMEOUT_CODE || code === CLIENT_QUERY_TIMEOUT_CODE || code === void 0 && message === PG_CLIENT_TIMEOUT_MESSAGE;
}
function withClientQueryDeadline(query, timeoutMs) {
if (timeoutMs === void 0) {
return query;
}
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
query.catch(() => {
});
reject(new ClientQueryTimeoutError(timeoutMs));
}, timeoutMs);
query.then(
(value) => {
clearTimeout(timer);
resolve(value);
},
(error) => {
clearTimeout(timer);
reject(error);
}
);
});
}
export {
CANCEL_QUERY_TIMEOUT_MS,
MAX_QUERY_TIMEOUT_SECONDS,
clientQueryTimeoutMs,
isClientSideTimeout,
withClientQueryDeadline
};