登录
首页 >  Golang >  Go问答

func init() 与 func main() 用于初始化 AWS Lambda 处理程序中的全局状态

来源:stackoverflow

时间:2024-04-19 15:33:33 467浏览 收藏

目前golang学习网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《func init() 与 func main() 用于初始化 AWS Lambda 处理程序中的全局状态》,也希望能帮助到大家,如果阅读完后真的对你学习Golang有帮助,欢迎动动手指,评论留言并分享~

问题内容

查看官方 go 中的 aws lambda 函数处理程序 文档中的使用全局状态部分 https://docs.aws.amazon.com/lambda/latest/dg/golang-handler.html

建议在 func init() 中初始化所有全局状态 即我们想要在多个 lambda 调用之间共享的任何包级别变量都位于此处。

我的理解是,每次 lambda 容器启动(即冷启动)时都会完成一次初始化。

我的问题是,是否可以使用 func main() 而不是 func init() 来执行相同的操作。

使用 func init() 基本上使我的处理程序函数 (func lambdahandler) 由于 func init() 运行的副作用而无法进行单元测试。

func init() 代码移至 func main() 似乎可以轻松解决此问题。

使用 func main()func init() 是否有任何副作用

代码示例

使用 func init()

package main
 
import (
        "log"
        "github.com/aws/aws-lambda-go/lambda"
        "github.com/aws/aws-sdk-go/aws/session"
        "github.com/aws/aws-sdk-go/service/s3"
        "github.com/aws/aws-sdk-go/aws"
)
 
var invokecount = 0
var myobjects []*s3.object
func init() {
        svc := s3.new(session.new())
        input := &s3.listobjectsv2input{
                bucket: aws.string("examplebucket"),
        }
        result, _ := svc.listobjectsv2(input)
        myobjects = result.contents
}
 
func lambdahandler() (int, error) {
        invokecount = invokecount + 1
        log.print(myobjects)
        return invokecount, nil
}
 
func main() {
        lambda.start(lambdahandler)
}

对比

使用 func main()

package main
 
import (
        "log"
        "github.com/aws/aws-lambda-go/lambda"
        "github.com/aws/aws-sdk-go/aws/session"
        "github.com/aws/aws-sdk-go/service/s3"
        "github.com/aws/aws-sdk-go/aws"
)
 
var invokeCount = 0
var myObjects []*s3.Object
 
func LambdaHandler() (int, error) {
        invokeCount = invokeCount + 1
        log.Print(myObjects)
        return invokeCount, nil
}
 
func main() {
        svc := s3.New(session.New())
        input := &s3.ListObjectsV2Input{
                Bucket: aws.String("examplebucket"),
        }
        result, _ := svc.ListObjectsV2(input)
        myObjects = result.Contents

        lambda.Start(LambdaHandler)
}

正确答案


我会提出以下建议(我们在很多 go lambda 中都成功使用了它)。

ma​​in.go

[...]

func (h *handler) handlerequest(ctx context.context) error {
    input := h.s3client.listobjectsv2input{
        bucket: aws.string("examplebucket"),
    }

    [...]
}

type handler struct {
    s3client s3iface.s3api
}

// main is called only once, when the lambda is initialised (started for the first time). code in this function should
// primarily be used to create service clients, read environments variables, read configuration from disk etc.
func main() {
    h := handler{
        s3client: s3.new(session.new()),
    }

    lambda.start(h.handlerequest)
}

ma​​in_test.go

type ListObjectsV2Mock struct {
    s3iface.S3API

    output *s3.ListObjectsV2Output
}

func TestHandleRequest(t *testing.T) {
    h := handler{
        s3Client: &ListObjectsV2Mock{
            output: &s3.ListObjectsV2Output{...},
        },
    }

    err := h.HandleRequest(context.TODO())
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
}

显然,缺少很多代码(导入、错误处理等),但这就是要点。

理论要掌握,实操不能落!以上关于《func init() 与 func main() 用于初始化 AWS Lambda 处理程序中的全局状态》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>