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

Long execution time caused by callbackWaitsForEmptyEventLoop=true on AWS Stream #264

Open
garfieldnate opened this issue Sep 16, 2024 · 6 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@garfieldnate
Copy link

Feature Request

We needed to set callbackWaitsForEmptyEventLoop to false for our use-case; without this, our lambda invocations were taking 30s instead of 8ms, so it's a huge deal for us.

It was a bit difficult to figure out how to access and modify the AWS context object, so I wanted to share our solution here for others to use in the future:

import {
  type BinarySettings,
  type ILogger,
  ServerlessAdapter,
} from "@h4ad/serverless-adapter";
import {
  type AWSStreamContext,
  AwsStreamHandler,
} from "@h4ad/serverless-adapter/lib/handlers/aws";

// Extend AwsStreamHandler to access the context object
class CustomAwsStreamHandler<TApp> extends AwsStreamHandler<TApp> {
  protected onReceiveRequest(
    log: ILogger,
    event: APIGatewayProxyEventV2,
    context: AWSStreamContext,
    binarySettings: BinarySettings,
    respondWithErrors: boolean,
  ): void {
    super.onReceiveRequest(
      log,
      event,
      context,
      binarySettings,
      respondWithErrors,
    );

    context.context.callbackWaitsForEmptyEventLoop = false;
  }
}

// set the stream handler on the adapter
export const handler = ServerlessAdapter.new(app)
  .setHandler(new CustomAwsStreamHandler())
  ...
  .build();
@garfieldnate garfieldnate added the enhancement New feature or request label Sep 16, 2024
@H4ad
Copy link
Owner

H4ad commented Sep 16, 2024

You can call this function and you will have access to the context and the event:

/**
* Get the reference to the event created by the serverless trigger or context created by the serverless environment.
*
* @example
* ```typescript
* import type { ALBEvent, Context } from 'aws-lambda';
*
* // inside the method that handles the aws alb request.
* const { event, context } = getCurrentInvoke<ALBEvent, Context>();
* ```
*
* @breadcrumb Core / Current Invoke
* @public
*/
export function getCurrentInvoke<TEvent = any, TContext = any>(): CurrentInvoke<

Are you using PromiseResolver or CallbackResolver?

@garfieldnate
Copy link
Author

🤔 Where would I call this function? Our entire handler creation looks like this:

export const handler = ServerlessAdapter.new(app)
  .setFramework(new ExpressFramework())
  .setHandler(new CustomAwsStreamHandler())
  .setResolver(new DummyResolver())
  .addAdapter(new ApiGatewayV2Adapter())
  .build();

This is following the documentation, which states that only DummyResolver is needed for streaming. We are not using CallbackResolver or PromiseResolver.

@H4ad
Copy link
Owner

H4ad commented Sep 16, 2024

Oh, I got it, I didn't see you were using AWS Stream Handler.

Hm... in this case, I think is worthy to have a flag to control this behavior, I'm suspect you have something in your event loop that makes the lambda keep alive for that amount of time but since resolving the promise is not enough, having that flag always false should be good.

Thanks for reporting this, I will probably add a option to customize that value in the future, and in a breaking change, I will try to make it default to false always to avoid these kind of issues.

@H4ad H4ad changed the title Document how to access the AWS handler context object Long execution time caused by callbackWaitsForEmptyEventLoop=true on AWS Stream Sep 16, 2024
@H4ad H4ad added the bug Something isn't working label Sep 16, 2024
@garfieldnate
Copy link
Author

That is wonderful, thank you!

Yes, we clearly have some DB connections or something that aren't getting closed. We always used this setting with the non-streaming API, so we just needed a way to continue using it.

H4ad added a commit that referenced this issue Sep 18, 2024
feat(aws-stream-handler): add flag to customize callbackWaitsForEmptyEventLoop (#264)
@H4ad
Copy link
Owner

H4ad commented Sep 21, 2024

Just to let you know, I released a new version with the flag to make callbackWaits to false, see more: https://serverless-adapter.viniciusl.com.br/docs/main/handlers/aws#my-execution-is-taking-too-long

@garfieldnate
Copy link
Author

Wow, thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants