4

我在 Go 中的 Google App Engine 上遇到 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 秒后超时。如何防止它这样做?我在代码中犯了一些错误吗?

4

5 回答 5

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},
        },
    }
于 2014-10-20T18:24:17.520 回答
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

于 2015-03-13T10:11:23.587 回答
2

查看 Go 的 appengine 的源代码:

和protobuffer生成的代码:

看起来 Duration 本身应该没有问题。

我的猜测是 appengine 中的整个应用程序在 5 秒后超时。

于 2012-11-15T18:53:26.337 回答
2

对我来说,这有效:

ctx_with_deadline, _ := context.WithTimeout(ctx, 15*time.Second)
client := urlfetch.Client(ctx_with_deadline)
于 2017-02-06T14:22:38.233 回答
1

现在随着图书馆的最新更新而改变了这一点。现在超时/延迟的持续时间必须由上下文携带,其中urlfetch.transport不再有 Deadline 字段。context.WithTimeout或者context.WithDeadline是使用的方法,这里是链接https://godoc.org/golang.org/x/net/context#WithTimeout

于 2015-09-22T12:03:05.587 回答