Skip to content
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

Feat: Multi-tiered cache for aws #699

Merged
merged 6 commits into from
Jan 15, 2025

Conversation

conico974
Copy link
Contributor

As discussed in #621.
The new incremental cache work this way :

  • First it checks the local in memory LRU cache and that it's not expired ( default TTL is 0 to avoid issue with On Demand revalidation )
  • If found but expired, it checks DynamoDB metadata to check if the data has been updated somewhere else ( If it's not been updated it will return the locally retrieved entry )
  • Lastly it'll check S3 cache and populate the local LRU cache

It requires both an S3 Bucket and a DynamoDb table
It uses the same env variable as both the default S3 and Tag cache as well as 2 new optional env OPEN_NEXT_LOCAL_CACHE_TTL (default is 0) and OPEN_NEXT_LOCAL_CACHE_SIZE (default is 1000, in nbr of entries)

Warning

This implementation is NOT strongly consistent
If some error happens while writing to DDB, some instance may use outdated local data

Copy link

changeset-bot bot commented Jan 14, 2025

🦋 Changeset detected

Latest commit: 2f06186

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 Minor
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 Jan 14, 2025

Open in Stackblitz

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

commit: 2f06186

},
async set(key, value, isFetch) {
const revalidatedAt = Date.now();
await S3Cache.set(key, value, isFetch);
Copy link
Contributor

Choose a reason for hiding this comment

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

use Promise.allSetlled() to parallelize?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is on purpose actually, given how it works we have 3 choice for handling write error failure:

  • We could do as it is here, set on S3, then set on DDB, which means that if it fails in DDB, instance that don't have local cache will work as expected. ( But those with local cache will still serve outdated data )
  • We could first write in DDB and then S3, which means that in case S3 fail, new instance will fetch outdated data, and existing instance will fetch outdated data.
  • Or we could use allSettled but then the behavior will be unpredictable in case one of the 2 fails

I should have added a comment explaining this. One other thing we could do is to let the user chose the behavior they'd want.

I'll update and merge the PR tomorrow in case we should chose another option

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh you're right 👍
Thanks for explaining very clearly

Copy link
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

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

LGTM, a few nits

@conico974 conico974 merged commit eaa9ef8 into opennextjs:main Jan 15, 2025
3 checks passed
@github-actions github-actions bot mentioned this pull request Jan 10, 2025
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