diff --git a/deno.json b/deno.json index 240b6c3a..9c0cec5a 100644 --- a/deno.json +++ b/deno.json @@ -50,7 +50,7 @@ "iso-639-1": "npm:iso-639-1@2.1.15", "isomorphic-dompurify": "npm:isomorphic-dompurify@^2.11.0", "kysely": "npm:kysely@^0.27.3", - "kysely_deno_postgres": "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/f2948b86190a10faa293588775e162b3a8b52e70/mod.ts", + "kysely_deno_postgres": "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/b4725e74ad6ca359ba0e370b55dbb8bb845a8a83/mod.ts", "light-bolt11-decoder": "npm:light-bolt11-decoder", "linkify-plugin-hashtag": "npm:linkify-plugin-hashtag@^4.1.1", "linkify-string": "npm:linkify-string@^4.1.1", @@ -59,6 +59,7 @@ "nostr-relaypool": "npm:nostr-relaypool2@0.6.34", "nostr-tools": "npm:nostr-tools@2.5.1", "nostr-wasm": "npm:nostr-wasm@^0.1.0", + "postgres": "https://deno.land/x/postgres@v0.19.0/mod.ts", "prom-client": "npm:prom-client@^15.1.2", "question-deno": "https://raw.githubusercontent.com/ocpu/question-deno/10022b8e52555335aa510adb08b0a300df3cf904/mod.ts", "tldts": "npm:tldts@^6.0.14", diff --git a/deno.lock b/deno.lock index e69798dc..855f7353 100644 --- a/deno.lock +++ b/deno.lock @@ -1391,6 +1391,10 @@ "https://esm.sh/v135/kysely@0.17.1/denonext/dist/esm/index-nodeless.js": "6f73bbf2d73bc7e96cdabf941c4ae8c12f58fd7b441031edec44c029aed9532b", "https://gitlab.com/soapbox-pub/deno-safe-fetch/-/raw/v1.0.0/load.ts": "3f74ab08cf97d4a3e6994cb79422e9b0069495e017416858121d5ff8ae04ac2a", "https://gitlab.com/soapbox-pub/deno-safe-fetch/-/raw/v1.0.0/mod.ts": "5f505cd265aefbcb687cde6f98c79344d3292ee1dd978e85e5ffa84a617c6682", + "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/b4725e74ad6ca359ba0e370b55dbb8bb845a8a83/deps.ts": "b3dbecae69c30a5f161323b8c8ebd91d9af1eceb98fafab3091c7281a4b64fed", + "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/b4725e74ad6ca359ba0e370b55dbb8bb845a8a83/mod.ts": "662438fd3909984bb8cbaf3fd44d2121e949d11301baf21d6c3f057ccf9887de", + "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/b4725e74ad6ca359ba0e370b55dbb8bb845a8a83/src/PostgreSQLDriver.ts": "ea5a523bceeed420858b744beeb95d48976cb2b0d3f519a68b65a8229036cf6a", + "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/b4725e74ad6ca359ba0e370b55dbb8bb845a8a83/src/PostgreSQLDriverDatabaseConnection.ts": "11e2fc10a3abb3d0729613c4b7cdb9cb73b597fd77353311bb6707c73a635fc5", "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/f2948b86190a10faa293588775e162b3a8b52e70/deps.ts": "b3dbecae69c30a5f161323b8c8ebd91d9af1eceb98fafab3091c7281a4b64fed", "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/f2948b86190a10faa293588775e162b3a8b52e70/mod.ts": "662438fd3909984bb8cbaf3fd44d2121e949d11301baf21d6c3f057ccf9887de", "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/f2948b86190a10faa293588775e162b3a8b52e70/src/PostgreSQLDriver.ts": "ac1a39e86fd676973bce215e19db1f26b82408b8f2bb09a3601802974ea7cec6", diff --git a/src/controllers/metrics.ts b/src/controllers/metrics.ts index 419931da..e85294c0 100644 --- a/src/controllers/metrics.ts +++ b/src/controllers/metrics.ts @@ -1,9 +1,15 @@ import { register } from 'prom-client'; import { AppController } from '@/app.ts'; +import { DittoDB } from '@/db/DittoDB.ts'; +import { dbAvailableConnectionsGauge, dbPoolSizeGauge } from '@/metrics.ts'; /** Prometheus/OpenMetrics controller. */ export const metricsController: AppController = async (c) => { + // Update some metrics at request time. + dbPoolSizeGauge.set(DittoDB.poolSize); + dbAvailableConnectionsGauge.set(DittoDB.availableConnections); + const metrics = await register.metrics(); const headers: HeadersInit = { diff --git a/src/db/DittoDB.ts b/src/db/DittoDB.ts index d06b3318..73cd1406 100644 --- a/src/db/DittoDB.ts +++ b/src/db/DittoDB.ts @@ -37,6 +37,20 @@ export class DittoDB { return kysely; } + static get poolSize(): number { + if (Conf.db.dialect === 'postgres') { + return DittoPostgres.getPool().size; + } + return 1; + } + + static get availableConnections(): number { + if (Conf.db.dialect === 'postgres') { + return DittoPostgres.getPool().available; + } + return 1; + } + /** Migrate the database to the latest version. */ static async migrate(kysely: Kysely) { const migrator = new Migrator({ diff --git a/src/db/adapters/DittoPostgres.ts b/src/db/adapters/DittoPostgres.ts index 122892ee..c06a262f 100644 --- a/src/db/adapters/DittoPostgres.ts +++ b/src/db/adapters/DittoPostgres.ts @@ -1,5 +1,6 @@ import { Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler } from 'kysely'; import { PostgreSQLDriver } from 'kysely_deno_postgres'; +import { Pool } from 'postgres'; import { Conf } from '@/config.ts'; import { DittoTables } from '@/db/DittoTables.ts'; @@ -7,6 +8,14 @@ import { KyselyLogger } from '@/db/KyselyLogger.ts'; export class DittoPostgres { static db: Kysely | undefined; + static pool: Pool | undefined; + + static getPool(): Pool { + if (!this.pool) { + this.pool = new Pool(Conf.databaseUrl, Conf.pg.poolSize); + } + return this.pool; + } // deno-lint-ignore require-await static async getInstance(): Promise> { @@ -17,10 +26,7 @@ export class DittoPostgres { return new PostgresAdapter(); }, createDriver() { - return new PostgreSQLDriver( - { connectionString: Conf.databaseUrl }, - Conf.pg.poolSize, - ); + return new PostgreSQLDriver(DittoPostgres.getPool()); }, createIntrospector(db: Kysely) { return new PostgresIntrospector(db); diff --git a/src/metrics.ts b/src/metrics.ts index 26dce124..68ddfcef 100644 --- a/src/metrics.ts +++ b/src/metrics.ts @@ -57,3 +57,13 @@ export const dbEventCounter = new Counter({ help: 'Total number of database inserts', labelNames: ['kind'], }); + +export const dbPoolSizeGauge = new Gauge({ + name: 'db_pool_size', + help: 'Number of connections in the database pool', +}); + +export const dbAvailableConnectionsGauge = new Gauge({ + name: 'db_available_connections', + help: 'Number of available connections in the database pool', +});