当处理函数退出时,aws-lambda中的goroutines会发生什么?

Jan*_*Jan 5 go node.js aws-lambda

问题起源于:已经发送响应后,我可以在后台执行多少工作。例如:我只想接收数据,告诉客户端“确定”,然后进行一些可能需要一些时间的数据库操作。

package main

import (
        "fmt"
        "context"
        "github.com/aws/aws-lambda-go/lambda"
)

type MyEvent struct {
        Name string `json:"name"`
}

func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
        go RecordQuery(name)
        return fmt.Sprintf("Hello %s!", name.Name ), nil
}

func RecordQuery(name MyEvent) {
        // insert stuff in the database, mark user active,
        // log activity, etc..
}

func main() {
        lambda.Start(HandleRequest)
}
Run Code Online (Sandbox Code Playgroud)

我们可以依靠goroutine来完成其工作吗?

Jan*_*Jan 5

事实证明,我们不能假设代码会运行。

示例实现:

var alreadyLogging bool

func RecordQuery(name MyEvent) {
    if alreadyLogging {
        return
    }
    alreadyLogging = true
    for i := 0; ; i++ {
        time.Sleep(time.Second)
        log.Print("Still here ", i)
    }
}
Run Code Online (Sandbox Code Playgroud)

行为:只要运行 lambda 的容器正在接收请求,就会执行 goroutine。但是当容器不再接收请求时,所有代码都会停止。

可能的输出(在 cloudwatch 中):

2018/05/16 08:50:46 Still here 70
2018/05/16 08:50:47 Still here 71
2018/05/16 08:50:48 Still here 72
2018/05/16 08:50:49 Still here 73
2018/05/16 08:51:36 Still here 74
2018/05/16 08:51:37 Still here 75
2018/05/16 08:51:38 Still here 76
Run Code Online (Sandbox Code Playgroud)

请注意,在 Node.js 编程模型中,您可以在调用回调后立即请求 AWS Lambda 冻结进程,即使事件循环中存在事件:上下文对象属性

看到这个 API 的一些用例会很有趣。

更新:在 Node.js 中,一旦你连接到数据库,你就会有一个非空的事件队列。这就是此设置可用的原因。

  • 对于需要先发送响应,然后执行更多工作的情况,该方法是让第一个函数异步调用第二个函数(Lambda 称之为“事件”调用),该调用会立即返回,仅抛出错误诸如访问被拒绝或没有此类功能之类的事情。Lambda 会丢弃其最终输出,但如果运行时发生错误,则会重试两次。 (2认同)