Skip to content

Serialize WebSocket stream batches - #3780

Closed
alangenfeld wants to merge 1 commit into
alangenfeld/plan-ws-streams-clientfrom
alangenfeld/ws-pipeline-depth-isolation
Closed

Serialize WebSocket stream batches#3780
alangenfeld wants to merge 1 commit into
alangenfeld/plan-ws-streams-clientfrom
alangenfeld/ws-pipeline-depth-isolation

Conversation

@alangenfeld

Copy link
Copy Markdown
Collaborator

Summary & Motivation

Matches the HTTP stream path's serial delivery, so a WebSocket comparison measures transport behavior rather than pipeline depth. The server's socket handler is serial anyway, so extra in-flight frames only queue behind it.

Test Plan

Existing coverage runs in CI.

@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview, v0 Aug 25, 2026 2:43pm
example-nextjs-workflow-webpack Ready Ready Preview, v0 Aug 25, 2026 2:43pm
example-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-astro-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-express-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-fastify-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-hono-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-nestjs-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-nitro-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-nuxt-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-python-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-sveltekit-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-tanstack-start-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workbench-vite-workflow Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workflow-docs Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workflow-swc-playground Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workflow-tarballs Ready Ready Preview, v0 Aug 25, 2026 2:43pm
workflow-web Ready Ready Preview, v0 Aug 25, 2026 2:43pm

@changeset-bot

changeset-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b2e738c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

Some tests failed

❌ Failed E2E Tests

▲ Vercel Production (8 failed)

python-node (8 failed):

  • promiseAllWorkflow | wrun_41M0WP1GTY0GPYQ2TF83FZAR1G | 🔍 observability
  • sleepingWorkflow | wrun_41M0WP273R0GYX2EPAYN3K99S0 | 🔍 observability
  • parallelSleepWorkflow | wrun_41M0WP28W10GT4MEYYMVSJN9W3 | 🔍 observability
  • nullByteWorkflow | wrun_41M0WP2CNY0GT572X26RZY2NEA | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41M0WP7ACQ0GWSJMYY07D76TBW | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41M0WP7DJB0GYWCDMK3H0A3MWA | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration | wrun_41M0WP7MFG0GJ5FDXC53WZVFJ3 | 🔍 observability
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41M0WP870J0GWG3Z1WW9R9DYJ0 | 🔍 observability

🌐 Cross-language Conformance (9 failed)

python (9 failed):

  • deploymentId: 'latest' is a no-op in non-Vercel worlds | wrun_01M0WP8DD95DCHHNFMP4BW1AS2
  • promiseAllWorkflow | wrun_41M0WP1GTY0GPYQ2TF83FZAR1G
  • sleepingWorkflow | wrun_41M0WP273R0GYX2EPAYN3K99S0
  • parallelSleepWorkflow | wrun_41M0WP28W10GT4MEYYMVSJN9W3
  • nullByteWorkflow | wrun_41M0WP2CNY0GT572X26RZY2NEA
  • cancelRun - cancelling a running workflow | wrun_41M0WP7ACQ0GWSJMYY07D76TBW
  • cancelRun via CLI - cancelling a running workflow | wrun_41M0WP7DJB0GYWCDMK3H0A3MWA
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration | wrun_41M0WP7MFG0GJ5FDXC53WZVFJ3
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41M0WP870J0GWG3Z1WW9R9DYJ0

⚠️ Flaky E2E Tests (passed on retry)

These tests failed at least once and passed on a retry. A recurring entry here is a real race worth investigating.

  • addTenWorkflow (vite)
  • cancelRun via CLI - cancelling a running workflow (nextjs-turbopack)
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep (nextjs-webpack)
  • webhookWorkflow (tanstack-start)

🛠 Infra Events (absorbed by the harness)

Platform anomalies the e2e harness detected and worked around (e.g. a run the queue never picked up, replaced by a fresh run). Clustered timestamps indicate a backend blip; a steady drip indicates a platform issue worth escalating.

34 infra events
  • cold-start-warmup · suite warmup (tanstack-start) · at 14:45:12Z · abandoned wrun_01M0WP33SFKPE8KY4WXPG2101W
  • cold-start-warmup · suite warmup (python) · at 14:45:56Z · abandoned wrun_41M0WP1FXC0GVTA6ZT5CAD647H · (+7 more)
  • run-pickup-stall · nullByteWorkflow (python) · at 14:46:13Z · abandoned wrun_41M0WP54QZ0GHRBS0JX703DMND
  • run-pickup-stall · promiseAllWorkflow (python) · at 14:46:13Z · abandoned wrun_41M0WP54QP0GK4JDSJ7HTH0Z11
  • run-pickup-stall · sleepingWorkflow (python) · at 14:46:13Z · abandoned wrun_41M0WP54QV0GTGRB25RXQNW392
  • run-pickup-stall · cancelRun - cancelling a running workflow (python) · at 14:46:13Z · abandoned wrun_41M0WP55480GJD89F3F4NK4QDH
  • run-pickup-stall · parallelSleepWorkflow (python) · at 14:46:13Z · abandoned wrun_41M0WP54QV0GTGRB25RXQNW393
  • cold-start-warmup · suite warmup (python) · at 14:46:28Z · abandoned wrun_01M0WP2EZJR20KKTNEV9Q9CK5W · (+7 more)
  • run-pickup-stall · deploymentId: 'latest' is a no-op in non-Vercel worlds (python) · at 14:46:43Z · abandoned wrun_01M0WP6446AWXN03AKZ2N76NYA
  • run-pickup-stall · nullByteWorkflow (python) · at 14:46:43Z · abandoned wrun_01M0WP644G9SFDJRGKC9BEAXJG
  • run-pickup-stall · promiseAllWorkflow (python) · at 14:46:43Z · abandoned wrun_01M0WP6447FS4FKP4S5MH0VG8G
  • run-pickup-stall · sleepingWorkflow (python) · at 14:46:43Z · abandoned wrun_01M0WP644C66KSDXEZ1DBBF10A
  • run-pickup-stall · parallelSleepWorkflow (python) · at 14:46:43Z · abandoned wrun_01M0WP644ENVAPDH79HTFKQWT5
  • run-pickup-stall · cancelRun - cancelling a running workflow (python) · at 14:46:46Z · abandoned wrun_41M0WP65150GR8GJAECVFP6ABS
  • run-pickup-stall · sleepingWorkflow (python) · at 14:47:13Z · abandoned wrun_41M0WP70890GNDD2CY0DB2PDJ3
  • run-pickup-stall · promiseAllWorkflow (python) · at 14:47:13Z · abandoned wrun_41M0WP70860GXRJAC9VH95G51P
  • run-pickup-stall · parallelSleepWorkflow (python) · at 14:47:14Z · abandoned wrun_41M0WP709D0GPAP1AKVHDJEYSS
  • run-pickup-stall · nullByteWorkflow (python) · at 14:47:14Z · abandoned wrun_41M0WP709G0GW32929X60MMAC4
  • run-pickup-stall · nullByteWorkflow (python) · at 14:47:43Z · abandoned wrun_01M0WP7YR4SD25BBEP2KF3A5K6
  • run-pickup-stall · parallelSleepWorkflow (python) · at 14:47:43Z · abandoned wrun_01M0WP7YR5726360KTAEJ8Q539
  • run-pickup-stall · sleepingWorkflow (python) · at 14:47:43Z · abandoned wrun_01M0WP7YR74VNTGC3XY7M7AN4D
  • run-pickup-stall · promiseAllWorkflow (python) · at 14:47:43Z · abandoned wrun_01M0WP7YR0R8CR343137S0VZNN
  • run-pickup-stall · deploymentId: 'latest' is a no-op in non-Vercel worlds (python) · at 14:47:43Z · abandoned wrun_01M0WP7YR2ECPDW2TWH2HTPPZK
  • run-pickup-stall · cancelRun via CLI - cancelling a running workflow (python) · at 14:48:04Z · abandoned wrun_41M0WP74YT0GN2PB16HQ1GR657
  • run-pickup-stall · cancelRun - cancelling a running workflow (python) · at 14:48:43Z · abandoned wrun_01M0WP9SBNYC2RQR0AA55RHMD2
  • run-pickup-stall · sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration (python) · at 14:48:43Z · abandoned wrun_01M0WP9SBZVTEZN9VSAEHT9XNY
  • run-pickup-stall · cancelRun via CLI - cancelling a running workflow (python) · at 14:48:43Z · abandoned wrun_01M0WP9SBXCJRMSKNJ0E0TXD4A
  • run-pickup-stall · cancelRun - cancelling a running workflow (python) · at 14:49:13Z · abandoned wrun_01M0WPAPQPYQKQZ6JS4FTGR7V6
  • run-pickup-stall · cancelRun via CLI - cancelling a running workflow (python) · at 14:49:13Z · abandoned wrun_01M0WPAPQMHMGR609Q8NX40SG5
  • run-pickup-stall · sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration (python) · at 14:49:43Z · abandoned wrun_01M0WPBKZ3WA15RRXB7E1TA1DC
  • run-pickup-stall · cancelRun via CLI - cancelling a running workflow (python) · at 14:50:25Z · abandoned wrun_41M0WP9WVC0GSE72NPJK0EM8EY
  • run-pickup-stall · sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration (python) · at 14:50:25Z · abandoned wrun_41M0WP9R4Q0GGY555A8EHMTSH1
  • run-pickup-stall · hookWithSleepFinalStepWorkflow - step only on final payload (nextjs-webpack) · at 14:53:31Z · abandoned wrun_01M0WPJJBKAFRPDEC0PMM9YEBN
  • run-pickup-stall · sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration (nextjs-webpack) · at 14:53:31Z · abandoned wrun_01M0WPJJE2H0JP9GJYDQ2JJX6G

E2E Test Summary

Summary
Passed Failed Skipped Total
❌ ▲ Vercel Production 3570 8 742 4320
✅ 💻 Local Development 3922 0 558 4480
✅ 📦 Local Production 3922 0 558 4480
✅ 🐘 Local Postgres 3922 0 558 4480
✅ 🪟 Windows 320 0 0 320
❌ 🌐 Cross-language Conformance 0 9 132 141
✅ vercel-http-transport 817 0 143 960
✅ vercel-multi-region 27 0 0 27
✅ vercel-ws-transport 553 0 87 640
Total 17053 17 2778 19848
Details by Category

❌ ▲ Vercel Production

App Passed Failed Skipped
✅ astro-node 132 0 28
✅ astro-quickjs 132 0 28
✅ example-node 132 0 28
✅ example-quickjs 132 0 28
✅ express-node 132 0 28
✅ express-quickjs 132 0 28
✅ fastify-node 132 0 28
✅ fastify-quickjs 132 0 28
✅ hono-node 132 0 28
✅ hono-quickjs 132 0 28
✅ nest-node 132 0 28
✅ nest-quickjs 132 0 28
✅ nextjs-turbopack-node 157 0 3
✅ nextjs-turbopack-quickjs 157 0 3
✅ nextjs-webpack-node 157 0 3
✅ nextjs-webpack-quickjs 157 0 3
✅ nitro-node 132 0 28
✅ nitro-quickjs 132 0 28
✅ nuxt-node 132 0 28
✅ nuxt-quickjs 132 0 28
❌ python-node 0 8 152
✅ sveltekit-node 151 0 9
✅ sveltekit-quickjs 151 0 9
✅ tanstack-start-node 132 0 28
✅ tanstack-start-quickjs 132 0 28
✅ vite-node 132 0 28
✅ vite-quickjs 132 0 28

✅ 💻 Local Development

App Passed Failed Skipped
✅ astro-stable-node 134 0 26
✅ astro-stable-quickjs 134 0 26
✅ express-stable-node 134 0 26
✅ express-stable-quickjs 134 0 26
✅ fastify-stable-node 134 0 26
✅ fastify-stable-quickjs 134 0 26
✅ hono-stable-node 134 0 26
✅ hono-stable-quickjs 134 0 26
✅ nest-stable-node 134 0 26
✅ nest-stable-quickjs 134 0 26
✅ nextjs-turbopack-canary-node 141 0 19
✅ nextjs-turbopack-canary-quickjs 141 0 19
✅ nextjs-turbopack-stable-node 160 0 0
✅ nextjs-turbopack-stable-quickjs 160 0 0
✅ nextjs-webpack-canary-node 141 0 19
✅ nextjs-webpack-canary-quickjs 141 0 19
✅ nextjs-webpack-stable-node 160 0 0
✅ nextjs-webpack-stable-quickjs 160 0 0
✅ nitro-stable-node 134 0 26
✅ nitro-stable-quickjs 134 0 26
✅ nuxt-stable-node 134 0 26
✅ nuxt-stable-quickjs 134 0 26
✅ sveltekit-stable-node 153 0 7
✅ sveltekit-stable-quickjs 153 0 7
✅ tanstack-start-node 134 0 26
✅ tanstack-start-quickjs 134 0 26
✅ vite-stable-node 134 0 26
✅ vite-stable-quickjs 134 0 26

✅ 📦 Local Production

App Passed Failed Skipped
✅ astro-stable-node 134 0 26
✅ astro-stable-quickjs 134 0 26
✅ express-stable-node 134 0 26
✅ express-stable-quickjs 134 0 26
✅ fastify-stable-node 134 0 26
✅ fastify-stable-quickjs 134 0 26
✅ hono-stable-node 134 0 26
✅ hono-stable-quickjs 134 0 26
✅ nest-stable-node 134 0 26
✅ nest-stable-quickjs 134 0 26
✅ nextjs-turbopack-canary-node 141 0 19
✅ nextjs-turbopack-canary-quickjs 141 0 19
✅ nextjs-turbopack-stable-node 160 0 0
✅ nextjs-turbopack-stable-quickjs 160 0 0
✅ nextjs-webpack-canary-node 141 0 19
✅ nextjs-webpack-canary-quickjs 141 0 19
✅ nextjs-webpack-stable-node 160 0 0
✅ nextjs-webpack-stable-quickjs 160 0 0
✅ nitro-stable-node 134 0 26
✅ nitro-stable-quickjs 134 0 26
✅ nuxt-stable-node 134 0 26
✅ nuxt-stable-quickjs 134 0 26
✅ sveltekit-stable-node 153 0 7
✅ sveltekit-stable-quickjs 153 0 7
✅ tanstack-start-node 134 0 26
✅ tanstack-start-quickjs 134 0 26
✅ vite-stable-node 134 0 26
✅ vite-stable-quickjs 134 0 26

✅ 🐘 Local Postgres

App Passed Failed Skipped
✅ astro-stable-node 134 0 26
✅ astro-stable-quickjs 134 0 26
✅ express-stable-node 134 0 26
✅ express-stable-quickjs 134 0 26
✅ fastify-stable-node 134 0 26
✅ fastify-stable-quickjs 134 0 26
✅ hono-stable-node 134 0 26
✅ hono-stable-quickjs 134 0 26
✅ nest-stable-node 134 0 26
✅ nest-stable-quickjs 134 0 26
✅ nextjs-turbopack-canary-node 141 0 19
✅ nextjs-turbopack-canary-quickjs 141 0 19
✅ nextjs-turbopack-stable-node 160 0 0
✅ nextjs-turbopack-stable-quickjs 160 0 0
✅ nextjs-webpack-canary-node 141 0 19
✅ nextjs-webpack-canary-quickjs 141 0 19
✅ nextjs-webpack-stable-node 160 0 0
✅ nextjs-webpack-stable-quickjs 160 0 0
✅ nitro-stable-node 134 0 26
✅ nitro-stable-quickjs 134 0 26
✅ nuxt-stable-node 134 0 26
✅ nuxt-stable-quickjs 134 0 26
✅ sveltekit-stable-node 153 0 7
✅ sveltekit-stable-quickjs 153 0 7
✅ tanstack-start-node 134 0 26
✅ tanstack-start-quickjs 134 0 26
✅ vite-stable-node 134 0 26
✅ vite-stable-quickjs 134 0 26

✅ 🪟 Windows

App Passed Failed Skipped
✅ nextjs-turbopack-node 160 0 0
✅ nextjs-turbopack-quickjs 160 0 0

❌ 🌐 Cross-language Conformance

App Passed Failed Skipped
❌ python 0 9 132

✅ vercel-http-transport

App Passed Failed Skipped
✅ example 132 0 28
✅ express 132 0 28
✅ hono 132 0 28
✅ nextjs-turbopack 157 0 3
✅ nitro 132 0 28
✅ vite 132 0 28

✅ vercel-multi-region

App Passed Failed Skipped
✅ nextjs-turbopack 27 0 0

✅ vercel-ws-transport

App Passed Failed Skipped
✅ example 132 0 28
✅ express 132 0 28
✅ nextjs-turbopack 157 0 3
✅ vite 132 0 28

📋 View full workflow run

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Sim World

Simulated world deterministic testing for races. Traces

🟠 world-sim scenario book — 1 fail of 41 total

fence=per-spec

scenario outcome events virt replay violations
smoke-no-steps completed 3 0ms ok 0
smoke-one-step completed 6 0ms ok 0
hook-at-step-started completed 12 0ms ok 0
hook-at-step-completed completed 12 0ms ok 0
hook-at-hook-created completed 12 0ms ok 0
deadline-hook-wins completed 7 1.0h ok 0
deadline-expires completed 7 1.0h ok 0
long-sleep completed 11 30.0d ok 0
hook-never-arrives stalled 3 0ms skipped 0
step-retries-twice completed 10 2.0s ok 0
parallel-steps completed 9 0ms ok 0
hook-on-execution-state completed 12 0ms ok 0
peek-hook-before-branch completed 12 0ms ok 0
peek-hook-after-branch completed 12 0ms ok 0
peek-hook-at-registration completed 12 0ms ok 0
race-hook-before-probe completed 12 0ms ok 0
race-hook-after-probe completed 12 0ms ok 0
race-duplicate-delivery completed 13 0ms ok 0
attr-hook-before-step completed 11 0ms ok 0
attr-hook-after-step completed 11 0ms ok 0
attr-from-step-body completed 13 0ms ok 0
fork-hook-after-timeout completed 14 1.0m ok 0
fork-hook-before-timeout completed 14 1.0m ok 0
count-hook-after-timeout completed 17 1.0m ok 0
count-hook-before-timeout completed 20 1.0m ok 0
stale-read-step-count-fork completed 20 1.0m ok 0
stale-read-equal-step-counts completed 14 1.0m ok 0
step-vs-step-fork completed 12 0ms ok 0
step-vs-step-fork-fenced completed 12 0ms ok 0
fence-catches-benign-direction completed 12 5ms ok 0
in-flight-before-decision completed 17 1.0m ok 0
in-flight-before-decision-counted completed 17 1.0m ok 0
in-flight-after-decision completed 19 2.0m ok 0
stale-read-step-count-fork-fenced completed 20 1.0m ok 0
fork-hook-wins completed 13 1.0m ok 0
fork-timeout-wins completed 13 1.0m ok 0
unclaimed-payload-under-fork completed 17 1.0m ok 0
claimed-payload-under-fork completed 17 1.0m ok 0
writers-independent-step-bodies completed 12 0ms ok 0
writers-scripted-tempo completed 12 0ms ok 0
cancel-mid-step cancelled 7 0ms skipped 0

Full trace: world-sim.txt

Signed-off-by: Alex Langenfeld <alex.langenfeld@vercel.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.

1 participant