Do not flush NewStream header on client side for unary RPCs and streaming RPCs with requests. (#1343)
If it's not client streaming, we should already have the request to be sent, so we don't flush the header. If it's client streaming, the user may never send a request or send it any time soon, so we ask the transport to flush the header. And flush header even without metadata
This commit is contained in:
@ -130,7 +130,11 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
|
|||||||
callHdr := &transport.CallHdr{
|
callHdr := &transport.CallHdr{
|
||||||
Host: cc.authority,
|
Host: cc.authority,
|
||||||
Method: method,
|
Method: method,
|
||||||
Flush: desc.ServerStreams && desc.ClientStreams,
|
// If it's not client streaming, we should already have the request to be sent,
|
||||||
|
// so we don't flush the header.
|
||||||
|
// If it's client streaming, the user may never send a request or send it any
|
||||||
|
// time soon, so we ask the transport to flush the header.
|
||||||
|
Flush: desc.ClientStreams,
|
||||||
}
|
}
|
||||||
if cc.dopts.cp != nil {
|
if cc.dopts.cp != nil {
|
||||||
callHdr.SendCompress = cc.dopts.cp.Type()
|
callHdr.SendCompress = cc.dopts.cp.Type()
|
||||||
|
@ -465,11 +465,9 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
|
|||||||
t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
|
t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
hasMD bool
|
|
||||||
endHeaders bool
|
endHeaders bool
|
||||||
)
|
)
|
||||||
if md, ok := metadata.FromOutgoingContext(ctx); ok {
|
if md, ok := metadata.FromOutgoingContext(ctx); ok {
|
||||||
hasMD = true
|
|
||||||
for k, vv := range md {
|
for k, vv := range md {
|
||||||
// HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set.
|
// HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set.
|
||||||
if isReservedHeader(k) {
|
if isReservedHeader(k) {
|
||||||
@ -501,7 +499,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
|
|||||||
endHeaders = true
|
endHeaders = true
|
||||||
}
|
}
|
||||||
var flush bool
|
var flush bool
|
||||||
if endHeaders && (hasMD || callHdr.Flush) {
|
if callHdr.Flush && endHeaders {
|
||||||
flush = true
|
flush = true
|
||||||
}
|
}
|
||||||
if first {
|
if first {
|
||||||
|
@ -539,8 +539,10 @@ type CallHdr struct {
|
|||||||
|
|
||||||
// Flush indicates whether a new stream command should be sent
|
// Flush indicates whether a new stream command should be sent
|
||||||
// to the peer without waiting for the first data. This is
|
// to the peer without waiting for the first data. This is
|
||||||
// only a hint. The transport may modify the flush decision
|
// only a hint.
|
||||||
|
// If it's true, the transport may modify the flush decision
|
||||||
// for performance purposes.
|
// for performance purposes.
|
||||||
|
// If it's false, new stream will never be flushed.
|
||||||
Flush bool
|
Flush bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user