Repository: grpc/grpc-go
File: internal/transport/controlbuf.go (Go)

Code before:
		maxSize = int(l.sendQuota)
	}
	// Compute how much of the header and data we can send within quota and max frame length
	hSize := min(maxSize, len(dataItem.h))
	dSize := min(maxSize-hSize, reader.Remaining())
	remainingBytes := len(dataItem.h) + reader.Remaining() - hSize - dSize
	size := hSize + dSize

	l.writeBuf = l.writeBuf[:0]
	if hSize > 0 {
		l.writeBuf = append(l.writeBuf, dataItem.h[:hSize])
	}
	if dSize > 0 {
		var err error
		l.writeBuf, err = reader.Peek(dSize, l.writeBuf)
		if err != nil {
			// This must never happen since the reader must have at least dSize
			// bytes.
			return false, err
		}
	}

	// Now that outgoing flow controls are checked we can replenish str's write quota
	str.wq.replenish(size)
	var endStream bool
	// If this is the last data message on this stream and all of it can be written in this iteration.
	if dataItem.endStream && remainingBytes == 0 {
		endStream = true
	}
	if dataItem.onEachWrite != nil {
		dataItem.onEachWrite()
	}
	err := l.framer.writeData(dataItem.streamID, endStream, l.writeBuf)
	reader.Discard(dSize)
	if err != nil {
		return false, err
	}
	str.bytesOutStanding += size
	l.sendQuota -= uint32(size)
	dataItem.h = dataItem.h[hSize:]

	if remainingBytes == 0 { // All the data from that message was written out.
		reader.Close()
		str.itl.dequeue()
	}
	if str.itl.isEmpty() {
		str.state = empty
	} else if trailer, ok := str.itl.peek().(*headerFrame); ok { // The next item is trailers.
		if err := l.writeHeader(trailer.streamID, trailer.endStream, trailer.hf, trailer.onWrite); err != nil {
			return false, err
		}

Review comment (suggestion):
It seems like this buffer can only grow and never shrinks.

1. What happens if a slice holds a pointer to a huge amount of data?  I believe it isn't possible to free it, but am not certain.  E.g.

```go
l.writeBuf = [][]byte{nil, nil, nil, nil, nil, nil, make([]byte, 10GB)}
l.writeBuf = l.writeBuf[:0]
```

2. What happens if `cap(l.writeBuf)` grows to a large value and then we never need it to be that large ever again?

I think we need to have some way to scale this buffer back down.

Code after:
	}

	// Figure out the maximum size we can send
	maxSize := http2MaxFrameLen
	if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota <= 0 { // stream-level flow control.
		str.state = waitingOnStreamQuota
		return false, nil
	} else if maxSize > strQuota {
		maxSize = strQuota
	}
	if maxSize > int(l.sendQuota) { // connection-level flow control.
		maxSize = int(l.sendQuota)
	}
	// Compute how much of the header and data we can send within quota and max frame length
	hSize := min(maxSize, len(dataItem.h))
	dSize := min(maxSize-hSize, reader.Remaining())
	remainingBytes := len(dataItem.h) + reader.Remaining() - hSize - dSize
	size := hSize + dSize

	l.writeBuf = l.writeBuf[:0]
	if hSize > 0 {
		l.writeBuf = append(l.writeBuf, dataItem.h[:hSize])
	}
	if dSize > 0 {
		var err error
		l.writeBuf, err = reader.Peek(dSize, l.writeBuf)
		if err != nil {
			// This must never happen since the reader must have at least dSize
			// bytes.
			// Log an error to fail tests.
			l.logger.Errorf("unexpected error while reading Data frame payload: %v", err)
			return false, err
		}
	}

	// Now that outgoing flow controls are checked we can replenish str's write quota
	str.wq.replenish(size)
	var endStream bool
	// If this is the last data message on this stream and all of it can be written in this iteration.
	if dataItem.endStream && remainingBytes == 0 {
		endStream = true
	}
	if dataItem.onEachWrite != nil {
		dataItem.onEachWrite()
	}
	err := l.framer.writeData(dataItem.streamID, endStream, l.writeBuf)
	reader.Discard(dSize)
	if cap(l.writeBuf) > maxWriteBufSize {
		l.writeBuf = nil
	} else {
		clear(l.writeBuf)