mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
fix: Apply statement_timeout on request-handling processes (#12422)
* fix: Apply Postgres statement_timeout on request-handling processes Sets `statement_timeout` to REQUEST_TIMEOUT on the Sequelize connection pool when the process handles HTTP requests (web/api/collaboration/ websockets/admin) and does not also run worker/cron. Prevents a single runaway query from saturating the shared Postgres instance and cascading into timeouts across all endpoints. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop dead `api` service check Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Only apply statement_timeout in forked cluster workers Skips the timeout in the master process so startup migrations driven from `checkPendingMigrations` are not cancelled mid-execution. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import cluster from "node:cluster";
|
||||
import path from "node:path";
|
||||
import type { InferAttributes, InferCreationAttributes } from "sequelize";
|
||||
import sequelizeStrictAttributes from "sequelize-strict-attributes";
|
||||
@@ -45,6 +46,22 @@ const poolMin = env.DATABASE_CONNECTION_POOL_MIN ?? 0;
|
||||
const databaseConfig = env.DATABASE_CONNECTION_POOL_URL || getDatabaseConfig();
|
||||
const schema = env.DATABASE_SCHEMA;
|
||||
|
||||
// Request-handling processes get a Postgres `statement_timeout` matching the
|
||||
// HTTP request timeout, so a single slow query cannot hold a connection past
|
||||
// the point at which its response could be delivered. Worker/cron processes
|
||||
// are exempted because background jobs may legitimately run long queries.
|
||||
// Only applied in forked cluster workers so that startup work driven from
|
||||
// the master process (notably migrations) is not subject to the timeout.
|
||||
const isApiProcess =
|
||||
(env.SERVICES.includes("web") ||
|
||||
env.SERVICES.includes("collaboration") ||
|
||||
env.SERVICES.includes("websockets") ||
|
||||
env.SERVICES.includes("admin")) &&
|
||||
!env.SERVICES.includes("worker") &&
|
||||
!env.SERVICES.includes("cron");
|
||||
const statementTimeout =
|
||||
isApiProcess && cluster.isWorker ? env.REQUEST_TIMEOUT : undefined;
|
||||
|
||||
export function createDatabaseInstance(
|
||||
databaseConfig: string | object,
|
||||
input: {
|
||||
@@ -68,6 +85,7 @@ export function createDatabaseInstance(
|
||||
logQueryParameters: env.isDevelopment,
|
||||
dialectOptions: {
|
||||
application_name: getConnectionName(),
|
||||
statement_timeout: statementTimeout,
|
||||
ssl:
|
||||
env.isProduction && !isSSLDisabled
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user