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

nextjs-bucket-deployment function being killed by AWS Lambda #244

Open
jcharlesworthuk opened this issue Feb 21, 2025 · 0 comments
Open

Comments

@jcharlesworthuk
Copy link

jcharlesworthuk commented Feb 21, 2025

Hey, I've been facing an issue where the NextjsBucketDeployment lambda function just gets killed by AWS while uploading the assets to S3. No errors in the logs, no timeout, just ends. And it therefore doesn't sent the response back to CloufFormation which leaves the Cfn stack in the UPDATE_IN_PROGRESS state indefinitely. This is what I see in the logs for the lambda:

2025-02-20T23:04:00.507Z INIT_START Runtime Version: nodejs:20.v51 Runtime Version ARN: arn:aws:lambda:eu-west-2::runtime:xxxx
2025-02-20T23:04:00.826Z START RequestId: xxx-xxx-xxx Version: $LATEST
2025-02-20T23:04:00.828Z 2025-02-20T23:04:00.828Z xxx-xxx-xxx INFO { "event": { "RequestType": "Update", "ServiceToken": ... } }
2025-02-20T23:04:00.832Z 2025-02-20T23:04:00.832Z xxx-xxx-xxx INFO "Downloading zip"
2025-02-20T23:04:01.021Z 2025-02-20T23:04:01.021Z xxx-xxx-xxx INFO "Extracting zip"
2025-02-20T23:04:01.400Z 2025-02-20T23:04:01.400Z xxx-xxx-xxx INFO "Uploading objects to: mybucket"
2025-02-20T23:04:22.001Z END RequestId: xxx-xxx-xxx
2025-02-20T23:04:22.001Z REPORT RequestId: xxx-xxx-xxx Duration: 21174.22 ms Billed Duration: 21175 ms Memory Size: 3008 MB Max Memory Used: 149 MB Init Duration: 316.98 ms

It gets killed after "Uploading objects to: mybucket" and never returns a response to CloudFormation.

My usage is super simple just:

 const nextjs = new Nextjs(this, 'Nextjs', {
      nextjsPath: '../../frontend',
      domainProps: {
         domainName: props.domainName,
         certificate: props.certificate,
         hostedZone: props.hostedZone,
      }
);

I only have a handful of static assets (under 20).

I did some digging into the code and I believe the issue is with this uploadObjects() function:

async function uploadObjects({

for await (const filePathChunk of chunkArray(filePaths, 100)) {
    const putObjectInputs: PutObjectCommandInput[] = filePathChunk.map((path) => {
      const contentType = mime.lookup(path) || undefined;
      const putObjectOptions = getPutObjectOptions({ path, putConfig });
      const key = createS3Key({ keyPrefix, path, baseLocalDir });
      return {
        ContentType: contentType,
        ...putObjectOptions,
        Bucket: bucket,
        Key: key,
        Body: createReadStream(path),
      };
    });

    await Promise.all(putObjectInputs.map((params) => new Upload({ client: s3, params }).done()));
  }

I don't know a huge amount about parallelism in Lambda, but I suspect it is running out of promises or something and AWS is killing the function silently.

By modifying the above code to chunkArray(filePaths, 10) and adding queueSize: 10 to the upload function it works again (I believe the default queueSize in @aws-sdk/lib-storage is 3)

await Promise.all(putObjectInputs.map((params) => new Upload({ client: s3, params, queueSize: 10 }).done()));

The above works for me but honestly I'm not 100% sure I'm not just masking some other issue.

Anyway hopefully someone who knows more about this than me can find a better solution to the issue, and I'll leave the above in case anybody else comes across a problem with CloudFormation getting stuck in UPDATE_IN_PROGRESS due to the Custom::NextjsBucketDeployment custom resource.

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

No branches or pull requests

1 participant