@@ -69,10 +69,16 @@ export async function startWebapp(
6969 ELECTRIC_ORIGIN : "http://localhost:3060" ,
7070 REDIS_HOST : redis . host ,
7171 REDIS_PORT : String ( redis . port ) ,
72- // Disable background workers and logical replication: they are irrelevant for auth
73- // tests and in CI the replication slot creation holds a snapshot lock that blocks
74- // the test process's Prisma writes to the same DB.
75- WORKER_ENABLED : "false" ,
72+ // Disable all background workers. Each worker has its own env var and its own
73+ // check idiom ("0" vs "false" vs boolean), so we set all of them explicitly.
74+ WORKER_ENABLED : "false" , // disables workerQueue.initialize() (checked === "true")
75+ RUN_ENGINE_WORKER_ENABLED : "0" , // disables run engine workers (checked === "0", default "1")
76+ SCHEDULE_WORKER_ENABLED : "0" , // disables schedule engine worker (checked === "0")
77+ BATCH_QUEUE_WORKER_ENABLED : "false" , // disables batch queue consumers (BoolEnv)
78+ LEGACY_RUN_ENGINE_WORKER_ENABLED : "0" , // disables legacy run engine worker
79+ COMMON_WORKER_ENABLED : "0" , // disables common worker
80+ RUN_ENGINE_TTL_SYSTEM_DISABLED : "true" , // disables TTL expiry system (BoolEnv)
81+ RUN_ENGINE_TTL_CONSUMERS_DISABLED : "true" , // disables TTL consumers (BoolEnv)
7682 RUN_REPLICATION_ENABLED : "0" ,
7783 NODE_PATH : nodePath ,
7884 } ,
@@ -153,6 +159,7 @@ export async function startTestServer(): Promise<TestServer> {
153159 let prisma : PrismaClient | undefined ;
154160 let stopWebapp : ( ( ) => Promise < void > ) | undefined ;
155161 let webapp : WebappInstance ;
162+ let diagInterval : ReturnType < typeof setInterval > | undefined ;
156163
157164 try {
158165 const pg = await createPostgresContainer ( network ) ;
@@ -163,6 +170,27 @@ export async function startTestServer(): Promise<TestServer> {
163170
164171 prisma = new PrismaClient ( { datasources : { db : { url : pg . url } } } ) ;
165172 await prisma . $connect ( ) ; // pre-warm pool; surface connection failures before tests start
173+
174+ // Periodically dump pg_stat_activity when debugging to identify hangs.
175+ if ( process . env . WEBAPP_TEST_VERBOSE ) {
176+ diagInterval = setInterval ( async ( ) => {
177+ try {
178+ const rows = await prisma ! . $queryRawUnsafe < Record < string , unknown > [ ] > ( `
179+ SELECT pid, state, wait_event_type, wait_event,
180+ LEFT(query, 300) AS query,
181+ EXTRACT(EPOCH FROM (now() - state_change))::int AS state_age_secs,
182+ EXTRACT(EPOCH FROM (now() - query_start))::int AS query_age_secs
183+ FROM pg_stat_activity
184+ WHERE datname = current_database() AND pid != pg_backend_pid()
185+ ORDER BY query_start NULLS LAST
186+ ` ) ;
187+ process . stderr . write ( `[pg_stat_activity] ${ JSON . stringify ( rows ) } \n` ) ;
188+ } catch {
189+ // Diagnostic failures are non-fatal; ignore them.
190+ }
191+ } , 10_000 ) ;
192+ }
193+
166194 const started = await startWebapp ( pg . url , { host : rc . getHost ( ) , port : rc . getPort ( ) } ) ;
167195 webapp = started . instance ;
168196 stopWebapp = started . stop ;
@@ -176,6 +204,7 @@ export async function startTestServer(): Promise<TestServer> {
176204 }
177205
178206 const stop = async ( ) => {
207+ if ( diagInterval ) clearInterval ( diagInterval ) ;
179208 await stopWebapp ! ( ) . catch ( ( err ) => console . error ( "stopWebapp failed:" , err ) ) ;
180209 await prisma ! . $disconnect ( ) . catch ( ( err ) => console . error ( "prisma.$disconnect failed:" , err ) ) ;
181210 await pgContainer ! . stop ( ) . catch ( ( err ) => console . error ( "pgContainer.stop failed:" , err ) ) ;
0 commit comments