awslabs / llrt

LLRT (Low Latency Runtime) is an experimental, lightweight JavaScript runtime designed to address the growing demand for fast and efficient Serverless applications.
Apache License 2.0
8.04k stars 355 forks source link

Bug: unable to import 2 AWS SDK clients at the same time. #380

Closed dreamorosi closed 4 months ago

dreamorosi commented 4 months ago

When running the following code on v0.1.13-beta:

import { CognitoIdentityProviderClient } from '@aws-sdk/client-cognito-identity-provider';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';

const cognitoIdpClient = new CognitoIdentityProviderClient({});
const ddbDocClient = DynamoDBDocumentClient.from(new DynamoDBClient({}));

export const handler = async (event: any) => {
  console.log('event', event);
};

I get this error:

TypeError: not an object
at all (native)
INIT_REPORT Init Duration: 42.39 ms     Phase: init     Status: error   Error Type: Runtime.ExitError
TypeError: not an object
at all (native)
INIT_REPORT Init Duration: 403.65 ms    Phase: invoke   Status: error   Error Type: Runtime.ExitError

All these clients are set as externalModules and thus my function is using the ones bundled in the runtime.

If I remove one and leave the other (i.e. only DynamoDBClient or only CognitoIdentityProviderClient) then the function runs normally.

As far as I can tell, the issue seems to appear whenever importing two AWS SDK clients in the same bundle and it's not specific to these above. I have tried also other combinations like @aws-sdk/client-secrets-manger + @aws-sdk/client-cognito-identity-provider and I get the same error.

Below is my fairly basic CDK architecture, which shows how I am adding LLRT:

```ts import { Stack, type StackProps, CfnOutput } from "aws-cdk-lib"; import { Construct } from "constructs"; import { Architecture, Runtime } from "aws-cdk-lib/aws-lambda"; import { NodejsFunction, OutputFormat, type NodejsFunctionProps, } from "aws-cdk-lib/aws-lambda-nodejs"; class LlrtFunction extends NodejsFunction { public constructor( scope: Construct, id: string, props: Omit ) { const architecture = props.architecture ?? Architecture.ARM_64; const cacheDir = `cdk.out/llrt-cache/latest/${architecture}`; const binaryUrl = `https://github.com/awslabs/llrt/releases/latest/download/llrt-lambda-${architecture}.zip`; const { bundling, ...rest } = props; super(scope, id, { ...rest, runtime: Runtime.NODEJS_20_X, bundling: { target: "es2020", format: OutputFormat.ESM, commandHooks: { beforeBundling: () => [], beforeInstall: () => [], afterBundling: (input, output) => [ `if [ ! -e ${input}/${cacheDir}/bootstrap ]; then mkdir -p ${input}/${cacheDir} cd ${input}/${cacheDir} curl -L -o llrt_temp.zip ${binaryUrl} unzip llrt_temp.zip rm -rf llrt_temp.zip fi`, `cp ${input}/${cacheDir}/bootstrap ${output}/`, ], }, externalModules: [ "@aws-sdk/client-cloudwatch-events", "@aws-sdk/client-cloudwatch-logs", "@aws-sdk/client-cognito-identity", "@aws-sdk/client-cognito-identity-provider", "@aws-sdk/client-dynamodb", "@aws-sdk/client-eventbridge", "@aws-sdk/client-kms", "@aws-sdk/client-lambda", "@aws-sdk/client-s3", "@aws-sdk/client-secrets-manager", "@aws-sdk/client-ses", "@aws-sdk/client-sfn", "@aws-sdk/client-sns", "@aws-sdk/client-sqs", "@aws-sdk/client-ssm", "@aws-sdk/client-sts", "@aws-sdk/client-xray", "@aws-sdk/credential-providers", "@aws-sdk/lib-dynamodb", "@aws-sdk/s3-request-presigner", "@aws-sdk/util-dynamodb", "@smithy", "uuid", ], }, }); // @ts-expect-error this.node.defaultChild.addPropertyOverride("Runtime", "provided.al2023"); } } export class TestLlrtStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const handler = new LlrtFunction(this, "Handler", { entry: "functions/docdb.ts", architecture: Architecture.ARM_64, }); new CfnOutput(this, "HandlerArn", { value: handler.functionArn, }); } } ```

As you can see the error is fairly cryptic so I can't provide any other info, but if you need more details feel free to reach out.

richarddavison commented 4 months ago

We have examples running s3 and dynamo at the same timme. Thanks for reporting, taking a look!

richarddavison commented 4 months ago

Thanks for the report. I can confirm that there was regression introduced when the Runtime Interface Client was ported to rust. Fix is coming up!

richarddavison commented 4 months ago

Fixed by https://github.com/awslabs/llrt/releases/tag/v0.1.14-beta