@@ -24,8 +24,11 @@ export class ConnectClusterTool extends AtlasToolBase {
2424 private async queryConnection (
2525 projectId : string ,
2626 clusterName : string
27- ) : Promise < "connected" | "disconnected" | "connecting" | "connected-to-other-cluster" > {
27+ ) : Promise < "connected" | "disconnected" | "connecting" | "connected-to-other-cluster" | "unknown" > {
2828 if ( ! this . session . connectedAtlasCluster ) {
29+ if ( this . session . serviceProvider ) {
30+ return "connected-to-other-cluster" ;
31+ }
2932 return "disconnected" ;
3033 }
3134
@@ -40,10 +43,21 @@ export class ConnectClusterTool extends AtlasToolBase {
4043 return "connecting" ;
4144 }
4245
43- await this . session . serviceProvider . runCommand ( "admin" , {
44- ping : 1 ,
45- } ) ;
46- return "connected" ;
46+ try {
47+ await this . session . serviceProvider . runCommand ( "admin" , {
48+ ping : 1 ,
49+ } ) ;
50+
51+ return "connected" ;
52+ } catch ( err : unknown ) {
53+ const error = err instanceof Error ? err : new Error ( String ( err ) ) ;
54+ logger . debug (
55+ LogId . atlasConnectFailure ,
56+ "atlas-connect-cluster" ,
57+ `error querying cluster: ${ error . message } `
58+ ) ;
59+ return "unknown" ;
60+ }
4761 }
4862
4963 private async prepareClusterConnection ( projectId : string , clusterName : string ) : Promise < string > {
@@ -111,8 +125,7 @@ export class ConnectClusterTool extends AtlasToolBase {
111125 private async connectToCluster (
112126 projectId : string ,
113127 clusterName : string ,
114- connectionString : string ,
115- tryCount : number
128+ connectionString : string
116129 ) : Promise < void > {
117130 let lastError : Error | undefined = undefined ;
118131
@@ -122,7 +135,8 @@ export class ConnectClusterTool extends AtlasToolBase {
122135 `attempting to connect to cluster: ${ this . session . connectedAtlasCluster ?. clusterName } `
123136 ) ;
124137
125- for ( let i = 0 ; i < tryCount ; i ++ ) {
138+ // try to connect for about 5 minutes
139+ for ( let i = 0 ; i < 600 ; i ++ ) {
126140 if (
127141 ! this . session . connectedAtlasCluster ||
128142 this . session . connectedAtlasCluster . projectId != projectId ||
@@ -185,89 +199,53 @@ export class ConnectClusterTool extends AtlasToolBase {
185199 }
186200
187201 protected async execute ( { projectId, clusterName } : ToolArgs < typeof this . argsShape > ) : Promise < CallToolResult > {
188- const connectingResult = {
189- content : [
190- {
191- type : "text" as const ,
192- text : `Attempting to connect to cluster "${ clusterName } "...` ,
193- } ,
194- {
195- type : "text" as const ,
196- text : `Warning: Provisioning a user and connecting to the cluster may take more time, please check again in a few seconds.` ,
197- } ,
198- ] ,
199- } ;
200-
201- try {
202+ for ( let i = 0 ; i < 60 ; i ++ ) {
202203 const state = await this . queryConnection ( projectId , clusterName ) ;
203204 switch ( state ) {
204205 case "connected" :
205206 return {
206207 content : [
207208 {
208209 type : "text" ,
209- text : "Cluster is already connected." ,
210+ text : `Connected to cluster " ${ clusterName } ".` ,
210211 } ,
211212 ] ,
212213 } ;
213214 case "connecting" :
214- return connectingResult ;
215+ break ;
215216 case "connected-to-other-cluster" :
216217 case "disconnected" :
218+ case "unknown" :
217219 default :
218- // fall through to create new connection
220+ await this . session . disconnect ( ) ;
221+ const connectionString = await this . prepareClusterConnection ( projectId , clusterName ) ;
222+
223+ // try to connect for about 5 minutes asynchronously
224+ void this . connectToCluster ( projectId , clusterName , connectionString ) . catch ( ( err : unknown ) => {
225+ const error = err instanceof Error ? err : new Error ( String ( err ) ) ;
226+ logger . error (
227+ LogId . atlasConnectFailure ,
228+ "atlas-connect-cluster" ,
229+ `error connecting to cluster: ${ error . message } `
230+ ) ;
231+ } ) ;
219232 break ;
220233 }
221- } catch ( err : unknown ) {
222- const error = err instanceof Error ? err : new Error ( String ( err ) ) ;
223- logger . debug (
224- LogId . atlasConnectFailure ,
225- "atlas-connect-cluster" ,
226- `error querying cluster: ${ error . message } `
227- ) ;
228- // fall through to create new connection
229- }
230-
231- await this . session . disconnect ( ) ;
232- const connectionString = await this . prepareClusterConnection ( projectId , clusterName ) ;
233-
234- try {
235- // First, try to connect to the cluster within the current tool call.
236- // We give it 60 attempts with 500 ms delay between each, so ~30 seconds
237- await this . connectToCluster ( projectId , clusterName , connectionString , 60 ) ;
238-
239- return {
240- content : [
241- {
242- type : "text" ,
243- text : `Connected to cluster "${ clusterName } ".` ,
244- } ,
245- ] ,
246- } ;
247- } catch ( err : unknown ) {
248- const error = err instanceof Error ? err : new Error ( String ( err ) ) ;
249- logger . debug (
250- LogId . atlasConnectFailure ,
251- "atlas-connect-cluster" ,
252- `error connecting to cluster: ${ error . message } `
253- ) ;
254-
255- // We couldn't connect in ~30 seconds, likely because user creation is taking longer.
256- // Retry the connection with longer timeout (~5 minutes), while also returning a response
257- // to the client. Many clients will have a 1 minute timeout for tool calls, so we want to
258- // return well before that.
259- //
260- // Once we add support for streamable http, we'd want to use progress notifications here.
261- void this . connectToCluster ( projectId , clusterName , connectionString , 600 ) . catch ( ( err ) => {
262- const error = err instanceof Error ? err : new Error ( String ( err ) ) ;
263- logger . debug (
264- LogId . atlasConnectFailure ,
265- "atlas-connect-cluster" ,
266- `error connecting to cluster: ${ error . message } `
267- ) ;
268- } ) ;
269234
270- return connectingResult ;
235+ await sleep ( 500 ) ;
271236 }
237+
238+ return {
239+ content : [
240+ {
241+ type : "text" as const ,
242+ text : `Attempting to connect to cluster "${ clusterName } "...` ,
243+ } ,
244+ {
245+ type : "text" as const ,
246+ text : `Warning: Provisioning a user and connecting to the cluster may take more time, please check again in a few seconds.` ,
247+ } ,
248+ ] ,
249+ } ;
272250 }
273251}
0 commit comments