@@ -24,8 +24,11 @@ export class ConnectClusterTool extends AtlasToolBase {
24
24
private async queryConnection (
25
25
projectId : string ,
26
26
clusterName : string
27
- ) : Promise < "connected" | "disconnected" | "connecting" | "connected-to-other-cluster" > {
27
+ ) : Promise < "connected" | "disconnected" | "connecting" | "connected-to-other-cluster" | "unknown" > {
28
28
if ( ! this . session . connectedAtlasCluster ) {
29
+ if ( this . session . serviceProvider ) {
30
+ return "connected-to-other-cluster" ;
31
+ }
29
32
return "disconnected" ;
30
33
}
31
34
@@ -40,10 +43,21 @@ export class ConnectClusterTool extends AtlasToolBase {
40
43
return "connecting" ;
41
44
}
42
45
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
+ }
47
61
}
48
62
49
63
private async prepareClusterConnection ( projectId : string , clusterName : string ) : Promise < string > {
@@ -111,8 +125,7 @@ export class ConnectClusterTool extends AtlasToolBase {
111
125
private async connectToCluster (
112
126
projectId : string ,
113
127
clusterName : string ,
114
- connectionString : string ,
115
- tryCount : number
128
+ connectionString : string
116
129
) : Promise < void > {
117
130
let lastError : Error | undefined = undefined ;
118
131
@@ -122,7 +135,8 @@ export class ConnectClusterTool extends AtlasToolBase {
122
135
`attempting to connect to cluster: ${ this . session . connectedAtlasCluster ?. clusterName } `
123
136
) ;
124
137
125
- for ( let i = 0 ; i < tryCount ; i ++ ) {
138
+ // try to connect for about 5 minutes
139
+ for ( let i = 0 ; i < 600 ; i ++ ) {
126
140
if (
127
141
! this . session . connectedAtlasCluster ||
128
142
this . session . connectedAtlasCluster . projectId != projectId ||
@@ -185,89 +199,53 @@ export class ConnectClusterTool extends AtlasToolBase {
185
199
}
186
200
187
201
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 ++ ) {
202
203
const state = await this . queryConnection ( projectId , clusterName ) ;
203
204
switch ( state ) {
204
205
case "connected" :
205
206
return {
206
207
content : [
207
208
{
208
209
type : "text" ,
209
- text : "Cluster is already connected." ,
210
+ text : `Connected to cluster " ${ clusterName } ".` ,
210
211
} ,
211
212
] ,
212
213
} ;
213
214
case "connecting" :
214
- return connectingResult ;
215
+ break ;
215
216
case "connected-to-other-cluster" :
216
217
case "disconnected" :
218
+ case "unknown" :
217
219
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
+ } ) ;
219
232
break ;
220
233
}
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
- } ) ;
269
234
270
- return connectingResult ;
235
+ await sleep ( 500 ) ;
271
236
}
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
+ } ;
272
250
}
273
251
}
0 commit comments