GAE Golang - тайм-аут urlfetch?
У меня проблемы с таймаутами urlfetch на Google App Engine в Go. Похоже, что приложение не хочет использовать более длительный тайм-аут, чем около 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 секунд. Как этому помешать? Я сделал ошибку в своем коде?
5 ответов
Вам нужно передать продолжительность времени, как это (в противном случае по умолчанию будет 5 секунд):
tr := &urlfetch.Transport{Context: c, Deadline: time.Duration(30) * time.Second}
Обновление 2 января 2016:
С новыми пакетами 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},
},
}
Попробуйте код ниже:
// 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
Для меня это сработало:
ctx_with_deadline, _ := context.WithTimeout(ctx, 15*time.Second)
client := urlfetch.Client(ctx_with_deadline)
Глядя на исходный код приложения Go:
и код, сгенерированный протобуфером:
Похоже, не должно быть проблем с самой продолжительностью.
Я предполагаю, что все приложение в appengine истекло через 5 секунд.
Теперь это изменилось с последними обновлениями библиотеки. Теперь Длительность тайм-аута / задержки должна переноситься контекстом, urlfetch.transport
больше нет поля Deadline в нем. context.WithTimeout
или же context.WithDeadline
это метод для использования, вот ссылка https://godoc.org/golang.org/x/net/context