AWS Lambda NodeJS区域设置/变量隔离

时间:2017-05-19 07:49:35

标签: amazon-web-services aws-lambda

关注aws-lambda中可重用变量的潜在问题。

用户的区域设置作为
传递 Browser cookies => AWS API Gateway => Lambda (NodeJS 6.10)

在服务器端,使用类中的静态变量实现本地化。为了清晰起见,提供typescript代码,但可以在纯ECMAScript中完成。

Module Language.ts

export default class Language
{
    public static Current: LanguageCode = LanguageCode.es;
}

静态Language.Current变量用于应用程序的不同部分以进行手动本地化,并且在客户端(react + redux)完美运行。

Lambda函数

import {APIGatewayEvent, Context, Callback} from 'aws-lambda';
import Language from './pathToModule/Language.ts';

export const api = function(event: APIGatewayEvent, context: Context, callback: Callback)
{
    Language.Current = event.headers.cookie.locale;

    // do the logic here
}

潜在问题

根据AWS文档,NodeJS实例可以重用于不同的请求。这意味着必须考虑着名的并发问题,例如

  • 用户1 调用lambda函数。语言环境设置为英语
  • 并行 user 2 调用相同的lambda实例。本地更改为西班牙语
  • 用户1 代码继续并从共享模块Language读取修改后的(错误的)语言环境变量。

你如何解决这个问题?

为方便起见,只有一个地方可以更改区域设置。据我所知,所有着名的i18n npm软件包(i18next,i18n,yahoo i18n等)都存在同样的问题。

2 个答案:

答案 0 :(得分:1)

Lambda函数的最佳实践之一是尝试不编写维护状态的代码。

在这里,您将根据初始请求初始化区域设置并将其应用于所有将来的请求,即使在基于服务器的代码上也存在缺陷,忘记服务器更少。

要解决此问题,您需要为每个请求初始化本地化库,或者至少维护内存中的懒惰映射,您可以使用当前请求的语言环境来实现所需的本地化。

答案 1 :(得分:0)

有几种解决方案:

  1. 节点JS容器仅在function process is finishedcallbackerror发生后)重复使用(感谢@idbehold)。因此,每个函数调用总会有一个唯一的上下文。

  2. 重构代码并传回一个语言环境变量并强制执行(@Yeshodhan Kulkarni建议)。
    例如,返回一个函数作为中间结果,并在调用结果之前使用它 var localizableResult = ...;
    var result = localizableResult.Localize(requestedLocale)

  3. 如果需要为其他项目使用本地堆栈(一种线程上下文),则有一个npm包node-continuation-local-storage

  4. Case 1使全局变量用于当前语言环境非常简单。