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

Make AbstractAspNetCoreFunction.Init() async #702

Closed
2 tasks done
damianh opened this issue Jul 20, 2020 · 8 comments
Closed
2 tasks done

Make AbstractAspNetCoreFunction.Init() async #702

damianh opened this issue Jul 20, 2020 · 8 comments
Labels
feature-request A feature should be added or improved. module/lambda-client-lib p3 This is a minor priority issue queued

Comments

@damianh
Copy link
Contributor

damianh commented Jul 20, 2020

Make this method async:

protected virtual void Init(IWebHostBuilder builder) { }

Describe the Feature

When initializing a webhost it is desirable to be able to load configuration asynchronously. For example, from Secrets Manager or Parameter Store. As this method is Sync, one is forced to use the nasty GetAwaiter().GetResult() when calling async APIs from within this methods.

This has a bit of knock on effect, however the function handler:

public virtual async Task<TRESPONSE> FunctionHandlerAsync(TREQUEST request, ILambdaContext lambdaContext)
{
if (!IsStarted)
{
Start();
}

... is already async so this change is entirely possible.

Is your Feature Request related to a problem?

More of a quality-of-life improvement.

Proposed Solution

  • Add an InitAsync() methods so it's not breaking.
  • Call InitAsync() before calling Init() - users should only override one but if they override both things should still work.
  • Optional - add [Obsolete("..", false)] attribute to Init()

Describe alternatives you've considered

Currently using GetAwaiter().GetResult() which is not desirable, especially when already in an async context (via the function handler).

Additional Context

Real world usage - loading config from Secrets Manager and Paramater Store.

Marking is as potentially breaking, though making it non-breaking would be preferable.

Environment

  • 👋 I may be able to implement this feature request
  • ⚠️ This feature might incur a breaking change

This is a 🚀 Feature Request

@damianh damianh added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Jul 20, 2020
@normj
Copy link
Member

normj commented Jul 20, 2020

This is a valid feature request and the proposed solution does not cause a breaking change. I would be willing to take in a PR for this otherwise I will get to it when I can.

@NGL321 NGL321 removed the needs-triage This issue or PR still needs to be triaged. label Jul 22, 2020
@damianh
Copy link
Contributor Author

damianh commented Jul 25, 2020

I've taken a look and it appears it won't be possible without a breaking change. The default mechanism to intitialize the aspnet core webhost is calling Start() from a constructor which will always be synchronous.

protected AbstractAspNetCoreFunction(StartupMode startupMode)
{
_startupMode = startupMode;
if (_startupMode == StartupMode.Constructor)
{
Start();
}
}

Ultimately Init() is called via here:


... which is inside a sync action that comes from IHostBuilder.ConfigureWebHostDefaults() of which whose API you don't have control over.

The only thing I can think of is to add nother virtual that invoked only if the StartupMode is set to FirstRequest and invoke it from within:
https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.AspNetCoreServer/AbstractAspNetCoreFunction.cs#L433-L436

Something like:

if (!IsStarted)
{
    await PreInitAsync();
    Start();
}

To be honest, I don't understand why one startup mode would have advantage or disadvantage over the other. In terms of a lambda lifecycle, it's only ever going to be effectively initialized on first request.

@mungojam
Copy link

I've hit a similar thing with APIGatewayProxyFunction since I want to do an async operation during the PostMarshallResponseFeature() abstract call but can't do it properly because it isn't async

@damianh
Copy link
Contributor Author

damianh commented Dec 27, 2020

Hi Norm, sorry dropped the ball the related PR #708. Had a chance to look at over the holidays and on reflecion I think adding yet another virtual member PreInitAsycn doesn't make things simpler for the end user. They'd probably end up writing code like:

private IConfiguration _config;

public overide async Task PreInitAsync()
{
	_config = await LoadConfigAsync();
}

public overide void Init(IWebHostBuilder builder)
{
	builder.UseConfiguration(_config);
}

I think this would preferable:

public overide async InitAsync(IWebHostBuilder builder)
{
	var config = await LoadConfigAsync();
	builder.UseConfiguration(config);
}

However, if people are not doing async work, they'll now be forced to return Task.CompletedTask ugh.

I'm also not happy with the oxymoronic name.

@github-actions
Copy link
Contributor

We have noticed this issue has not received attention in 1 year. We will close this issue for now. If you think this is in error, please feel free to comment and reopen the issue.

@github-actions github-actions bot added the closing-soon This issue will automatically close in 4 days unless further comments are made. label Dec 28, 2021
@mungojam
Copy link

Still relevant

@github-actions github-actions bot removed the closing-soon This issue will automatically close in 4 days unless further comments are made. label Dec 29, 2021
@ashishdhingra
Copy link
Contributor

Needs review. @normj Please check if this is still relevant.

@ashishdhingra ashishdhingra added needs-review p2 This is a standard priority issue labels Dec 27, 2022
@ashishdhingra ashishdhingra added p3 This is a minor priority issue queued and removed needs-review p2 This is a standard priority issue labels May 12, 2023
@damianh damianh closed this as completed Oct 11, 2023
@github-actions
Copy link
Contributor

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. module/lambda-client-lib p3 This is a minor priority issue queued
Projects
None yet
Development

No branches or pull requests

5 participants