Skip to content

[experimental] Performance testing#1540

Draft
VaguelySerious wants to merge 129 commits intomainfrom
peter/vroom
Draft

[experimental] Performance testing#1540
VaguelySerious wants to merge 129 commits intomainfrom
peter/vroom

Conversation

@VaguelySerious
Copy link
Copy Markdown
Member

Summary

🚧 WIP — Do not merge

Combines two branches for performance testing:

  • peter/v2-flow — Eager inline step execution & incremental event replay. Merges workflow and step handlers into a single workflowEntrypoint(), executing steps inline where possible and only deferring to the queue for parallelism. Reduces function invocations dramatically (e.g., 10-step serial workflow: 21 → 1 invocation).
  • peter/lazy-start — Resilient start() that calls run_created and queue in parallel via Promise.allSettled, tolerating storage unavailability as long as the queue is healthy. Also speeds up run start by removing the sequential dependency.

Test plan

  • Unit tests pass (pnpm test)
  • E2E tests pass against preview deployment
  • Performance comparison vs main branch

🤖 Generated with Claude Code

VaguelySerious and others added 30 commits March 11, 2026 14:33
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
…nd step handler

Transient network errors (ECONNRESET, etc.) during infrastructure calls
(event listing, event creation) were caught by a shared try/catch that
also handles user code errors, incorrectly marking runs as run_failed
or steps as step_failed instead of letting the queue redeliver.

- runtime.ts: Move infrastructure calls outside the user-code try/catch
  so errors propagate to the queue handler for automatic retry
- step-handler.ts: Same structural separation — only stepFn.apply() is
  wrapped in the try/catch that produces step_failed/step_retrying
- helpers.ts: Add isTransientNetworkError() and update withServerErrorRetry
  to retry network errors in addition to 5xx responses
- helpers.test.ts: Add tests for network error detection and retry
Merge flow and step routes into a single combined handler that executes
steps inline when possible, reducing function invocations and queue
overhead. Serial workflows can now complete in a single function
invocation instead of 2N+1 invocations.

Key changes:
- Add `combinedEntrypoint()` to core runtime with inline step execution loop
- Extract reusable step execution logic into `step-executor.ts`
- Add `handleSuspensionV2()` that creates events without queuing steps
- Add `stepId` field to `WorkflowInvokePayload` for background step dispatch
- Add `createCombinedBundle()` to base builder
- Update Next.js builder to generate combined route at v1/flow
- Update health check e2e tests for single-route architecture

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Redundant with undici RetryAgent which already handles 5xx retries
and network error retries at the HTTP dispatcher level.
The step registrations file moved from step/route.js to
flow/__step_registrations.js in the V2 combined bundle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The watch mode was still using workflowEntrypoint wrapper from the
original createWorkflowsBundle. Provide a custom bundleFinal that
generates the combined entrypoint wrapper instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The deferred builder hasn't been updated for the V2 combined bundle yet.
Disable lazyDiscovery in the turbopack workbench to use the eager
builder which has V2 support. Also remove step route from deferred
entries since V2 doesn't generate a separate step route.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the combined handler receives a stepId message (background step),
execute the step then queue a plain workflow continuation — don't
replay inline. The step_started/step_completed events need to be
consumed by the workflow's event subscriptions during replay, which
requires the workflow code to re-execute from the beginning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same fix as turbopack — deferred builder doesn't support V2 yet.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… try/catch, re-add 5xx/410 safety net in step handler, relax e2e test assertion
This test validated withServerErrorRetry's in-process retry behavior,
which was removed. Queue-level retry with process-scoped fault injection
is unreliable across serverless instances and too slow for e2e timeouts.
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Cache the event log in memory across loop iterations. On the first
iteration, do a full load and save the pagination cursor. On subsequent
iterations, fetch only new events created after the last known cursor
and append them to the cached array.

This avoids re-fetching the entire event log on every replay cycle,
which is significant for workflows with many steps where the event
log grows with each completed step.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The server now always returns a cursor on the final page, so the
fallback full-reload branch is no longer needed. Simplified to a
clean first-load vs incremental-load branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All World implementations should return a cursor when there are events,
but if one doesn't, fall back to a full reload with an error log rather
than silently breaking incremental loading.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
VaguelySerious and others added 2 commits March 30, 2026 17:47
…le call

Remove duplicate `format` and `inputFiles` parameters and invalid
`rewriteTsExtensions` parameter from the createCombinedBundle call
in the vitest builder.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
VaguelySerious and others added 4 commits March 30, 2026 17:50
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
Missing braces in template literal: `/dep$inputExt` -> `/dep${inputExt}`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants