-
Notifications
You must be signed in to change notification settings - Fork 46
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
fix: Initial support for open-next v2 and ISR #125
fix: Initial support for open-next v2 and ISR #125
Conversation
@kevin-mitchell, thanks for starting on this! One way to test this would be to deploy the Next.js 13 App Dir Example from Vercel here and ensure everything works as expected. I think that example showcases many features we'd want to test against. Not sure about pages directory as I don't have as much experience with those features. |
Current version of this branch is mainly working, however using the Next.js demo when I attempt to navigate through the client context page I'm getting an error about a missing key in the cache. clicking "electronics" on this page And I think this is the corresponding error. I have to look to see what is wrong here. edit: the below error I think is actually expected / working as intended because this exception is caught (see: async getFetchCache(key: string) {).
I'm sort of guessing the real error here is actually from the request trying to fetch from the server:
|
I switched to using the explicit examples called out here: https://github.com/serverless-stack/open-next/blob/main/README.md#example I could use some input on the CloudFront Distribution setup. What I have "works" and seems to have the same behavior as SST (without digging too deep - IMHO a 404 should be cached, but both the current branch here as well as SST returns a "Error from cloudfront" x-cache header), but I should look closer to see what the "right" thing to do is. That said, SOMETHING isn't tuned well because the SSG pages are serving very old Cloudfront caches. I'm not sure if this issue predates this PR because I never actually have used I'm copy / pasting some notes I took, although the 404 is fixed as noted above by removing the origin group and just replacing it will a direct call to the web server. IssuesI have never (successfully) been able to use this CDK construct / project, so I’m not sure which of these are new, which are related to the changes in this PR, and Error related to SST in logs for Server Function
Not sure why this is happening, but it seems “random” (most requests don’t see it). Cache isn’t behaving ideally for SSG
Maybe this is working as intended, but it seems like the TTL is either too long or a cache invalidation should happen as part of the deployment, OR some documentation somewhere should say “you have to invalidate the cache yourself on deployment.” Or I’m just missing something (very possible) 404 pages seem to serve 403 XML response from S3NOTE THIS WAS AT LEAST PARTIALLY FIXED - I removed the default origin group with the S3 fallback with a direct call to the Lambda server which is I believe what SST also does. I’m not 100% this is what’s actually happening, maybe it’s not S3. But it at least seems involved. One header is “Server: AmazonS3” I’m not sure how this is intended to work, or if this is coming from the cache bucket because the cache bucket is misconfigured, etc.
Note that the server lambda is triggered, and seems to generate the correct response - so it’s something about either the Cloud Front Distribution or something else about the setup that’s causing the wrong result to be sent. In other words, the result of
|
@kevin-mitchell, the "Error related to SST in logs for Server Function" doesn't make sense to me. There should be no code related to SST in this construct. Were you referring to SST's construct? |
Could this be connected to the change in the default origin group code I commented on? |
@bestickley right this is why I called it out. I'm not sure where it came from. I'll try to look with fresh eyes today. Edit: and nope, I was referring to this construct, the pr I've got open. I figured perhaps open-next might reference it somewhere but couldn't see where. |
@kevin-mitchell, any other outstanding issues? Do all routes work on the test website? |
@bestickley in short, yes, there are still outstanding issues with the test website(s). It's taken me so long to reply because I'm trying to figure out what is actually an issue with this PR vs what is a prior issue / incompatibility between this project and the Vercel app playground / open-next example sites. More details below, but I wonder if it might be a good idea to do something like:
Below are some more details on specific issues I've hit, but again in some cases I'm not certain it's not just an issue with my local setup and how I'm deploying, etc. So take these with a grain of salt I'm just not sure if they are new issues, or old issues. Looking at my PR, honestly there aren't all that many changes so I suspect in the end even if this was landed as is it would be in better shape than before, BUT here are the issues I'm aware of: General
open-next example
Vercel app playground
|
@kevin-mitchell, I think 1 from above makes sense, if you can create a PR for that, I think we should get it merged so newcomers aren't confused why this construct isn't working out of the box. I'm work with incrementally working on v2 support on this PR. |
There was quite a bit of discussion about this, and it's still not the best solution for all situations. For now it should fix an issue where direct requests to static assets (e.g. files in the `/public` directory) cause a 404. jetbridge#125 (comment)
I'll be on tomorrow morning PST. |
@kevin-mitchell |
@kevin-mitchell #129, this will affect the fallback stuff we discussed. |
@kevin-mitchell, I'm planning on resolving the remaining issues and then resolving the origin group fallback behavior issue in #129. Server actions are an important feature I think we should support. I'll keep you updated. |
RE: Steaming isn't supported - good, I won't worry about having broken it then :) RE: Error in logs - I haven't been able to reproduce. I suspect it's a concurrency issue with Lambda / AWS, though I'm not sure why I would have hit the limit. RE: Invaliding "/*" on deployment - previously, as @bestickley mentioned perhaps this function was handled by invalidating the S3 "assets" bucket contents on deployment. Now this SSG content is inside a different bucket so at least to me it appears these aren't invalidated. I added a new config parameter to allow the full invalidation to be skipped, but defaulted to invalidating |
@kevin-mitchell, on 2nd thought, how about we get this branch merged, then we can address origin group issue in another PR. I want you to "get credit" for this great work. I will test out your changes on this branch tomorrow morning with the open-next test app and if everything looks good I'll merge it. |
Updates the server handler to include cache bucket configuration, **which is likely not correct as I'm just using the static asset bucket temporarily**. I need to look at how SST does this and what the spirit of this should be, e.g. if a separate bucket would be more appropriate, a folder, etc. This also adds the ISR handling logic. I haven't actually tested this yet (am not 100% sure how to). **This is a WIP**.
This isn't working 100% quite yet. I am testing with https://github.com/vercel/app-playground - with these changes I'm able to deploy but I need to populate the cache bucket name in another function env I believe. I also haven't really gotten into the details of looking to see if messages are actually being sent to the queue, etc. The main difference here is some cleanup, and I added the separate bucket for the cache.
* added a new constant so we can keep the default memory size uniform across lambda functions * Allow the cache bucket to be passed in as a construct property if user wants to supply their own s3 cache bucket
I'm not at all confident this is the "right" thing to do here, but without this I was having issues with S3 fallback serving 403s. It's entirely likely this is a shortsighted change and in reality I need to fix something on the S3 bucket in terms of how it handles 404 / 403s. See SST implementation here: https://github.com/serverless-stack/sst/blob/b56c2ea021290211c72841c605cec58579ef3591/packages/sst/src/constructs/SsrSite.ts#L1053-L1058
I now see why this was in place originally. It still doesn't work, but I'd rather leave it as it is for now. SST creates additional behaviors in CloudFormation at deploy time, basically iterating through all of the files in the root of `/public` and creating a rule that routes to the static assets bucket for these matches: https://github.com/serverless-stack/sst/blob/b56c2ea021290211c72841c605cec58579ef3591/packages/sst/src/constructs/SsrSite.ts#L1113 ``` protected addStaticFileBehaviors() { const { cdk } = this.props; // Create a template for statics behaviours const publicDir = path.join( this.props.path, this.buildConfig.clientBuildOutputDir ); for (const item of fs.readdirSync(publicDir)) { const isDir = fs.statSync(path.join(publicDir, item)).isDirectory(); this.distribution.addBehavior(isDir ? `${item}/*` : item, this.s3Origin, { viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS, allowedMethods: AllowedMethods.ALLOW_GET_HEAD_OPTIONS, cachedMethods: CachedMethods.CACHE_GET_HEAD_OPTIONS, compress: true, cachePolicy: CachePolicy.CACHING_OPTIMIZED, responseHeadersPolicy: cdk?.responseHeadersPolicy, }); } } ``` This is a bit more complicated with the pitfall of hitting the maximum number of behaviors (25 apparently). > First do no evil.
There was quite a bit of discussion about this, and it's still not the best solution for all situations. For now it should fix an issue where direct requests to static assets (e.g. files in the `/public` directory) cause a 404. jetbridge#125 (comment)
bbac591
to
94490cf
Compare
I rebased on main to prep for a potential landing but somehow lost the changes in NextjsBuild. Also a typo fix.
@kevin-mitchell, in my testing, I've run across an issue where the const fn = new Function(scope, 'ServerHandler', {
memorySize: functionOptions?.memorySize || DEFAULT_LAMBA_MEMORY,
timeout: functionOptions?.timeout ?? Duration.seconds(10),
runtime: LAMBDA_RUNTIME,
handler: path.join('index.handler'),
code,
// prevents "Resolution error: Cannot use resource in a cross-environment
// fashion, the resource's physical name must be explicit set or use
// PhysicalName.GENERATE_IF_NEEDED."
functionName: Stack.of(this).region !== 'us-east-1' ? PhysicalName.GENERATE_IF_NEEDED : undefined,
...functionOptions,
// `environment` needs to go after `functionOptions` b/c if
// `functionOptions.environment` is defined, it will override
// CACHE_* environment variables which are required
environment,
}); UPDATE: I went ahead and resolved this issue. |
I've verified that ISR works with the Next.js App Router example! All other pages seem to be working too except for loading. @kevin-mitchell, was loading working for you in App Router example app? UPDATE: I think this is happening because open-next's cache doesn't respect the |
As far as I know it's working for me - at least based on my understanding. Hopefully this gif either looks "right" or "wrong" - but I just deployed what's out there and this is what I'm seeing. |
Awesome, if you want to publish a new (major?) version then let's go for it whenever you're ready. |
FYI I'm heading out to do some backcountry camping this afternoon. Normally I'd try to make sure I was around in case any fast-follow type fixes were needed, but I'll be "out of pocket" as they say from this afternoon with limited connectivity options. |
@kevin-mitchell, no worries! Enjoy your trip! |
@kevin-mitchell, I'm glad the loading is working for you! It's not working for me or @khuezy. Not sure why, but not a show stopper IMO. |
See: #119
Updates the server handler to include cache bucket configuration, which is likely not correct as I'm just using the static asset bucket temporarily. I need to look at how SST does this and what the spirit of this should be, e.g. if a separate bucket would be more appropriate, a folder, etc.
This also adds the ISR handling logic. I haven't actually tested this yet (am not 100% sure how to).
This is a WIP.
Fixes #119
TODO
Confirm if we should make a new bucket for cache or use an existing bucketConfirm permissions appropriate for this bucket between nextjs server and the bucketMake sure I didn't break anything along the way