github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/stream/peer.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:44</date> 10 //</624450115607728128> 11 12 13 package stream 14 15 import ( 16 "context" 17 "errors" 18 "fmt" 19 "sync" 20 "time" 21 22 "github.com/ethereum/go-ethereum/metrics" 23 "github.com/ethereum/go-ethereum/p2p/protocols" 24 "github.com/ethereum/go-ethereum/swarm/log" 25 pq "github.com/ethereum/go-ethereum/swarm/network/priorityqueue" 26 "github.com/ethereum/go-ethereum/swarm/network/stream/intervals" 27 "github.com/ethereum/go-ethereum/swarm/spancontext" 28 "github.com/ethereum/go-ethereum/swarm/state" 29 "github.com/ethereum/go-ethereum/swarm/storage" 30 opentracing "github.com/opentracing/opentracing-go" 31 ) 32 33 type notFoundError struct { 34 t string 35 s Stream 36 } 37 38 func newNotFoundError(t string, s Stream) *notFoundError { 39 return ¬FoundError{t: t, s: s} 40 } 41 42 func (e *notFoundError) Error() string { 43 return fmt.Sprintf("%s not found for stream %q", e.t, e.s) 44 } 45 46 //如果达到对等服务器限制,将返回errmaxpeerservers。 47 //它将在subscriberormsg中发送。 48 var ErrMaxPeerServers = errors.New("max peer servers") 49 50 //Peer是流协议的对等扩展 51 type Peer struct { 52 *protocols.Peer 53 streamer *Registry 54 pq *pq.PriorityQueue 55 serverMu sync.RWMutex 56 clientMu sync.RWMutex //保护客户端和客户端参数 57 servers map[Stream]*server 58 clients map[Stream]*client 59 //clientparams映射保留必需的客户端参数 60 //在注册表上设置的。订阅并使用 61 //在提供的哈希处理程序中创建新客户端。 62 clientParams map[Stream]*clientParams 63 quit chan struct{} 64 } 65 66 type WrappedPriorityMsg struct { 67 Context context.Context 68 Msg interface{} 69 } 70 71 //newpeer是peer的构造函数 72 func NewPeer(peer *protocols.Peer, streamer *Registry) *Peer { 73 p := &Peer{ 74 Peer: peer, 75 pq: pq.New(int(PriorityQueue), PriorityQueueCap), 76 streamer: streamer, 77 servers: make(map[Stream]*server), 78 clients: make(map[Stream]*client), 79 clientParams: make(map[Stream]*clientParams), 80 quit: make(chan struct{}), 81 } 82 ctx, cancel := context.WithCancel(context.Background()) 83 go p.pq.Run(ctx, func(i interface{}) { 84 wmsg := i.(WrappedPriorityMsg) 85 err := p.Send(wmsg.Context, wmsg.Msg) 86 if err != nil { 87 log.Error("Message send error, dropping peer", "peer", p.ID(), "err", err) 88 p.Drop(err) 89 } 90 }) 91 92 //PQ争用的基本监控 93 go func(pq *pq.PriorityQueue) { 94 ticker := time.NewTicker(5 * time.Second) 95 defer ticker.Stop() 96 for { 97 select { 98 case <-ticker.C: 99 var len_maxi int 100 var cap_maxi int 101 for k := range pq.Queues { 102 if len_maxi < len(pq.Queues[k]) { 103 len_maxi = len(pq.Queues[k]) 104 } 105 106 if cap_maxi < cap(pq.Queues[k]) { 107 cap_maxi = cap(pq.Queues[k]) 108 } 109 } 110 111 metrics.GetOrRegisterGauge(fmt.Sprintf("pq_len_%s", p.ID().TerminalString()), nil).Update(int64(len_maxi)) 112 metrics.GetOrRegisterGauge(fmt.Sprintf("pq_cap_%s", p.ID().TerminalString()), nil).Update(int64(cap_maxi)) 113 case <-p.quit: 114 return 115 } 116 } 117 }(p.pq) 118 119 go func() { 120 <-p.quit 121 cancel() 122 }() 123 return p 124 } 125 126 //传递向对等端发送storerequestmsg协议消息 127 //根据“同步”参数,我们发送不同的消息类型 128 func (p *Peer) Deliver(ctx context.Context, chunk storage.Chunk, priority uint8, syncing bool) error { 129 var sp opentracing.Span 130 var msg interface{} 131 132 spanName := "send.chunk.delivery" 133 134 //如果传递是为了同步或检索,我们会发送不同类型的消息, 135 //即使消息的处理和内容相同, 136 //因为交换记帐根据消息类型决定哪些消息需要记帐 137 if syncing { 138 msg = &ChunkDeliveryMsgSyncing{ 139 Addr: chunk.Address(), 140 SData: chunk.Data(), 141 } 142 spanName += ".syncing" 143 } else { 144 msg = &ChunkDeliveryMsgRetrieval{ 145 Addr: chunk.Address(), 146 SData: chunk.Data(), 147 } 148 spanName += ".retrieval" 149 } 150 ctx, sp = spancontext.StartSpan( 151 ctx, 152 spanName) 153 defer sp.Finish() 154 155 return p.SendPriority(ctx, msg, priority) 156 } 157 158 //sendpriority使用传出优先级队列向对等端发送消息 159 func (p *Peer) SendPriority(ctx context.Context, msg interface{}, priority uint8) error { 160 defer metrics.GetOrRegisterResettingTimer(fmt.Sprintf("peer.sendpriority_t.%d", priority), nil).UpdateSince(time.Now()) 161 metrics.GetOrRegisterCounter(fmt.Sprintf("peer.sendpriority.%d", priority), nil).Inc(1) 162 wmsg := WrappedPriorityMsg{ 163 Context: ctx, 164 Msg: msg, 165 } 166 err := p.pq.Push(wmsg, int(priority)) 167 if err == pq.ErrContention { 168 log.Warn("dropping peer on priority queue contention", "peer", p.ID()) 169 p.Drop(err) 170 } 171 return err 172 } 173 174 //sendforferedhashes发送offeredhashemsg协议消息 175 func (p *Peer) SendOfferedHashes(s *server, f, t uint64) error { 176 var sp opentracing.Span 177 ctx, sp := spancontext.StartSpan( 178 context.TODO(), 179 "send.offered.hashes") 180 defer sp.Finish() 181 182 hashes, from, to, proof, err := s.setNextBatch(f, t) 183 if err != nil { 184 return err 185 } 186 //只有在退出时才为真 187 if len(hashes) == 0 { 188 return nil 189 } 190 if proof == nil { 191 proof = &HandoverProof{ 192 Handover: &Handover{}, 193 } 194 } 195 s.currentBatch = hashes 196 msg := &OfferedHashesMsg{ 197 HandoverProof: proof, 198 Hashes: hashes, 199 From: from, 200 To: to, 201 Stream: s.stream, 202 } 203 log.Trace("Swarm syncer offer batch", "peer", p.ID(), "stream", s.stream, "len", len(hashes), "from", from, "to", to) 204 return p.SendPriority(ctx, msg, s.priority) 205 } 206 207 func (p *Peer) getServer(s Stream) (*server, error) { 208 p.serverMu.RLock() 209 defer p.serverMu.RUnlock() 210 211 server := p.servers[s] 212 if server == nil { 213 return nil, newNotFoundError("server", s) 214 } 215 return server, nil 216 } 217 218 func (p *Peer) setServer(s Stream, o Server, priority uint8) (*server, error) { 219 p.serverMu.Lock() 220 defer p.serverMu.Unlock() 221 222 if p.servers[s] != nil { 223 return nil, fmt.Errorf("server %s already registered", s) 224 } 225 226 if p.streamer.maxPeerServers > 0 && len(p.servers) >= p.streamer.maxPeerServers { 227 return nil, ErrMaxPeerServers 228 } 229 230 sessionIndex, err := o.SessionIndex() 231 if err != nil { 232 return nil, err 233 } 234 os := &server{ 235 Server: o, 236 stream: s, 237 priority: priority, 238 sessionIndex: sessionIndex, 239 } 240 p.servers[s] = os 241 return os, nil 242 } 243 244 func (p *Peer) removeServer(s Stream) error { 245 p.serverMu.Lock() 246 defer p.serverMu.Unlock() 247 248 server, ok := p.servers[s] 249 if !ok { 250 return newNotFoundError("server", s) 251 } 252 server.Close() 253 delete(p.servers, s) 254 return nil 255 } 256 257 func (p *Peer) getClient(ctx context.Context, s Stream) (c *client, err error) { 258 var params *clientParams 259 func() { 260 p.clientMu.RLock() 261 defer p.clientMu.RUnlock() 262 263 c = p.clients[s] 264 if c != nil { 265 return 266 } 267 params = p.clientParams[s] 268 }() 269 if c != nil { 270 return c, nil 271 } 272 273 if params != nil { 274 //调试.printstack() 275 if err := params.waitClient(ctx); err != nil { 276 return nil, err 277 } 278 } 279 280 p.clientMu.RLock() 281 defer p.clientMu.RUnlock() 282 283 c = p.clients[s] 284 if c != nil { 285 return c, nil 286 } 287 return nil, newNotFoundError("client", s) 288 } 289 290 func (p *Peer) getOrSetClient(s Stream, from, to uint64) (c *client, created bool, err error) { 291 p.clientMu.Lock() 292 defer p.clientMu.Unlock() 293 294 c = p.clients[s] 295 if c != nil { 296 return c, false, nil 297 } 298 299 f, err := p.streamer.GetClientFunc(s.Name) 300 if err != nil { 301 return nil, false, err 302 } 303 304 is, err := f(p, s.Key, s.Live) 305 if err != nil { 306 return nil, false, err 307 } 308 309 cp, err := p.getClientParams(s) 310 if err != nil { 311 return nil, false, err 312 } 313 defer func() { 314 if err == nil { 315 if err := p.removeClientParams(s); err != nil { 316 log.Error("stream set client: remove client params", "stream", s, "peer", p, "err", err) 317 } 318 } 319 }() 320 321 intervalsKey := peerStreamIntervalsKey(p, s) 322 if s.Live { 323 //尝试查找以前的历史记录和实时间隔,并将实时记录合并到历史记录中 324 historyKey := peerStreamIntervalsKey(p, NewStream(s.Name, s.Key, false)) 325 historyIntervals := &intervals.Intervals{} 326 err := p.streamer.intervalsStore.Get(historyKey, historyIntervals) 327 switch err { 328 case nil: 329 liveIntervals := &intervals.Intervals{} 330 err := p.streamer.intervalsStore.Get(intervalsKey, liveIntervals) 331 switch err { 332 case nil: 333 historyIntervals.Merge(liveIntervals) 334 if err := p.streamer.intervalsStore.Put(historyKey, historyIntervals); err != nil { 335 log.Error("stream set client: put history intervals", "stream", s, "peer", p, "err", err) 336 } 337 case state.ErrNotFound: 338 default: 339 log.Error("stream set client: get live intervals", "stream", s, "peer", p, "err", err) 340 } 341 case state.ErrNotFound: 342 default: 343 log.Error("stream set client: get history intervals", "stream", s, "peer", p, "err", err) 344 } 345 } 346 347 if err := p.streamer.intervalsStore.Put(intervalsKey, intervals.NewIntervals(from)); err != nil { 348 return nil, false, err 349 } 350 351 next := make(chan error, 1) 352 c = &client{ 353 Client: is, 354 stream: s, 355 priority: cp.priority, 356 to: cp.to, 357 next: next, 358 quit: make(chan struct{}), 359 intervalsStore: p.streamer.intervalsStore, 360 intervalsKey: intervalsKey, 361 } 362 p.clients[s] = c 363 cp.clientCreated() //取消阻止正在等待的所有可能的getclient调用 364 next <- nil //这是为了在第一批到达之前允许wantedkeysmsg 365 return c, true, nil 366 } 367 368 func (p *Peer) removeClient(s Stream) error { 369 p.clientMu.Lock() 370 defer p.clientMu.Unlock() 371 372 client, ok := p.clients[s] 373 if !ok { 374 return newNotFoundError("client", s) 375 } 376 client.close() 377 delete(p.clients, s) 378 return nil 379 } 380 381 func (p *Peer) setClientParams(s Stream, params *clientParams) error { 382 p.clientMu.Lock() 383 defer p.clientMu.Unlock() 384 385 if p.clients[s] != nil { 386 return fmt.Errorf("client %s already exists", s) 387 } 388 if p.clientParams[s] != nil { 389 return fmt.Errorf("client params %s already set", s) 390 } 391 p.clientParams[s] = params 392 return nil 393 } 394 395 func (p *Peer) getClientParams(s Stream) (*clientParams, error) { 396 params := p.clientParams[s] 397 if params == nil { 398 return nil, fmt.Errorf("client params '%v' not provided to peer %v", s, p.ID()) 399 } 400 return params, nil 401 } 402 403 func (p *Peer) removeClientParams(s Stream) error { 404 _, ok := p.clientParams[s] 405 if !ok { 406 return newNotFoundError("client params", s) 407 } 408 delete(p.clientParams, s) 409 return nil 410 } 411 412 func (p *Peer) close() { 413 for _, s := range p.servers { 414 s.Close() 415 } 416 } 417