GAE Golang — тайм-аут urfetch?

У меня проблемы с тайм-аутом urfetch в Google App Engine in 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 секунд. Как не допустить этого? Я сделал какую-то ошибку в своем коде?


person ThePiachu    schedule 09.11.2012    source источник


Ответы (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},
        },
    }
person orcaman    schedule 20.10.2014
comment
Вам не нужно приводить константы таким образом, 30 * time.Second предпочтительнее. - person Dave C; 13.03.2015

Попробуйте код ниже:

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

person Devaroop    schedule 13.03.2015

Глядя на исходный код appengine Go:

и сгенерированный протобуфером код:

Похоже, что не должно быть проблем с самой длительностью.

Я предполагаю, что все приложение внутри appengine отключается через 5 секунд.

person fabrizioM    schedule 15.11.2012

для меня это сработало:

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

Теперь это изменилось с последними обновлениями библиотеки. Теперь продолжительность тайм-аута/задержки должна переноситься контекстом, urlfetch.transport в нем больше нет поля «Крайний срок». context.WithTimeout или context.WithDeadline — метод, который следует использовать, вот ссылка https://godoc.org/golang.org/x/net/context#WithTimeout

person Karthic Rao    schedule 22.09.2015