Fix stream serialization to resolve when user releases lock instead of waiting for stream to close#678
Conversation
🦋 Changeset detectedLatest commit: 5cdb799 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (17 failed)mongodb (1 failed):
redis (1 failed):
starter (14 failed):
turso (1 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
a298e32 to
4eedfed
Compare
| state.resolve(); | ||
| clearInterval(intervalId); | ||
| } | ||
| }, LOCK_POLL_INTERVAL_MS); |
|
|
||
| /** | ||
| * Polls a WritableStream to check if the user has released their lock. | ||
| * Resolves the done promise when lock is released and no pending ops remain. |
|
@copilot please review the comments on this PR and implement any suggested changes that seem correct / relevant to you |
|
@TooTallNate I've opened a new pull request, #761, to work on those changes. Once the pull request is ready, I'll request review from you. |
…f waiting for stream to close

Fix stream serialization to resolve when users release locks instead of waiting for streams to close, preventing Vercel functions from hanging.
What changed?
flushablePipefunction that resolves in two scenarios:How to test?
Create a workflow step that incrementally writes to a stream:
Verify the step completes immediately after lock release rather than hanging
Run the new test cases that verify both lock release and normal stream closure behaviors
Why make this change?
This fixes an issue where Vercel functions would hang when users incrementally write to streams within steps. Previously, the system would wait for the stream to fully close before resolving, but many users follow a pattern where they write data and release the lock without explicitly closing the stream. This change allows steps to complete as soon as the user releases the lock and all pending writes are flushed, which is the expected behavior in most streaming scenarios.