2012-11-09 61 views
4

我在Go中的Google App Engine上遇到urlfetch超时问题。该应用程序似乎不想花费比5秒钟更长的超时时间(它会忽略较长的超时时间,并超过自己的时间超时)。GAE Golang - urlfetch超时?

我的代码是:

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秒钟后。如何防止它做到这一点?我的代码中有错误吗?

回答

10

您需要通过这样的持续时间(否则它会默认为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}, 
     }, 
    } 
+0

你不需要施放[常量](https://blog.golang.org /常数),'30 * time.Second'是首选。 –

+1

感谢2016年更新! –

3

尝试下面的代码:

// 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, 
     }, 
    } 
} 

这里是如何使用它。

// urlfetch 
client := createClient(c, time.Second*60) 

礼貌@gosharplite

1

这是现在已经改变了与最近更新到库中。现在,持续时间/延迟必须由上下文携带,urlfetch.transport不再有Deadline字段。 context.WithTimeoutcontext.WithDeadline是使用的方法,这里是链接https://godoc.org/golang.org/x/net/context#WithTimeout

1

对我来说,这个工作:

ctx_with_deadline, _ := context.WithTimeout(ctx, 15*time.Second) 
client := urlfetch.Client(ctx_with_deadline)