在init()函数中,如何在Go App Engine中获取版本而不使用Context?

huangapple go评论86阅读模式
英文:

Go App Engine get version in init() without Context

问题

在没有Context的情况下,有没有办法在我的init()函数中获取我的自动缩放应用程序的VersionID?唯一可用的选项似乎是appengine.VersionID(context.Context)。手动缩放的实例在启动时调用/_ah/start(提供对Context的访问),但是对于自动缩放的实例没有类似的机制。

我不关心appengine.VersionID返回的生成的ID,只关心app.yaml的版本。

编辑:一些背景信息:我想以x-x-x-dev或x-x-x-live的形式部署版本,并且让我的数据库连接依赖于版本后缀。这样,当我查看GCP控制台时,我可以确定哪些部署的模块/服务正在使用哪个数据库。当然,我在init()中设置了我的数据库连接池,但它无法访问Context

英文:

Is there a way to to get my autoscaled application's VersionID in my init() function without a Context? The only available option seems to be appengine.VersionID(context.Context). Manually scaled instances have /_ah/start called when they start up (giving access to a Context), but there is nothing like this for autoscaled instances.

I am not caring about the generated ID that appengine.VersionID returns with it, just the app.yaml version.

EDIT: A bit of context: I am wanting to deploy versions in the form x-x-x-dev or x-x-x-live and have my database connection depend on the version suffix. This way, when I look in the GCP console, I can be certain which deployed modules/services are using which database. Of course, I setup my DB connection pool in the init(), which has no access to a Context.

答案1

得分: 1

我在网上搜索了很久也没有找到答案,所以我在这里给出解决方法。

在你的 init() 函数中,简单地解析 app.yaml 文件。我这里的示例使用了一个 yaml 解析包,但如果需要的话,也可以使用更轻量级的方法。

import "github.com/ghodss/yaml"

type AppVersion struct {
    Version string `json:"version"`
}

func VersionID() (string, error) {
    dat, err := ioutil.ReadFile("app.yaml")
    if err != nil {
        return "", err
    }
    a := &AppVersion{}
    err = yaml.Unmarshal(dat, a)
    if err != nil {
        return "", err
    }
    return a.Version, nil
}

请注意,这个函数返回的版本号不是像 appengine.VersionID() 那样的形式 X.Y,只返回版本号的 X 部分。

另外,值得一提的是,在 Github 上的 appengine 仓库中,实际调用 appengine.VersionID 的时候需要一个 Context 参数,但内部却使用了 nil。所以他们基本上强制你使用一个 Context 来调用它,但实际上并没有使用到。这真的非常令人恼火。

编辑:需要注意的是,gcloud 中的新 Go SDK 不再支持在 app.yaml 中使用 version,因为现在在部署时它是一个必需的参数。然而,“legacy” SDK 仍然受到支持和维护,我至今仍在使用它(截至 2018 年 12 月 24 日)。

英文:

I searched and searched with no answers online anywhere, so here it is.

Simply parse the app.yaml file in your init() function. My example here uses a yaml parsing package, but it can be done more lightweight if you need.

import "github.com/ghodss/yaml"

type AppVersion struct {
    Version string `json:"version"`
}

func VersionID() (string, error) {
    dat, err := ioutil.ReadFile("app.yaml")
    if err != nil {
	    return "", err
    }
    a := &AppVersion{}
    err = yaml.Unmarshal(dat, a)
    if err != nil {
	    return "", err
    }
    return a.Version, nil
}

Note that this DOES NOT return the generated ID in the form X.Y that <a href="https://godoc.org/google.golang.org/appengine#VersionID">appengine.VersionID()</a> does. Only the X part of the version.

As an aside, in the appengine repo on Github, the actual call to appengine.VersionID requires a Context, but internally calls the internal package with nil. So they basically force you to call it with a Context, but it isn't actually used. It's incredibly infuriating.

EDIT: It should be noted that the new Go SDK in gcloud no longer supports version in the app.yaml, as it is now a required parameter at deploy. However, the "legacy" SDK is still supported and maintained, which I am continuing to use as of today (12/24/2018).

huangapple
  • 本文由 发表于 2017年2月10日 07:16:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/42148739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定