【发布时间】:2018-06-01 21:32:30
【问题描述】:
我正在使用 Go 编写一个简单的 App Engine 程序。我需要将一些数据写入 Google DataStore。当我尝试将数据放入存储时,程序一直挂起。这整个星期都困扰着我。
在某个时候,我设法将数据写入 DataStore,直到我发现如何在 Cloud Console 中查看上传的数据后才意识到这一点。从那以后我已经对代码进行了很多更改,现在我不能再写任何数据了。它每次都挂起。
日志显示没有任何帮助。仅通知该过程已超时。没有从程序写入的日志,仅从系统写入。
由于超出了请求期限,进程终止。 (错误代码 123)
我尝试使用this link 更改导入语句,但编译失败,所以我返回this link,编译没有问题。
我考虑到我的开发环境可能以某种方式严重错误配置(也许是毁容?),所以我去了一台干净的机器并仔细进行了新安装。它仍然挂起。
我的 app.yaml 文件:
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
我添加的一个 index.yaml 文件:
indexes:
- kind: Bacon
properties:
- name: YCode
direction: asc
- name: URL
- name: Owner
- name: Location
这是我的代码:
package main
import (
"fmt"
"log"
"net/http"
"google.golang.org/appengine/datastore"
"google.golang.org/appengine"
)
type Bacon struct {
YCode string
URL string
Owner string
Location string
}
func main() {
http.HandleFunc("/", indexHandler)
appengine.Main()
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
projectID := "fake-for-discussion-thread-787987"
client, err := datastore.NewClient(ctx, projectID)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
return
}
kind := "Bacon"
name := "3"
baconKey := datastore.NameKey(kind, name, nil)
//Make bacon
bacon := Bacon{
YCode: "1",
URL: "http://www.safeway.com",
Owner: "Bob",
Location: "Deli",
}
// I've confirmed that this is where it hangs every time.
// It doesn't even capture my silly fatal log entry.
// It just times out and finally sends a 500 Server Error.
if _, err := client.Put(ctx, baconKey, &bacon); err != nil {
log.Fatalf("Failed to save my Bacon: %v", err)
}
client.Close()
}
非常感谢您提供的任何帮助!
【问题讨论】:
-
嗯培根...这可能是因为上下文被使用了两次(NewClient 和 client.Put 中的 ctx)。尝试在 main 中创建一个长期存在的应用引擎客户端,并在请求处理程序中重用它。见example
-
或者 datastore.NewClient 应该使用 context.Background() 而不是请求上下文创建。见example
-
我开始认为在本地运行和在 App Engine 上运行之间的差异在很多在线文档中都没有得到很好的体现。恰当的例子:许多示例确实使用了 context.Background(),但是当我尝试它时,我收到了 App Engine 的拒绝,因为它“不是应用程序引擎上下文”。叹。所以我求助于将那段代码嵌入到 indexHandler 中,因为它生成了 r,我可以将它提供给 appengine.NewContext() 以获取 App Engine 发现的上下文。
-
我确实设法通过挖掘此处引用的代码解决了这个问题:cloud.google.com/appengine/docs/standard/go/building-app/…。而且,更具体地说:github.com/GoogleCloudPlatform/golang-samples/blob/master/…。解决我的 Put 问题的方法是停止尝试创建客户端对象,只需调用 datastore.Put。繁荣!不再挂起,我的数据以极快的速度写入 Google 的 DataStore!
-
所以这里的大收获:App Engine 在后台做了很多事情,并且很好地融入了他们的 DataStore 服务,只要你不尝试使用相同的代码约定在本地(或在非 App Engine 机器上)运行时可能工作。
标签: google-app-engine go google-cloud-datastore