-
Notifications
You must be signed in to change notification settings - Fork 141
Add stress test benchmarks for large concurrent step counts #539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
70646d4
12f9c1f
e3aa441
c9748aa
9487c93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| "@workflow/world-local": patch | ||
| --- | ||
|
|
||
| perf: optimize for high-concurrency workflows | ||
|
|
||
| - Add in-memory cache for file existence checks to avoid expensive fs.access() calls | ||
| - Increase default concurrency limit from 20 to 100 | ||
| - Improve HTTP connection pooling with undici Agent (100 connections, 30s keepalive) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -86,3 +86,42 @@ export async function streamWorkflow() { | |||||||||||||||||||||
| const doubled = await doubleNumbers(stream); | ||||||||||||||||||||||
| return doubled; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ////////////////////////////////////////////////////////// | ||||||||||||||||||||||
| // Stress test workflows for large concurrent step counts | ||||||||||||||||||||||
| ////////////////////////////////////////////////////////// | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| async function stressTestStep(i: number) { | ||||||||||||||||||||||
| 'use step'; | ||||||||||||||||||||||
| // Minimal work to isolate the overhead of concurrent step tracking | ||||||||||||||||||||||
| return i; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Stress test: Promise.all with many concurrent steps | ||||||||||||||||||||||
| export async function promiseAllStressTestWorkflow(count: number) { | ||||||||||||||||||||||
| 'use workflow'; | ||||||||||||||||||||||
| const promises: Promise<number>[] = []; | ||||||||||||||||||||||
| for (let i = 0; i < count; i++) { | ||||||||||||||||||||||
| promises.push(stressTestStep(i)); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| const results = await Promise.all(promises); | ||||||||||||||||||||||
| return results.length; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Stress test: Promise.race with many concurrent steps (uses Map pattern from report) | ||||||||||||||||||||||
| export async function promiseRaceStressTestLargeWorkflow(count: number) { | ||||||||||||||||||||||
| 'use workflow'; | ||||||||||||||||||||||
| const runningTasks = new Map<number, Promise<number>>(); | ||||||||||||||||||||||
| for (let i = 0; i < count; i++) { | ||||||||||||||||||||||
| runningTasks.set(i, stressTestStep(i)); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const done: number[] = []; | ||||||||||||||||||||||
| while (runningTasks.size > 0) { | ||||||||||||||||||||||
| const result = await Promise.race(runningTasks.values()); | ||||||||||||||||||||||
| done.push(result); | ||||||||||||||||||||||
| runningTasks.delete(result); | ||||||||||||||||||||||
|
Comment on lines
+121
to
+123
|
||||||||||||||||||||||
| const result = await Promise.race(runningTasks.values()); | |
| done.push(result); | |
| runningTasks.delete(result); | |
| const entries = Array.from(runningTasks.entries()); | |
| const racePromises = entries.map(([key, promise]) => | |
| promise.then(result => ({ key, result })) | |
| ); | |
| const { key, result } = await Promise.race(racePromises); | |
| done.push(result); | |
| runningTasks.delete(key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also be stress testing for
Promise.allSettled?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can add more in a future PR but should be no different than
Promise.allwhere everything succeedsWill need to add a new step that throws errors too, to stress test retrying steps that fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm gonna make sure these tests are performant with the incoming PRs, and make sure they don't break (hence why I disabled 500 and 1k) and then will add more teats