Skip to content

Conversation

conico974
Copy link
Contributor

@conico974 conico974 commented Aug 1, 2025

Update handling of pending writes to prevent locked readable streams in the composable cache. This change improves the management of cache entries and ensures proper stream handling.

I want to make some test first, as this one will increase memory usage, which could be an issue in cloudflare
Seems to be working fine

Copy link

changeset-bot bot commented Aug 1, 2025

🦋 Changeset detected

Latest commit: 6a34a21

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@opennextjs/aws Patch
app-pages-router Patch
app-router Patch

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

Copy link

pkg-pr-new bot commented Aug 1, 2025

Open in StackBlitz

pnpm add https://pkg.pr.new/@opennextjs/aws@939

commit: 6a34a21

Copy link
Contributor

github-actions bot commented Aug 1, 2025

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 27.7% 2720 / 9817
🔵 Statements 27.7% 2720 / 9817
🔵 Functions 55.51% 146 / 263
🔵 Branches 74.63% 668 / 895
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/open-next/src/adapters/composable-cache.ts 98.3% 94.73% 100% 98.3% 42, 53
Generated in workflow #1402 for commit 6a34a21 by the Vitest Coverage Report Action

@conico974 conico974 marked this pull request as ready for review August 1, 2025 12:16
@conico974 conico974 requested a review from Copilot August 3, 2025 14:28
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Fixes a locked readable stream issue in the composable cache by improving how pending cache entries are handled. The solution prevents stream locking by ensuring that ReadableStreams are properly converted to strings before storing and recreated when retrieving from the pending write map.

  • Updates pending write promise mapping to handle string values instead of streams
  • Improves stream handling during cache get operations for pending entries
  • Adds comprehensive test coverage for the composable cache functionality

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
packages/open-next/src/adapters/composable-cache.ts Fixes stream locking by converting streams to strings in pending writes and recreating streams on retrieval
packages/tests-unit/tests/adapters/composable-cache.test.ts Adds comprehensive test suite covering all cache operations including concurrent access scenarios
.changeset/wet-emus-brake.md Documents the fix for locked readable stream issue
Comments suppressed due to low confidence (2)

packages/open-next/src/adapters/composable-cache.ts:7

  • [nitpick] The variable name pendingWritePromiseMap could be more concise. Consider renaming to pendingWrites or pendingEntries for better readability.
const pendingWritePromiseMap = new Map<

packages/tests-unit/tests/adapters/composable-cache.test.ts:404

  • The variable name writtenTags shadows the global variable declared at line 50. Consider renaming to writtenTagsCall or actualWrittenTags to avoid confusion.
      const writtenTags = tagCache.writeTags.mock.calls[0][0];

invalidatePaths: vi.fn(),
};
globalThis.cdnInvalidationHandler = invalidateCdnHandler;
let writtenTags = new Set();
Copy link
Preview

Copilot AI Aug 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The writtenTags variable is declared with let but could be const since it's reassigned in beforeEach blocks rather than mutated directly.

Suggested change
let writtenTags = new Set();
const writtenTags = new Set();

Copilot uses AI. Check for mistakes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This AI just stole my job!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It stole mine as well. It wrote a lot of the unit test 😄

// If we do, we return the pending promise instead of fetching the cache
if (pendingWritePromiseMap.has(cacheKey)) {
return pendingWritePromiseMap.get(cacheKey);
const stored = pendingWritePromiseMap.get(cacheKey)!;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a scenario where set doesn't get called and this returns undefined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of any, but I can add a check just in case. And it will stop typescript complaining

Copy link
Contributor

@khuezy khuezy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@conico974 conico974 merged commit 521346b into main Aug 3, 2025
3 checks passed
@conico974 conico974 deleted the conico/locked-readable-stream branch August 3, 2025 20:42
@conico974
Copy link
Contributor Author

Thanks for the review!

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