@@ -475,6 +475,26 @@ export function createChannelIngressQueue<
475475 return runOpenClawStateWriteTransaction (
476476 ( tx ) => {
477477 const kysely = getChannelIngressKysely ( tx . db ) ;
478+ let effectiveBlocked = blocked ;
479+ if ( candidateIds && candidateIds . length > 0 ) {
480+ // Candidate snapshots can race a sibling drainer. If an earlier
481+ // candidate is now claimed, its lane must block later same-lane rows.
482+ const claimedCandidateRows = executeSqliteQuerySync (
483+ tx . db ,
484+ kysely
485+ . selectFrom ( "channel_ingress_events" )
486+ . selectAll ( )
487+ . where ( "queue_name" , "=" , queueName )
488+ . where ( "status" , "=" , "claimed" )
489+ . where ( "event_id" , "in" , candidateIds ) ,
490+ ) . rows ;
491+ const claimedCandidateLaneKeys = claimedCandidateRows
492+ . map ( ( row ) => row . lane_key ?? claimOptions ?. deriveLaneKey ?.( baseRecord ( row ) ) )
493+ . filter ( ( laneKey ) : laneKey is string => Boolean ( laneKey ) ) ;
494+ if ( claimedCandidateLaneKeys . length > 0 ) {
495+ effectiveBlocked = new Set ( [ ...blocked , ...claimedCandidateLaneKeys ] ) ;
496+ }
497+ }
478498 const baseSelect = kysely
479499 . selectFrom ( "channel_ingress_events" )
480500 . selectAll ( )
@@ -484,9 +504,9 @@ export function createChannelIngressQueue<
484504 if ( candidateIds ) {
485505 select = select . where ( "event_id" , "in" , candidateIds ) ;
486506 }
487- if ( blocked . size > 0 && ! claimOptions ?. deriveLaneKey ) {
507+ if ( effectiveBlocked . size > 0 && ! claimOptions ?. deriveLaneKey ) {
488508 select = select . where ( ( eb ) =>
489- eb . or ( [ eb ( "lane_key" , "is" , null ) , eb ( "lane_key" , "not in" , [ ...blocked ] ) ] ) ,
509+ eb . or ( [ eb ( "lane_key" , "is" , null ) , eb ( "lane_key" , "not in" , [ ...effectiveBlocked ] ) ] ) ,
490510 ) ;
491511 }
492512 let orderedSelect =
@@ -500,7 +520,7 @@ export function createChannelIngressQueue<
500520 const rows = executeSqliteQuerySync ( tx . db , orderedSelect ) . rows ;
501521 const selected = rows . find ( ( row ) => {
502522 const laneKey = row . lane_key ?? claimOptions ?. deriveLaneKey ?.( baseRecord ( row ) ) ;
503- return ! laneKey || ! blocked . has ( laneKey ) ;
523+ return ! laneKey || ! effectiveBlocked . has ( laneKey ) ;
504524 } ) ;
505525 if ( ! selected ) {
506526 return null ;
0 commit comments