Skip to content

Commit 39921c6

Browse files
retry with 1 connection
1 parent 732b86a commit 39921c6

2 files changed

Lines changed: 35 additions & 96 deletions

File tree

integration-tests/common/LoadTest.test.ts

Lines changed: 34 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,133 +2,75 @@ import { describe, test, expect, jest } from "@jest/globals";
22
import { orkesConductorClient } from "../../src/orkes";
33
import { WorkflowExecutor } from "../../src/core";
44
import { TaskType } from "../../src/common";
5-
import { fetch as undiciFetch, Agent as UndiciAgent } from "undici";
65

7-
// --- Configuration for the Load Test ---
8-
// The number of requests to send in parallel.
9-
// Adjust this number to find the breaking point of your load balancer.
106
const CONCURRENT_REQUESTS = 500;
117
const TEST_TIMEOUT = 180000 * 10; // 180 seconds
128

139
describe("Load Test for ECONNRESET", () => {
1410
jest.setTimeout(TEST_TIMEOUT);
1511

1612
test(`should handle ${CONCURRENT_REQUESTS} staggered GET requests (1 every 0ms) without ECONNRESET`, async () => {
17-
// const client = await orkesConductorClient();
18-
// const executor = new WorkflowExecutor(client);
13+
const client = await orkesConductorClient();
14+
const executor = new WorkflowExecutor(client);
1915

20-
// // To ensure we are making valid API calls, we first create a simple
21-
// // workflow and start one execution. We will then query this execution's status.
22-
// const workflowName = "load_test_workflow";
23-
// await executor.registerWorkflow(true, {
24-
// name: workflowName,
25-
// version: 1,
26-
// tasks: [
27-
// {
28-
// name: "simple_task",
29-
// taskReferenceName: "simple_task_ref",
30-
// type: TaskType.SIMPLE,
31-
// },
32-
// ],
33-
// timeoutSeconds: 0,
34-
// inputParameters: [],
35-
// });
36-
// const executionId = await executor.startWorkflow({
37-
// name: workflowName,
38-
// version: 1,
39-
// });
16+
// To ensure we are making valid API calls, we first create a simple
17+
// workflow and start one execution. We will then query this execution's status.
18+
const workflowName = "load_test_workflow";
19+
await executor.registerWorkflow(true, {
20+
name: workflowName,
21+
version: 1,
22+
tasks: [
23+
{
24+
name: "simple_task",
25+
taskReferenceName: "simple_task_ref",
26+
type: TaskType.SIMPLE,
27+
},
28+
],
29+
timeoutSeconds: 0,
30+
inputParameters: [],
31+
});
32+
const executionId = await executor.startWorkflow({
33+
name: workflowName,
34+
version: 1,
35+
});
4036

41-
// console.log(
42-
// `Starting load test with workflow execution ID: ${executionId}`
43-
// );
37+
console.log(
38+
`Starting load test with workflow execution ID: ${executionId}`
39+
);
4440
console.log(
4541
`Sending ${CONCURRENT_REQUESTS} staggered requests (1 every 0ms)...`
4642
);
4743

48-
// Create an array to hold all the request promises.
49-
const undiciAgent = new UndiciAgent({
50-
allowH2: true,
51-
connections: 1,
52-
//pipelining: 10,
53-
// keepAliveTimeout: 270000,
54-
// keepAliveMaxTimeout: 270000,
55-
// connectTimeout: 270000,
56-
// bodyTimeout: 270000,
57-
// headersTimeout: 270000,
58-
// connect: {
59-
// timeout: 270000, // Connect timeout in milliseconds (e.g., 60 seconds)
60-
// },
61-
});
62-
63-
// Create an array to hold all the request promises.
6444
const requestPromises: Promise<any>[] = [];
6545
for (let i = 0; i < CONCURRENT_REQUESTS; i++) {
66-
// Start the request but don't wait for it to finish here.
67-
//requestPromises.push(executor.getWorkflow(executionId, false));
68-
//requestPromises.push(fetch(`https://siliconmint-dev-5x.orkesconductor.io/`));
69-
requestPromises.push(
70-
undiciFetch(`https://siliconmint-dev-5x.orkesconductor.io/`, {
71-
dispatcher: undiciAgent,
72-
})
73-
);
74-
// requestPromises.push(
75-
// undiciFetch(`https://siliconmint-dev-5x.orkesconductor.io/`, {
76-
// dispatcher: undiciAgent,
77-
// })
78-
// );
79-
80-
// if (i < CONCURRENT_REQUESTS - 1) {
81-
// // Wait 100ms before starting the next request.
82-
// await new Promise((resolve) => setTimeout(resolve, 0));
83-
// }
46+
requestPromises.push(executor.getWorkflow(executionId, false));
8447
}
8548

86-
// Now, wait for all the in-flight requests to complete.
8749
const results = await Promise.allSettled(requestPromises);
8850

89-
// Analyze the results to find specific errors
9051
let successCount = 0;
91-
const econnresetErrors: any[] = [];
92-
const http429Errors: any[] = [];
93-
const otherErrors: any[] = [];
52+
const errors: any[] = [];
9453

9554
results.forEach((result, index) => {
9655
if (result.status === "fulfilled") {
9756
successCount++;
9857
} else {
9958
const reason = result.reason;
100-
// Check if the rejection reason is the specific ECONNRESET error
101-
if (reason?.code === "ECONNRESET") {
102-
econnresetErrors.push({ requestIndex: index, reason });
103-
} else if (reason?.body?.status === 429) {
104-
http429Errors.push({ requestIndex: index, reason });
105-
} else {
106-
otherErrors.push({ requestIndex: index, reason });
107-
}
59+
60+
errors.push({ requestIndex: index, reason });
10861
}
10962
});
11063

11164
console.log("--- Load Test Results ---");
11265
console.log(
11366
`Successful Requests: ${successCount} / ${CONCURRENT_REQUESTS}`
11467
);
115-
console.log(`ECONNRESET Failures: ${econnresetErrors.length}`);
116-
console.log(`HTTP 429 Failures: ${http429Errors.length}`);
117-
console.log(`Other Failures: ${otherErrors.length}`);
68+
console.log(`Failures: ${errors.length}`);
11869
console.log("-------------------------");
11970

120-
if (econnresetErrors.length > 0) {
121-
console.error("ECONNRESET errors detected:", econnresetErrors);
122-
}
123-
if (http429Errors.length > 0) {
124-
console.error(
125-
"HTTP 429 (Too Many Requests) errors detected:",
126-
http429Errors
127-
);
128-
}
129-
if (otherErrors.length > 0) {
130-
console.error(`\n--- Other Errors (${otherErrors.length}) ---`);
131-
for (const error of otherErrors) {
71+
if (errors.length > 0) {
72+
console.error(`\n--- Errors (${errors.length}) ---`);
73+
for (const error of errors) {
13274
console.error(
13375
`Request Index ${error.requestIndex} failed. Reason:`,
13476
error.reason
@@ -137,9 +79,6 @@ describe("Load Test for ECONNRESET", () => {
13779
console.error("--------------------------\n");
13880
}
13981

140-
// The test assertion: Fail if we encounter any ECONNRESET errors.
141-
expect(econnresetErrors.length).toBe(0);
142-
expect(http429Errors.length).toBe(0);
143-
expect(otherErrors.length).toBe(0);
82+
expect(errors.length).toBe(0);
14483
});
14584
});

src/orkes/helpers/resolveFetchFn.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const resolveFetchFn = async (
1313
// eslint-disable-next-line
1414
// @ts-ignore since undici is an optional dependency and could me missing
1515
const { fetch: undiciFetch, Agent } = await import("undici");
16-
const undiciAgent = new Agent({ allowH2: true, connections: 500 });
16+
const undiciAgent = new Agent({ allowH2: true, connections: 1 });
1717

1818
return ((input: RequestInfo, init?: RequestInit) =>
1919
undiciFetch(input, { ...init, dispatcher: undiciAgent })) as FetchFn;

0 commit comments

Comments
 (0)