역할별 PostgreSQL pool 상한과 동일 process 공유 pool을 적용하고 health 지표를 노출한다.\n\n게임 기능 advisory lock을 schema namespace로 통일하고 실제 PostgreSQL 통합 하네스를 보강한다.
33 lines
1.2 KiB
TypeScript
33 lines
1.2 KiB
TypeScript
import { GamePrisma, type GamePrismaClient } from './gamePrisma.js';
|
|
|
|
type GameSchemaAdvisoryLockDatabase = Pick<GamePrismaClient, '$executeRaw' | '$queryRaw'>;
|
|
|
|
interface TryLockRow {
|
|
acquired: boolean;
|
|
}
|
|
|
|
const lockKeySql = (logicalKey: string): GamePrisma.Sql =>
|
|
GamePrisma.sql`hashtextextended(current_schema() || chr(31) || ${logicalKey}, 0)`;
|
|
|
|
/**
|
|
* Acquires a transaction-scoped lock whose namespace is the active game schema.
|
|
* Callers must already be inside the transaction that owns the protected write.
|
|
*/
|
|
export const acquireGameSchemaAdvisoryXactLock = async (
|
|
database: GameSchemaAdvisoryLockDatabase,
|
|
logicalKey: string
|
|
): Promise<void> => {
|
|
await database.$executeRaw(GamePrisma.sql`SELECT pg_advisory_xact_lock(${lockKeySql(logicalKey)})`);
|
|
};
|
|
|
|
/** Test and diagnostics boundary matching acquireGameSchemaAdvisoryXactLock. */
|
|
export const tryGameSchemaAdvisoryXactLock = async (
|
|
database: GameSchemaAdvisoryLockDatabase,
|
|
logicalKey: string
|
|
): Promise<boolean> => {
|
|
const rows = await database.$queryRaw<TryLockRow[]>(
|
|
GamePrisma.sql`SELECT pg_try_advisory_xact_lock(${lockKeySql(logicalKey)}) AS acquired`
|
|
);
|
|
return rows[0]?.acquired === true;
|
|
};
|