@@ -15,8 +15,11 @@ const TICKET_HEARTBEAT_TTL_SECONDS = 30
1515export const HEARTBEAT_REFRESH_INTERVAL_MS = 10_000
1616
1717/**
18- * TTL on the queue list itself. Set on every enqueue. Prevents abandoned queues
19- * (whole workspace went silent) from sticking around forever in Redis.
18+ * TTL on the queue list itself. Set on every enqueue and re-extended by the head's
19+ * heartbeat while it actively waits, so a long-waiting head (whose budget can exceed
20+ * this TTL for enterprise async runs) never lets the list expire out from under the
21+ * waiters behind it. Prevents abandoned queues (whole workspace went silent) from
22+ * sticking around forever in Redis.
2023 */
2124const QUEUE_LIST_TTL_SECONDS = 600
2225
@@ -148,7 +151,11 @@ export class HostedKeyQueue {
148151
149152 /**
150153 * Refresh the ticket's heartbeat. Called periodically by the head while it's
151- * waiting on the bucket so it doesn't get reaped as dead.
154+ * waiting on the bucket so it doesn't get reaped as dead. Also re-extends the
155+ * queue list TTL: a head whose wait outlives {@link QUEUE_LIST_TTL_SECONDS}
156+ * (possible for long enterprise async budgets) would otherwise let the list
157+ * expire with no new enqueue to refresh it, dropping every waiter to "missing"
158+ * and collapsing FIFO ordering into concurrent bucket racing.
152159 */
153160 async refreshHeartbeat (
154161 provider : string ,
@@ -158,9 +165,13 @@ export class HostedKeyQueue {
158165 const redis = getRedisClient ( )
159166 if ( ! redis ) return
160167
168+ const listKey = queueListKey ( provider , billingActorId )
161169 const hbKey = heartbeatKey ( provider , billingActorId , ticketId )
162170 try {
163- await redis . set ( hbKey , '1' , 'EX' , TICKET_HEARTBEAT_TTL_SECONDS )
171+ const pipeline = redis . multi ( )
172+ pipeline . set ( hbKey , '1' , 'EX' , TICKET_HEARTBEAT_TTL_SECONDS )
173+ pipeline . expire ( listKey , QUEUE_LIST_TTL_SECONDS )
174+ await pipeline . exec ( )
164175 } catch ( error ) {
165176 logger . warn ( `Queue heartbeat refresh failed for ${ hbKey } ` , {
166177 error : toError ( error ) . message ,
0 commit comments