Skip to content

Commit 071863f

Browse files
committed
fix: Reconnect clients on retry
1 parent 395bc6c commit 071863f

1 file changed

Lines changed: 55 additions & 30 deletions

File tree

e2e_tests/typescript/src/main.ts

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import {
1010
import logger from "./logger.js";
1111

1212
async function main(): Promise<void> {
13-
logger.info(`Starting e2e test with LOG_LEVEL=${process.env.LOG_LEVEL || 'info'}`);
13+
logger.info(
14+
`Starting e2e test with LOG_LEVEL=${process.env.LOG_LEVEL || "info"}`
15+
);
1416
logger.info(`Node version: ${process.version}`);
1517

1618
const config = new Configuration();
@@ -19,7 +21,9 @@ async function main(): Promise<void> {
1921
const mcpClients = [];
2022

2123
logger.info("Initializing MCP clients...");
22-
for (const [name, srvConfig] of Object.entries(serverConfig.stdioServers || {})) {
24+
for (const [name, srvConfig] of Object.entries(
25+
serverConfig.stdioServers || {}
26+
)) {
2327
try {
2428
mcpClients.push(await createStdioClient(name, srvConfig));
2529
} catch (error) {
@@ -28,25 +32,37 @@ async function main(): Promise<void> {
2832
}
2933
}
3034

31-
for (const [name, srvConfig] of Object.entries(serverConfig.lambdaFunctionServers || {})) {
35+
for (const [name, srvConfig] of Object.entries(
36+
serverConfig.lambdaFunctionServers || {}
37+
)) {
3238
try {
3339
mcpClients.push(await createLambdaFunctionClient(name, srvConfig));
3440
} catch (error) {
35-
logger.error(`Failed to initialize lambda function server ${name}:`, error);
41+
logger.error(
42+
`Failed to initialize lambda function server ${name}:`,
43+
error
44+
);
3645
throw error;
3746
}
3847
}
3948

40-
for (const [name, srvConfig] of Object.entries(serverConfig.lambdaFunctionUrls || {})) {
49+
for (const [name, srvConfig] of Object.entries(
50+
serverConfig.lambdaFunctionUrls || {}
51+
)) {
4152
try {
4253
mcpClients.push(await createLambdaFunctionUrlClient(name, srvConfig));
4354
} catch (error) {
44-
logger.error(`Failed to initialize lambda function URL server ${name}:`, error);
55+
logger.error(
56+
`Failed to initialize lambda function URL server ${name}:`,
57+
error
58+
);
4559
throw error;
4660
}
4761
}
4862

49-
for (const [name, srvConfig] of Object.entries(serverConfig.oAuthServers || {})) {
63+
for (const [name, srvConfig] of Object.entries(
64+
serverConfig.oAuthServers || {}
65+
)) {
5066
try {
5167
const client = await createAutomatedOAuthClient(name, srvConfig);
5268
mcpClients.push(client);
@@ -57,41 +73,50 @@ async function main(): Promise<void> {
5773
}
5874

5975
logger.info("Connecting to MCP clients with retry...");
60-
await Promise.all(mcpClients.map(async (client, i) => {
61-
for (let attempt = 0; attempt < 5; attempt++) {
62-
try {
63-
const timeout = new Promise((_, reject) =>
64-
setTimeout(() => reject(new Error(`Connection timeout`)), 30000)
65-
);
66-
await Promise.race([client.connect(), timeout]);
67-
return;
68-
} catch (error) {
69-
if (attempt < 4) {
70-
const delay = 2000 * Math.pow(2, attempt);
71-
logger.warn(`Client ${i} connection failed, retrying in ${delay}ms...`);
72-
await new Promise(resolve => setTimeout(resolve, delay));
73-
} else {
74-
throw error;
76+
await Promise.all(
77+
mcpClients.map(async (client, i) => {
78+
for (let attempt = 0; attempt < 5; attempt++) {
79+
try {
80+
const timeout = new Promise((_, reject) =>
81+
setTimeout(() => reject(new Error(`Connection timeout`)), 30000)
82+
);
83+
await Promise.race([client.connect(true), timeout]);
84+
return;
85+
} catch (error) {
86+
if (attempt < 4) {
87+
const delay = 2000 * Math.pow(2, attempt);
88+
logger.warn(
89+
`Client ${i} connection failed, retrying in ${delay}ms...`
90+
);
91+
await new Promise((resolve) => setTimeout(resolve, delay));
92+
} else {
93+
throw error;
94+
}
7595
}
7696
}
77-
}
78-
}));
97+
})
98+
);
7999

80100
logger.info(`Successfully initialized ${mcpClients.length} MCP clients`);
81101

82-
const userUtterances = Configuration.loadConfig("../test_questions.json") as string[];
102+
const userUtterances = Configuration.loadConfig(
103+
"../test_questions.json"
104+
) as string[];
83105
logger.info(`Loaded ${userUtterances.length} test questions`);
84106

85107
logger.info("Initializing Bedrock model...");
86-
const region = typeof config.bedrockClient.config.region === 'function'
87-
? await config.bedrockClient.config.region()
88-
: config.bedrockClient.config.region;
108+
const region =
109+
typeof config.bedrockClient.config.region === "function"
110+
? await config.bedrockClient.config.region()
111+
: config.bedrockClient.config.region;
89112
const model = new BedrockModel({
90113
region: region as string,
91114
modelId: config.modelId,
92115
stream: false,
93116
});
94-
logger.info(`Using model: ${config.modelId} in region: ${region} (streaming disabled)`);
117+
logger.info(
118+
`Using model: ${config.modelId} in region: ${region} (streaming disabled)`
119+
);
95120

96121
logger.info("Creating agent...");
97122
const agent = new Agent({
@@ -121,7 +146,7 @@ main().catch((error) => {
121146
if (error.stack) {
122147
logger.error("Stack trace:", error.stack);
123148
}
124-
if ('cause' in error && error.cause) {
149+
if ("cause" in error && error.cause) {
125150
logger.error("Error cause:", JSON.stringify(error.cause, null, 2));
126151
}
127152
}

0 commit comments

Comments
 (0)