@@ -99,13 +99,13 @@ type ServerStatusUpdate =
9999 outcome : 'connected'
100100 toolCount : number
101101 configUpdatedAt : string
102- discoveryStartedAt : Date
102+ publicationOrder : Date
103103 }
104104 | {
105105 outcome : 'failed'
106106 error : string
107107 configUpdatedAt : string
108- discoveryStartedAt : Date
108+ publicationOrder : Date
109109 }
110110
111111function isOauthAuthorizationError ( error : unknown , authType : McpServerConfig [ 'authType' ] ) : boolean {
@@ -429,7 +429,7 @@ class McpService {
429429 lt ( mcpServers . updatedAt , configUpdatedAt . endExclusive ) ,
430430 or (
431431 isNull ( mcpServers . lastToolsRefresh ) ,
432- lte ( mcpServers . lastToolsRefresh , update . discoveryStartedAt )
432+ lte ( mcpServers . lastToolsRefresh , update . publicationOrder )
433433 )
434434 )
435435
@@ -441,10 +441,10 @@ class McpService {
441441 lastConnected : now ,
442442 lastError : null ,
443443 toolCount : update . toolCount ,
444- // This column is also the publication ordering token. Persist the
445- // discovery start (rather than finish) so a newer-started run can
446- // still publish after an older run completes while it is in flight .
447- lastToolsRefresh : update . discoveryStartedAt ,
444+ // The cache mutation id is a monotonic millisecond timestamp. Use
445+ // that same token here so cache and database publication cannot
446+ // choose different winners during begin-mutation retries .
447+ lastToolsRefresh : update . publicationOrder ,
448448 statusConfig : {
449449 consecutiveFailures : 0 ,
450450 lastSuccessfulDiscovery : now . toISOString ( ) ,
@@ -485,7 +485,7 @@ class McpService {
485485 connectionStatus : isErrorState ? 'error' : 'disconnected' ,
486486 lastError : update . error || 'Unknown error' ,
487487 toolCount : 0 ,
488- lastToolsRefresh : update . discoveryStartedAt ,
488+ lastToolsRefresh : update . publicationOrder ,
489489 statusConfig : {
490490 consecutiveFailures : newFailures ,
491491 lastSuccessfulDiscovery : currentConfig . lastSuccessfulDiscovery ,
@@ -538,7 +538,7 @@ class McpService {
538538 serverId : string ,
539539 workspaceId : string ,
540540 configUpdatedAt : string ,
541- discoveryStartedAt : Date
541+ publicationOrder : Date
542542 ) : Promise < boolean > {
543543 try {
544544 const configUpdatedAtBounds = getTimestampMillisecondBounds ( configUpdatedAt )
@@ -548,7 +548,7 @@ class McpService {
548548 connectionStatus : 'disconnected' ,
549549 lastError : null ,
550550 toolCount : 0 ,
551- lastToolsRefresh : discoveryStartedAt ,
551+ lastToolsRefresh : publicationOrder ,
552552 } )
553553 . where (
554554 and (
@@ -559,7 +559,7 @@ class McpService {
559559 lt ( mcpServers . updatedAt , configUpdatedAtBounds . endExclusive ) ,
560560 or (
561561 isNull ( mcpServers . lastToolsRefresh ) ,
562- lte ( mcpServers . lastToolsRefresh , discoveryStartedAt )
562+ lte ( mcpServers . lastToolsRefresh , publicationOrder )
563563 )
564564 )
565565 )
@@ -636,8 +636,7 @@ class McpService {
636636 workspaceId : string ,
637637 config : McpServerConfig ,
638638 mutation : CacheMutation | null ,
639- tools : McpTool [ ] ,
640- discoveryStartedAt : Date
639+ tools : McpTool [ ]
641640 ) : Promise < boolean > {
642641 const cacheApplied = await this . applyServerCacheMutation (
643642 workspaceId ,
@@ -650,13 +649,13 @@ class McpService {
650649 } ,
651650 [ failureCacheKey ( workspaceId , config . id ) ]
652651 )
653- if ( ! cacheApplied ) return false
652+ if ( ! cacheApplied || ! mutation ) return false
654653
655654 const statusApplied = await this . updateServerStatus ( config . id , workspaceId , {
656655 outcome : 'connected' ,
657656 toolCount : tools . length ,
658657 configUpdatedAt : config . updatedAt ! ,
659- discoveryStartedAt ,
658+ publicationOrder : new Date ( mutation . id ) ,
660659 } )
661660 if ( statusApplied ) return true
662661
@@ -675,8 +674,7 @@ class McpService {
675674 config : McpServerConfig ,
676675 mutation : CacheMutation | null ,
677676 error : unknown ,
678- message : string ,
679- discoveryStartedAt : Date
677+ message : string
680678 ) : Promise < boolean > {
681679 const cacheApplied = await this . applyServerCacheMutation (
682680 workspaceId ,
@@ -691,13 +689,13 @@ class McpService {
691689 } ,
692690 [ serverCacheKey ( workspaceId , config . id ) ]
693691 )
694- if ( ! cacheApplied ) return false
692+ if ( ! cacheApplied || ! mutation ) return false
695693
696694 const statusApplied = await this . updateServerStatus ( config . id , workspaceId , {
697695 outcome : 'failed' ,
698696 error : message ,
699697 configUpdatedAt : config . updatedAt ! ,
700- discoveryStartedAt ,
698+ publicationOrder : new Date ( mutation . id ) ,
701699 } )
702700 if ( statusApplied ) return true
703701
@@ -712,8 +710,7 @@ class McpService {
712710 private async publishOauthPending (
713711 workspaceId : string ,
714712 config : McpServerConfig ,
715- mutation : CacheMutation | null ,
716- discoveryStartedAt : Date
713+ mutation : CacheMutation | null
717714 ) : Promise < boolean > {
718715 const cacheApplied = await this . applyServerCacheMutation (
719716 workspaceId ,
@@ -722,13 +719,13 @@ class McpService {
722719 null ,
723720 [ serverCacheKey ( workspaceId , config . id ) , failureCacheKey ( workspaceId , config . id ) ]
724721 )
725- if ( ! cacheApplied ) return false
722+ if ( ! cacheApplied || ! mutation ) return false
726723
727724 return this . markServerOauthPending (
728725 config . id ,
729726 workspaceId ,
730727 config . updatedAt ! ,
731- discoveryStartedAt
728+ new Date ( mutation . id )
732729 )
733730 }
734731
@@ -738,8 +735,6 @@ class McpService {
738735 forceRefresh = false
739736 ) : Promise < McpTool [ ] > {
740737 const requestId = generateRequestId ( )
741- const discoveryStartedAt = new Date ( )
742-
743738 try {
744739 logger . info ( `[${ requestId } ] Discovering MCP tools for workspace ${ workspaceId } ` )
745740
@@ -822,8 +817,7 @@ class McpService {
822817 workspaceId ,
823818 outcome . resolvedConfig ,
824819 outcome . mutation ,
825- outcome . tools ,
826- discoveryStartedAt
820+ outcome . tools
827821 )
828822 if ( ! published ) {
829823 logger . info (
@@ -847,12 +841,7 @@ class McpService {
847841 logger . info (
848842 `[${ requestId } ] Skipping server ${ server . name } : OAuth authorization pending`
849843 )
850- await this . publishOauthPending (
851- workspaceId ,
852- outcome . config ,
853- outcome . mutation ,
854- discoveryStartedAt
855- )
844+ await this . publishOauthPending ( workspaceId , outcome . config , outcome . mutation )
856845 return { tools : [ ] , cached : 0 , fetched : 0 , failed : 0 , liveConnection : null }
857846 }
858847 if ( outcome . kind === 'unhealthy' ) {
@@ -867,8 +856,7 @@ class McpService {
867856 outcome . config ,
868857 outcome . mutation ,
869858 outcome . originalError ,
870- outcome . message ,
871- discoveryStartedAt
859+ outcome . message
872860 )
873861 return { tools : [ ] , cached : 0 , fetched : 0 , failed : 1 , liveConnection : null }
874862 } )
@@ -941,7 +929,6 @@ class McpService {
941929 forceRefresh : boolean
942930 ) : Promise < McpTool [ ] > {
943931 const requestId = generateRequestId ( )
944- const discoveryStartedAt = new Date ( )
945932 const maxRetries = 2
946933
947934 if ( ! forceRefresh ) {
@@ -991,8 +978,7 @@ class McpService {
991978 workspaceId ,
992979 resolvedConfig ,
993980 mutation ,
994- tools ,
995- discoveryStartedAt
981+ tools
996982 )
997983 if ( ! published ) {
998984 logger . info (
@@ -1015,15 +1001,14 @@ class McpService {
10151001 }
10161002 if ( config ) {
10171003 if ( isOauthAuthorizationError ( error , config . authType ) ) {
1018- await this . publishOauthPending ( workspaceId , config , mutation , discoveryStartedAt )
1004+ await this . publishOauthPending ( workspaceId , config , mutation )
10191005 } else {
10201006 await this . publishFailedDiscovery (
10211007 workspaceId ,
10221008 config ,
10231009 mutation ,
10241010 error ,
1025- getDiscoveryFailureMessage ( error , config . authType , 'Connection failed' ) ,
1026- discoveryStartedAt
1011+ getDiscoveryFailureMessage ( error , config . authType , 'Connection failed' )
10271012 )
10281013 }
10291014 }
0 commit comments