2012-11-09 99 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)