Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle db client errors on appview #1481

Merged
merged 1 commit into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/bsky/src/db/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Kysely, PostgresDialect } from 'kysely'
import { Pool as PgPool, types as pgTypes } from 'pg'
import DatabaseSchema, { DatabaseSchemaType } from './database-schema'
import { PgOptions } from './types'
import { dbLogger } from '../logger'

export class Database {
pool: PgPool
Expand Down Expand Up @@ -41,6 +42,7 @@ export class Database {
}

pool.on('connect', (client) => {
client.on('error', onClientError)
// Used for trigram indexes, e.g. on actor search
client.query('SET pg_trgm.word_similarity_threshold TO .4;')
if (schema) {
Expand Down Expand Up @@ -83,3 +85,5 @@ export class Database {
}

export default Database

const onClientError = (err: Error) => dbLogger.error({ err }, 'db client error')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we close the connection here? 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my initial reaction too— I had a client.release(err) in there to drop the connection from the pool and close it. But it turns out kysely also has its hands in there, and I was getting a double-release error from the pool which caused its own unhandled error 🙃 I think we should keep an eye on it, but hoping this is good enough for now with the work that the pool and kysely are also doing.

14 changes: 14 additions & 0 deletions packages/bsky/tests/db.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { once } from 'events'
import { sql } from 'kysely'
import { wait } from '@atproto/common'
import { TestNetwork } from '@atproto/dev-env'
import { Database } from '../src'
Expand All @@ -20,6 +21,19 @@ describe('db', () => {
await network.close()
})

it('handles client errors without crashing.', async () => {
const tryKillConnection = db.transaction(async (dbTxn) => {
const result = await sql`select pg_backend_pid() as pid;`.execute(
dbTxn.db,
)
const pid = result.rows[0]?.['pid'] as number
await sql`select pg_terminate_backend(${pid});`.execute(db.db)
await sql`select 1;`.execute(dbTxn.db)
})
// This should throw, but no unhandled error
await expect(tryKillConnection).rejects.toThrow()
})

describe('transaction()', () => {
it('commits changes', async () => {
const result = await db.transaction(async (dbTxn) => {
Expand Down