opennextjs / opennextjs-cloudflare

Open Next.js adapter for Cloudflare
https://opennext.js.org/cloudflare
MIT License
281 stars 6 forks source link

Cache support #105

Open vicb opened 3 days ago

vicb commented 3 days ago

Cache support.

This is a big chunk of work that should be split into multiple sub-tasks when we start the work.

References:

AWS uses multiple components for the cache:

This task is about providing a cache (incremental + tag) on the cloudflare infrastructure.

We have started to explore multiple possibles solutions using:

conico974 commented 1 day ago

If you plan on reusing the aws cache handler as it is i can give some advice. The 3 component we have can easily be overrided

S3 storage

For the S3 storage ( the incremental cache and the fetch cache ) it should be the easiest and the obvious choice seems to be KV. Here is the aws implementation for context https://github.com/opennextjs/opennextjs-aws/blob/main/packages/open-next/src/cache/incremental/s3.ts. You'll just need to provide something that implement the IncrementalCache interface The cache also needs to be populated at build time

Queue

The role of the queue is for ISR revalidation, when a page is marked as stale, the queue component will be called. For this one there is an easy and a more complex but better implementation.

For the easy one, you don't need any other component you just do exactly the same thing as in the run locally example for the dev/queue.ts component : https://opennext.js.org/aws/contribute/local_run This solution has a drawback, it doesn't handle deduplication. Multiple user reaching a stale page would trigger multiple revalidation

For the more complex solution, i'm not sure, but it seems that durable object could be a way to go The message that you get include a MessageDeduplicationId, it is computed in a way that there is a finite number of id (defined by this env variable MAX_REVALIDATE_CONCURRENCY, default is 10) and every route will always output the same id. This could allow to spawn MAX_REVALIDATE_CONCURRENCY durable object that would then need to handle deduplication and trigger the revalidation in the same way as the easy one. Not sure if a cloudflare queue could be used this way.

Tag cache (DynamoDB)

It is only used for revalidateTag or revalidatePath

Really not sure about this one, it is heavily geared toward DynamoDB to take full advantage of it. If used as it is now the only component that i could see working for this would be D1. For reference here is the default aws implementation : https://github.com/opennextjs/opennextjs-aws/blob/main/packages/open-next/src/cache/tag/dynamodb.ts It also needs to be prepopulated at build time

I also have plan to offer an alternative way to query for the tag cache (that is closer to the next implementation in the default handler), but that means having to query for a bunch of tags for every get request

These 3 are also used by the experimental cache interceptor that avoid having to reach the server to serve ISR/SSG route.

vicb commented 1 day ago

Thank you so much for the super valuable info on those github issues/tasks. ❤️