Skip to content

Feature request: add access method to coldStart field in the Utility class #3668

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

Closed
1 of 2 tasks
am29d opened this issue Feb 26, 2025 · 6 comments · Fixed by #3682
Closed
1 of 2 tasks

Feature request: add access method to coldStart field in the Utility class #3668

am29d opened this issue Feb 26, 2025 · 6 comments · Fixed by #3682
Assignees
Labels
commons This item relates to the Commons Utility completed This item is complete and has been merged/shipped feature-request This item refers to a feature request for an existing or new utility

Comments

@am29d
Copy link
Contributor

am29d commented Feb 26, 2025

Use case

I'd like to have a method that will return the current value of the coldStart field of the Utility class without changing the value. Right now both isColdStart and getColdStart changes the value when called. As mentioned in #3278 we can't access the flag without changing it.

Solution/User Experience

I propose to change isColdStart to return the coldStart value without changing it which would also reflect its meaning.

Alternative solutions

Change `coldstart` field to protected.

Acknowledgment

Future readers

Please react with 👍 and your use case to help us understand customer demand.

@am29d am29d added commons This item relates to the Commons Utility discussing The issue needs to be discussed, elaborated, or refined feature-request This item refers to a feature request for an existing or new utility labels Feb 26, 2025
@am29d am29d self-assigned this Feb 26, 2025
@am29d
Copy link
Contributor Author

am29d commented Feb 27, 2025

I am going forward and set the coldStart field to protected for now. We will eventually circle back and remove the Utility class in the future.

@am29d am29d added confirmed The scope is clear, ready for implementation and removed discussing The issue needs to be discussed, elaborated, or refined labels Feb 27, 2025
@am29d am29d moved this from Triage to Working on it in Powertools for AWS Lambda (TypeScript) Feb 27, 2025
@dreamorosi
Copy link
Contributor

The current design was built on the assumption that each utility instance (i.e. Logger) would access/visit that value only once per initialization. With that in mind, it made sense to make it this way.

I know this request comes related to the work in #3278, which now requires us to access the cold start value twice, so it makes sense to refactor.

Two non-invasive options would be:

  1. make this value protected so you can access it directly from the Logger
  2. make sure you're calling the sampling logic after the addContext, and then access the cold start value at this.powertoolsLogData.lambdaContext?.coldStart.

I think both are not great and kind of defeat the purpose of having that Utility class abstraction. For context, we added that class over 3 years ago in #484 as an early effort to consolidate common logic between core utilities in a shared parent class.

Despite this initial push however, the core utilities have evolved to have their own independent logic over time and we barely ever touched that Utility class. In hindsight, looking at current usage, this might've been a case of premature optimization

To move forward, I think we have two options, assuming we don't want to pursue any of the suboptimal ones above:

Option 1

Remove this Utility class entirely, and move back the logic into each core utility. In its current state this class only adds cognitive complexity to the mix and provides little deduplication value.

The two methods getColdStart() and isColdStart() could be consolidated, and the getDefaultServiceName() method is just an accessor, so in practice we'd only need two properties:

  • isColdStart
  • defaultServiceName
    and a method that flips it

Option 2

We keep the Utility class and we actually make it useful.

Specifically, we could implement new logic that actually keeps track of whether a certain invocation is a cold start or not based on the environment rather than on an internal state alone.

Right now, if for some reason you have two independent Logger instances, or are using Powertools in a compute environment that supports multiple requests at once, the cold start logic is completely broken since it relies on the order of access for the property for each instance of the class.

We could instead make the cold start scoped to a specific request and do something like this:

coldStartMap = new Map<string, boolean>();

public isColdStart() {
  const requestId = process.env._X_AMZN_REQUEST_ID;
  if (!requestId) {
    return true; // this is during init, so we it's THE cold start
  }
  if (this.coldStartMap.size === 0) {
    this.coldStartMap.set(requestId, true); // this is the first request being seen
    return true;
  }
  this.coldStartMap.set(requestId, false); // these are all the others
  return false;
}

This way we rely on the presence and value of _X_AMZN_REQUEST_ID and use it to keep a state of whether this is the first request we're seeing (aka a cold start) or if it's a subsequent one.

This logic would have to exist outside of the Logger instance and its parents, so in practice we'd have to create some shared context.


What do we think?

Btw I am okay also with making a quick change and make it protected to progress on the other issue, have a discussion here, and then go back to change if we agree on something.

@dreamorosi dreamorosi added discussing The issue needs to be discussed, elaborated, or refined and removed confirmed The scope is clear, ready for implementation labels Feb 27, 2025
@dreamorosi dreamorosi moved this from Working on it to Backlog in Powertools for AWS Lambda (TypeScript) Feb 27, 2025
@dreamorosi dreamorosi moved this from Backlog to Ideas in Powertools for AWS Lambda (TypeScript) Feb 27, 2025
@am29d
Copy link
Contributor Author

am29d commented Feb 27, 2025

I like your idea to broaden the scope of Utility and make it more useful. I will change the coldStart field to protected to unblock the other issue, and will address this issue in a separate PR.

@dreamorosi
Copy link
Contributor

On second thought, maybe we can just simplify it like this for now:

export class Utility {
  protected coldStart = true;
  protected readonly defaultServiceName: string = 'service_undefined';

  /**
   * Get the cold start status of the current execution environment.
   *
   * @example
   * ```typescript
   * import { Utility } from '@aws-lambda-powertools/commons';
   *
   * const utility = new Utility();
   * utility.isColdStart(); // true
   * utility.isColdStart(); // false
   * ```
   *
   * The method also flips the cold start status to `false` after the first invocation.
   */
  public getColdStart(): boolean {
    if (this.coldStart) {
      this.coldStart = false;

      return true;
    }

    return false;
  }

  /**
   * Validate that the service name provided is valid.
   * Used internally during initialization.
   *
   * @param serviceName Service name to validate
   */
  protected isValidServiceName(serviceName?: string): boolean {
    return typeof serviceName === 'string' && serviceName.trim().length > 0;
  }
}

and focus on something more impactful.

I think this is something we might want to revisit in the future still, but I would not keep it on the backlog.

@am29d am29d added the revisit-in-3-months Blocked issues/PRs that need to be revisited label Feb 28, 2025
@dreamorosi dreamorosi moved this from Ideas to Working on it in Powertools for AWS Lambda (TypeScript) Mar 3, 2025
@dreamorosi dreamorosi added confirmed The scope is clear, ready for implementation and removed discussing The issue needs to be discussed, elaborated, or refined revisit-in-3-months Blocked issues/PRs that need to be revisited labels Mar 3, 2025
@dreamorosi dreamorosi assigned dreamorosi and unassigned am29d Mar 3, 2025
@dreamorosi dreamorosi linked a pull request Mar 3, 2025 that will close this issue
@github-project-automation github-project-automation bot moved this from Working on it to Coming soon in Powertools for AWS Lambda (TypeScript) Mar 3, 2025
Copy link
Contributor

github-actions bot commented Mar 3, 2025

⚠️ COMMENT VISIBILITY WARNING ⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.

@github-actions github-actions bot added pending-release This item has been merged and will be released soon and removed confirmed The scope is clear, ready for implementation labels Mar 3, 2025
Copy link
Contributor

github-actions bot commented Mar 7, 2025

This is now released under v2.16.0 version!

@github-actions github-actions bot added completed This item is complete and has been merged/shipped and removed pending-release This item has been merged and will be released soon labels Mar 7, 2025
@dreamorosi dreamorosi moved this from Coming soon to Shipped in Powertools for AWS Lambda (TypeScript) Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
commons This item relates to the Commons Utility completed This item is complete and has been merged/shipped feature-request This item refers to a feature request for an existing or new utility
Projects
Development

Successfully merging a pull request may close this issue.

2 participants