https://github.com/messixukej...
在liangzhiyang/annotate-grpc-go基础上补充了部分注释git
HTTP/2 流量控制的目标,在流量窗口初始值的约束下,给予接收端以全权,控制当下想要接受的流量大小。github
算法:算法
// 用于发送流控。 将当前可用的quota(字节数)写入c,有数据发送须要时,从c中获取。acquire到的大小即为可支持的最大发送量。 // acquire 将quota所有获取出来,根据实际使用量,将未使用的从新add回pool。 type quotaPool struct{ c chan int mu sync.Mutex quota int } http2Client.Write消耗quota,client跟stream有各自的控制。 handleWindowUpdate补充quota。
//用于接收流控。onData经过判断pendingData、pendingUpdate之和是否超过limit来进行流控。 type inFlow struct{ /// The inbound flow control limit for pending data./ limit uint32 mu sync.Mutex // pendingData is the overall data which have been received but not been consumed by applications. //接收可是未被应用消费的数据,对应onData。 pendingData uint32 // The amount of data the application has consumed but grpc has not sent window update for them. Used to reduce window update frequency. //对应onRead pendingUpdate uint32 } pendingData:handleData->onData增长pendingData->s.write(可供io.ReadFull读取) pendingUpdate:io.ReadFull(s1, p)->Stream.Read读取数据->windowHandler->updateWindow->onRead减小pendingData,按照1/4limit量还清空pendingUpdate->windowUpdate->framer.writeWindowUpdate更新发送端窗口大小->发送端处理handleWindowUpdate(id=0更新client,非0更新对应stream) ->进而增长发送端quota