golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.66k stars 17.62k forks source link

x/net/http2: access to maxConcurrentStreams #17265

Open nathany opened 8 years ago

nathany commented 8 years ago

What version of Go are you using (go version)?

go version go1.7.1 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64" GOOS="darwin"

What did you do?

I am working on an HTTP/2 client for Apple's push notification service. When using JWT tokens to authenticate, Apple initially sends maxConcurrentStreams = 1. Once authentication is complete they send maxConcurrentStreams = 500 (though this number may vary).

Currently I have a worker pool to send multiple requests concurrently. If I could monitor the maxConcurrentStreams, I would know how big the worker pool should be -- or how many workers should be active.

What did you expect to see?

Access to maxConcurrentStreams via httptrace or some other x/net/http2 API.

https://github.com/golang/net/blob/master/http2/transport.go#L1735

Possibly related: https://github.com/golang/go/issues/13774

What did you see instead?

If I send more requests than maxConcurrentStreams dictates

With Go 1.7.1 http.DefaultClient I am getting the following error.

http2: server sent GOAWAY and closed the connection; LastStreamID=1, ErrCode=REFUSED_STREAM, 
debug="Maximum active streams violated for this endpoint."

With the latest x/net/http2 I'm getting slightly different errors (still looking into these).

2016/09/28 10:14:43 (9) device: [my-token], error: Post https://api.development.push.apple.com/3/device/[my-token]: 
http2: no cached connection was available

and

2016/09/28 10:14:43 (11) device: [my-token], 
error: invalid character 'M' looking for beginning of value

In any case, the best I can do is prime the connection with a single request, and then send some number of concurrent requests, but not really knowing how many I can send.

bradfitz commented 8 years ago

Doesn't really fit with httptrace as it's a connection-level setting and not a per-Request thing.

But I suppose we could add something to http2.ClientConn.

I'd entertain a CL if somebody has an idea and time.

nathany commented 8 years ago

Would it be possible to notify the client (caller) when maxConcurrentStreams changes? (callback function, event channel?)

Or should this just expose the value of maxConcurrentStreams through http2.ClientConn -- with the client polling the value?

I'm also curious what the direction is for #13774 (blocking the transport)? By itself, that may prevent the REFUSED_STREAM errors I'm seeing. Though my code would be left guessing at the optimal number of concurrent requests without visibility into maxConcurrentStreams.

gopherbot commented 6 years ago

Change https://golang.org/cl/85855 mentions this issue: http2: use callback to expose SETTINGS updates from the server