【问题标题】:Access ILambdaContext in Lambda Entrypoint for dotnet serverless API在用于 dotnet 无服务器 API 的 Lambda 入口点访问 ILambdaContext
【发布时间】:2022-12-07 07:25:10
【问题描述】:

尝试获取 ILambdaContext 对象 - 下面的示例和用例。我正在使用点网 6

 public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction

    {
        internal static ILambdaContext Context;

        public override async Task<APIGatewayProxyResponse> FunctionHandlerAsync(APIGatewayProxyRequest request, ILambdaContext lambdaContext)
        {
            Context = lambdaContext;
            return await base.FunctionHandlerAsync(request, lambdaContext);
        }

        protected override void Init(IWebHostBuilder builder)
        {
            var variables = JsonConvert.SerializeObject(Context);
            //var variables = JsonConvert.Serliaze
            throw new Exception($"{variables}");
            var environment = "Beta";// arr[arr.Length - 1];


            //builder.UseStartup<Startup>();
            builder.ConfigureAppConfiguration((c, b) =>
            {
                b.AddJsonFile("appsettings.json");
                b.AddSystemsManager((source) =>
                {
                    var awsOptions = new AWSOptions();
                    awsOptions.Region = RegionEndpoint.EUWest1;
                    source.Path = $"/common";
                    source.AwsOptions = awsOptions;
                    source.ReloadAfter = TimeSpan.FromMinutes(5);
                });
                b.AddSystemsManager((source) =>
                {
                    var awsOptions = new AWSOptions();
                    awsOptions.Region = RegionEndpoint.EUWest1;
                    source.Path = $"/{environment}";
                    source.AwsOptions = awsOptions;
                    source.ReloadAfter = TimeSpan.FromMinutes(5);
                });
            }).UseStartup<Startup>();
        }
    }

我使用来自 here 的示例来尝试覆盖 FunctionHandlerAsync 入口点,但 Lambda 上下文为空。我也尝试过许多其他路径,但都失败了。

我的目标是从 lambda 上下文中获取别名以用作环境配置。我已经阅读了大部分互联网内容,但我仍然无法做到这一点。

【问题讨论】:

  • 这个 lambda 函数的目的是什么? InitFunctionHandlerAsync 之前调用,因此contextInit 方法期间不可用。这就是为什么你越来越空?你能解释一下重写 Init 方法的目的是什么吗?
  • 这是你的处理程序类吗?
  • 如果您尝试使用 Lambda 函数运行 Web 应用程序,那么您需要了解 Lambda 函数并非用于此目的。你能解释一下你到底想达到什么目的吗? @daveBM
  • @Chetan Init 应该在 FunctionHandlerAsync 之后被调用,因为处理程序是方法中的入口点。我什至尝试将 ILambdaContext 序列化为 json,然后将其打印出来,但它在 FunctionHandlerAsync 方法中为 null
  • @Chetan 这是一个无状态的 webapi,我已经在 Lambda 中运行了一段时间。我基本上是在尝试获取函数的别名 var arr = Context.InvokedFunctionArn.Split(':'); var env= arr[arr.Length - 1];其中 InvokedFunctionArn 是“arn:aws:lambda:Region:AccId:function:FunctionName:Production”。此函数由 ApiGateway 调用

标签: c# .net aws-lambda


【解决方案1】:

我刚刚对此进行了测试,您的示例运行良好。

这是一个使用“ASP.NET Core Web App”的 .Net 6“AWS Serverless Application”。

函数处理程序覆盖有效,我可以访问上下文。

【讨论】:

  • 好的,这里澄清一下。可以在 FunctionHandlerAsync 中访问 lambdaContext,我可以成功打印出 AwsRequestId 作为示例。但是,在 Init 方法中,存储的 lambdaConext 为空,我似乎无法检索 AwsRequestId。
【解决方案2】:

你可以利用:

ConcurrentDictionary<Guid, ILambdaContext>

您将向其添加 lambda 处理程序包装器,并在作用域结束时将其删除。

// MyLambdaWrapper.cs
using Amazon.Lambda.Core;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;

namespace MyNamespace;

public class MyLambdaWrapper
{
    private readonly ConcurrentDictionary<Guid, ILambdaContext> _contexts = new();

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped(_ => new ScopeContextIdentifier(Guid.NewGuid()));
        services.AddScoped<ILambdaContext>(serviceProvider =>
        {
            var scopeContextIdentifier =
                serviceProvider.GetRequiredService<ScopeContextIdentifier>();
            var contexts =
                serviceProvider
                    .GetRequiredService
                        <ConcurrentDictionary<Guid, ILambdaContext>>();
            var injected = contexts[scopeContextIdentifier.Guid];
            return injected;
        });
        services
            .AddSingleton<ConcurrentDictionary<Guid, ILambdaContext>>(_contexts);
    }

    public async Task Run
    (
        IServiceProvider serviceProvider, App app, Type handlerType
    )
    {
        Func<Stream, ILambdaContext, Task<Stream?>> func =
        async (inputStream, lambdaContext) =>
        {
            // ...
            using var scope = serviceProvider.CreateScope();
            using var _ =
                new ScopeContextManager(scope, lambdaContext, _contexts);
            // ...
        };
        // ...
    }
}

和经理:

// ScopeContextManager.cs
using Amazon.Lambda.Core;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;


namespace MyNamespace;

internal sealed record ScopeContextIdentifier(Guid Guid);

internal sealed class ScopeContextManager : IDisposable
{
    private readonly ConcurrentDictionary<Guid, ILambdaContext> _contexts;
    private readonly ScopeContextIdentifier _internalScopeContext;

    public ScopeContextManager
    (
        IServiceScope serviceScope,
        ILambdaContext lambdaContext,
        ConcurrentDictionary<Guid, ILambdaContext> ctx
    )
    {
        _internalScopeContext = serviceScope.ServiceProvider
            .GetRequiredService<ScopeContextIdentifier>();
        _contexts = ctx;
        _contexts.TryAdd(_internalScopeContext.Guid, lambdaContext);
    }

    public void Dispose()
    {
        _contexts.Remove(_internalScopeContext.Guid, out _);
    }
}

【讨论】:

    【解决方案3】:

    关闭这个,目前无法获取上下文

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 2019-12-12
      • 2020-08-12
      • 2019-08-25
      • 2018-08-27
      • 1970-01-01
      相关资源
      最近更新 更多