github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/les/flowcontrol/manager.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2016 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 //包流控制实现客户端流控制机制 26 package flowcontrol 27 28 import ( 29 "sync" 30 "time" 31 32 "github.com/ethereum/go-ethereum/common/mclock" 33 ) 34 35 const rcConst = 1000000 36 37 type cmNode struct { 38 node *ClientNode 39 lastUpdate mclock.AbsTime 40 serving, recharging bool 41 rcWeight uint64 42 rcValue, rcDelta, startValue int64 43 finishRecharge mclock.AbsTime 44 } 45 46 func (node *cmNode) update(time mclock.AbsTime) { 47 dt := int64(time - node.lastUpdate) 48 node.rcValue += node.rcDelta * dt / rcConst 49 node.lastUpdate = time 50 if node.recharging && time >= node.finishRecharge { 51 node.recharging = false 52 node.rcDelta = 0 53 node.rcValue = 0 54 } 55 } 56 57 func (node *cmNode) set(serving bool, simReqCnt, sumWeight uint64) { 58 if node.serving && !serving { 59 node.recharging = true 60 sumWeight += node.rcWeight 61 } 62 node.serving = serving 63 if node.recharging && serving { 64 node.recharging = false 65 sumWeight -= node.rcWeight 66 } 67 68 node.rcDelta = 0 69 if serving { 70 node.rcDelta = int64(rcConst / simReqCnt) 71 } 72 if node.recharging { 73 node.rcDelta = -int64(node.node.cm.rcRecharge * node.rcWeight / sumWeight) 74 node.finishRecharge = node.lastUpdate + mclock.AbsTime(node.rcValue*rcConst/(-node.rcDelta)) 75 } 76 } 77 78 type ClientManager struct { 79 lock sync.Mutex 80 nodes map[*cmNode]struct{} 81 simReqCnt, sumWeight, rcSumValue uint64 82 maxSimReq, maxRcSum uint64 83 rcRecharge uint64 84 resumeQueue chan chan bool 85 time mclock.AbsTime 86 } 87 88 func NewClientManager(rcTarget, maxSimReq, maxRcSum uint64) *ClientManager { 89 cm := &ClientManager{ 90 nodes: make(map[*cmNode]struct{}), 91 resumeQueue: make(chan chan bool), 92 rcRecharge: rcConst * rcConst / (100*rcConst/rcTarget - rcConst), 93 maxSimReq: maxSimReq, 94 maxRcSum: maxRcSum, 95 } 96 go cm.queueProc() 97 return cm 98 } 99 100 func (self *ClientManager) Stop() { 101 self.lock.Lock() 102 defer self.lock.Unlock() 103 104 //向任何等待接受例程发出返回false的信号 105 self.nodes = make(map[*cmNode]struct{}) 106 close(self.resumeQueue) 107 } 108 109 func (self *ClientManager) addNode(cnode *ClientNode) *cmNode { 110 time := mclock.Now() 111 node := &cmNode{ 112 node: cnode, 113 lastUpdate: time, 114 finishRecharge: time, 115 rcWeight: 1, 116 } 117 self.lock.Lock() 118 defer self.lock.Unlock() 119 120 self.nodes[node] = struct{}{} 121 self.update(mclock.Now()) 122 return node 123 } 124 125 func (self *ClientManager) removeNode(node *cmNode) { 126 self.lock.Lock() 127 defer self.lock.Unlock() 128 129 time := mclock.Now() 130 self.stop(node, time) 131 delete(self.nodes, node) 132 self.update(time) 133 } 134 135 //重新计算总重量 136 func (self *ClientManager) updateNodes(time mclock.AbsTime) (rce bool) { 137 var sumWeight, rcSum uint64 138 for node := range self.nodes { 139 rc := node.recharging 140 node.update(time) 141 if rc && !node.recharging { 142 rce = true 143 } 144 if node.recharging { 145 sumWeight += node.rcWeight 146 } 147 rcSum += uint64(node.rcValue) 148 } 149 self.sumWeight = sumWeight 150 self.rcSumValue = rcSum 151 return 152 } 153 154 func (self *ClientManager) update(time mclock.AbsTime) { 155 for { 156 firstTime := time 157 for node := range self.nodes { 158 if node.recharging && node.finishRecharge < firstTime { 159 firstTime = node.finishRecharge 160 } 161 } 162 if self.updateNodes(firstTime) { 163 for node := range self.nodes { 164 if node.recharging { 165 node.set(node.serving, self.simReqCnt, self.sumWeight) 166 } 167 } 168 } else { 169 self.time = time 170 return 171 } 172 } 173 } 174 175 func (self *ClientManager) canStartReq() bool { 176 return self.simReqCnt < self.maxSimReq && self.rcSumValue < self.maxRcSum 177 } 178 179 func (self *ClientManager) queueProc() { 180 for rc := range self.resumeQueue { 181 for { 182 time.Sleep(time.Millisecond * 10) 183 self.lock.Lock() 184 self.update(mclock.Now()) 185 cs := self.canStartReq() 186 self.lock.Unlock() 187 if cs { 188 break 189 } 190 } 191 close(rc) 192 } 193 } 194 195 func (self *ClientManager) accept(node *cmNode, time mclock.AbsTime) bool { 196 self.lock.Lock() 197 defer self.lock.Unlock() 198 199 self.update(time) 200 if !self.canStartReq() { 201 resume := make(chan bool) 202 self.lock.Unlock() 203 self.resumeQueue <- resume 204 <-resume 205 self.lock.Lock() 206 if _, ok := self.nodes[node]; !ok { 207 return false //如果节点已删除或管理器已停止,则拒绝 208 } 209 } 210 self.simReqCnt++ 211 node.set(true, self.simReqCnt, self.sumWeight) 212 node.startValue = node.rcValue 213 self.update(self.time) 214 return true 215 } 216 217 func (self *ClientManager) stop(node *cmNode, time mclock.AbsTime) { 218 if node.serving { 219 self.update(time) 220 self.simReqCnt-- 221 node.set(false, self.simReqCnt, self.sumWeight) 222 self.update(time) 223 } 224 } 225 226 func (self *ClientManager) processed(node *cmNode, time mclock.AbsTime) (rcValue, rcCost uint64) { 227 self.lock.Lock() 228 defer self.lock.Unlock() 229 230 self.stop(node, time) 231 return uint64(node.rcValue), uint64(node.rcValue - node.startValue) 232 }