英文:
GAE Golang - urlfetch timeout?
问题
我在Google App Engine中使用Go语言的urlfetch遇到了超时问题。应用似乎不愿意接受超过5秒的超时时间(它会忽略更长的超时时间并在自己的时间后超时)。
我的代码是:
var TimeoutDuration time.Duration = time.Second*30
func Call(c appengine.Context, address string, allowInvalidServerCertificate bool, method string, id interface{}, params []interface{})(map[string]interface{}, error){
data, err := json.Marshal(map[string]interface{}{
"method": method,
"id": id,
"params": params,
})
if err != nil {
return nil, err
}
req, err:=http.NewRequest("POST", address, strings.NewReader(string(data)))
if err!=nil{
return nil, err
}
tr := &urlfetch.Transport{Context: c, Deadline: TimeoutDuration, AllowInvalidServerCertificate: allowInvalidServerCertificate}
resp, err:=tr.RoundTrip(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
result := make(map[string]interface{})
err = json.Unmarshal(body, &result)
if err != nil {
return nil, err
}
return result, nil
}
无论我将TimeoutDuration
设置为什么值,应用都会在大约5秒后超时。如何防止这种情况发生?我的代码中是否有错误?
英文:
I am having issues with urlfetch's timeouts on Google App Engine in Go. The app does not appear to want to take a longer timeout than about 5 seconds (it ignores a longer timeout and times out after its own time).
My code is:
var TimeoutDuration time.Duration = time.Second*30
func Call(c appengine.Context, address string, allowInvalidServerCertificate bool, method string, id interface{}, params []interface{})(map[string]interface{}, error){
data, err := json.Marshal(map[string]interface{}{
"method": method,
"id": id,
"params": params,
})
if err != nil {
return nil, err
}
req, err:=http.NewRequest("POST", address, strings.NewReader(string(data)))
if err!=nil{
return nil, err
}
tr := &urlfetch.Transport{Context: c, Deadline: TimeoutDuration, AllowInvalidServerCertificate: allowInvalidServerCertificate}
resp, err:=tr.RoundTrip(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
result := make(map[string]interface{})
err = json.Unmarshal(body, &result)
if err != nil {
return nil, err
}
return result, nil
}
No matter what I try to set TimeoutDuration
to, the app times out after about 5 seconds. How prevent it from doing that? Did I make some error in my code?
答案1
得分: 13
你需要像这样传递时间持续时间(否则它将默认为5秒超时):
tr := &urlfetch.Transport{Context: c, Deadline: time.Duration(30) * time.Second}
更新于2016年1月2日:
使用新的GAE golang包(google.golang.org/appengine/*
),这已经改变了。在传输中,urlfetch
不再接收截止时间持续时间。
现在,您应该通过新的上下文包设置超时。例如,这是如何设置1分钟截止时间的示例:
func someFunc(ctx context.Context) {
ctx_with_deadline, _ := context.WithTimeout(ctx, 1*time.Minute)
client := &http.Client{
Transport: &oauth2.Transport{
Base: &urlfetch.Transport{Context: ctx_with_deadline},
},
}
英文:
You need to pass the time duration like this (otherwise it will default to the 5 sec timeout):
tr := &urlfetch.Transport{Context: c, Deadline: time.Duration(30) * time.Second}
Update Jan 2 2016:
With the new GAE golang packages (google.golang.org/appengine/*
), this has changed. urlfetch
no longer receives a deadline time duration in the transport.
You should now set the timeout via the new context package. For example, this is how you would set a 1 minute deadline:
func someFunc(ctx context.Context) {
ctx_with_deadline, _ := context.WithTimeout(ctx, 1*time.Minute)
client := &http.Client{
Transport: &oauth2.Transport{
Base: &urlfetch.Transport{Context: ctx_with_deadline},
},
}
答案2
得分: 3
尝试下面的代码:
// createClient是带有截止时间的urlfetch.Client
func createClient(context appengine.Context, t time.Duration) *http.Client {
return &http.Client{
Transport: &urlfetch.Transport{
Context: context,
Deadline: t,
},
}
}
以下是如何使用它的方法。
// urlfetch
client := createClient(c, time.Second*60)
感谢 @gosharplite
英文:
Try the code below:
// createClient is urlfetch.Client with Deadline
func createClient(context appengine.Context, t time.Duration) *http.Client {
return &http.Client{
Transport: &urlfetch.Transport{
Context: context,
Deadline: t,
},
}
}
Here is how to use it.
// urlfetch
client := createClient(c, time.Second*60)
Courtesy @gosharplite
答案3
得分: 2
查看Go的appengine源代码:
以及生成的协议缓冲区代码:
看起来Duration本身应该没有问题。
我猜测整个在appengine中的应用程序在5秒后超时。
英文:
Looking at the source code of Go's appengine:
and the protobuffer generated code:
Looks like there should not be a problem with Duration itself.
My guess is that the whole application inside appengine timeouts after 5 seconds.
答案4
得分: 2
对我来说,这个方法有效:
ctx_with_deadline, _ := context.WithTimeout(ctx, 15*time.Second)
client := urlfetch.Client(ctx_with_deadline)
英文:
for me, this worked:
ctx_with_deadline, _ := context.WithTimeout(ctx, 15*time.Second)
client := urlfetch.Client(ctx_with_deadline)
答案5
得分: 1
这是最近对库进行的更新后所做的更改。现在超时/延迟的持续时间必须由上下文传递,urlfetch.transport
中不再有截止日期字段。context.WithTimeout
或context.WithDeadline
是要使用的方法,这是链接https://godoc.org/golang.org/x/net/context#WithTimeout。
英文:
This is had now changed with the recent updates to the library . Now the Duration of timeout/delay have to carried by the context , urlfetch.transport
no more has the Deadline field in it . context.WithTimeout
or context.WithDeadline
is the method to use , here is the link https://godoc.org/golang.org/x/net/context#WithTimeout
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论