github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:48</date> 10 //</624342675784470528> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 package stream 29 30 import ( 31 "context" 32 "fmt" 33 "sync" 34 "time" 35 36 "github.com/ethereum/go-ethereum/metrics" 37 "github.com/ethereum/go-ethereum/p2p/protocols" 38 "github.com/ethereum/go-ethereum/swarm/log" 39 pq "github.com/ethereum/go-ethereum/swarm/network/priorityqueue" 40 "github.com/ethereum/go-ethereum/swarm/network/stream/intervals" 41 "github.com/ethereum/go-ethereum/swarm/spancontext" 42 "github.com/ethereum/go-ethereum/swarm/state" 43 "github.com/ethereum/go-ethereum/swarm/storage" 44 opentracing "github.com/opentracing/opentracing-go" 45 ) 46 47 var sendTimeout = 30 * time.Second 48 49 type notFoundError struct { 50 t string 51 s Stream 52 } 53 54 func newNotFoundError(t string, s Stream) *notFoundError { 55 return ¬FoundError{t: t, s: s} 56 } 57 58 func (e *notFoundError) Error() string { 59 return fmt.Sprintf("%s not found for stream %q", e.t, e.s) 60 } 61 62 // 63 type Peer struct { 64 *protocols.Peer 65 streamer *Registry 66 pq *pq.PriorityQueue 67 serverMu sync.RWMutex 68 clientMu sync.RWMutex // 69 servers map[Stream]*server 70 clients map[Stream]*client 71 // 72 // 73 // 74 clientParams map[Stream]*clientParams 75 quit chan struct{} 76 } 77 78 type WrappedPriorityMsg struct { 79 Context context.Context 80 Msg interface{} 81 } 82 83 // 84 func NewPeer(peer *protocols.Peer, streamer *Registry) *Peer { 85 p := &Peer{ 86 Peer: peer, 87 pq: pq.New(int(PriorityQueue), PriorityQueueCap), 88 streamer: streamer, 89 servers: make(map[Stream]*server), 90 clients: make(map[Stream]*client), 91 clientParams: make(map[Stream]*clientParams), 92 quit: make(chan struct{}), 93 } 94 ctx, cancel := context.WithCancel(context.Background()) 95 go p.pq.Run(ctx, func(i interface{}) { 96 wmsg := i.(WrappedPriorityMsg) 97 p.Send(wmsg.Context, wmsg.Msg) 98 }) 99 go func() { 100 <-p.quit 101 cancel() 102 }() 103 return p 104 } 105 106 // 107 func (p *Peer) Deliver(ctx context.Context, chunk *storage.Chunk, priority uint8) error { 108 var sp opentracing.Span 109 ctx, sp = spancontext.StartSpan( 110 ctx, 111 "send.chunk.delivery") 112 defer sp.Finish() 113 114 msg := &ChunkDeliveryMsg{ 115 Addr: chunk.Addr, 116 SData: chunk.SData, 117 } 118 return p.SendPriority(ctx, msg, priority) 119 } 120 121 // 122 func (p *Peer) SendPriority(ctx context.Context, msg interface{}, priority uint8) error { 123 defer metrics.GetOrRegisterResettingTimer(fmt.Sprintf("peer.sendpriority_t.%d", priority), nil).UpdateSince(time.Now()) 124 metrics.GetOrRegisterCounter(fmt.Sprintf("peer.sendpriority.%d", priority), nil).Inc(1) 125 cctx, cancel := context.WithTimeout(context.Background(), sendTimeout) 126 defer cancel() 127 wmsg := WrappedPriorityMsg{ 128 Context: ctx, 129 Msg: msg, 130 } 131 return p.pq.Push(cctx, wmsg, int(priority)) 132 } 133 134 // 135 func (p *Peer) SendOfferedHashes(s *server, f, t uint64) error { 136 var sp opentracing.Span 137 ctx, sp := spancontext.StartSpan( 138 context.TODO(), 139 "send.offered.hashes") 140 defer sp.Finish() 141 142 hashes, from, to, proof, err := s.SetNextBatch(f, t) 143 if err != nil { 144 return err 145 } 146 // 147 if len(hashes) == 0 { 148 return nil 149 } 150 if proof == nil { 151 proof = &HandoverProof{ 152 Handover: &Handover{}, 153 } 154 } 155 s.currentBatch = hashes 156 msg := &OfferedHashesMsg{ 157 HandoverProof: proof, 158 Hashes: hashes, 159 From: from, 160 To: to, 161 Stream: s.stream, 162 } 163 log.Trace("Swarm syncer offer batch", "peer", p.ID(), "stream", s.stream, "len", len(hashes), "from", from, "to", to) 164 return p.SendPriority(ctx, msg, s.priority) 165 } 166 167 func (p *Peer) getServer(s Stream) (*server, error) { 168 p.serverMu.RLock() 169 defer p.serverMu.RUnlock() 170 171 server := p.servers[s] 172 if server == nil { 173 return nil, newNotFoundError("server", s) 174 } 175 return server, nil 176 } 177 178 func (p *Peer) setServer(s Stream, o Server, priority uint8) (*server, error) { 179 p.serverMu.Lock() 180 defer p.serverMu.Unlock() 181 182 if p.servers[s] != nil { 183 return nil, fmt.Errorf("server %s already registered", s) 184 } 185 os := &server{ 186 Server: o, 187 stream: s, 188 priority: priority, 189 } 190 p.servers[s] = os 191 return os, nil 192 } 193 194 func (p *Peer) removeServer(s Stream) error { 195 p.serverMu.Lock() 196 defer p.serverMu.Unlock() 197 198 server, ok := p.servers[s] 199 if !ok { 200 return newNotFoundError("server", s) 201 } 202 server.Close() 203 delete(p.servers, s) 204 return nil 205 } 206 207 func (p *Peer) getClient(ctx context.Context, s Stream) (c *client, err error) { 208 var params *clientParams 209 func() { 210 p.clientMu.RLock() 211 defer p.clientMu.RUnlock() 212 213 c = p.clients[s] 214 if c != nil { 215 return 216 } 217 params = p.clientParams[s] 218 }() 219 if c != nil { 220 return c, nil 221 } 222 223 if params != nil { 224 // 225 if err := params.waitClient(ctx); err != nil { 226 return nil, err 227 } 228 } 229 230 p.clientMu.RLock() 231 defer p.clientMu.RUnlock() 232 233 c = p.clients[s] 234 if c != nil { 235 return c, nil 236 } 237 return nil, newNotFoundError("client", s) 238 } 239 240 func (p *Peer) getOrSetClient(s Stream, from, to uint64) (c *client, created bool, err error) { 241 p.clientMu.Lock() 242 defer p.clientMu.Unlock() 243 244 c = p.clients[s] 245 if c != nil { 246 return c, false, nil 247 } 248 249 f, err := p.streamer.GetClientFunc(s.Name) 250 if err != nil { 251 return nil, false, err 252 } 253 254 is, err := f(p, s.Key, s.Live) 255 if err != nil { 256 return nil, false, err 257 } 258 259 cp, err := p.getClientParams(s) 260 if err != nil { 261 return nil, false, err 262 } 263 defer func() { 264 if err == nil { 265 if err := p.removeClientParams(s); err != nil { 266 log.Error("stream set client: remove client params", "stream", s, "peer", p, "err", err) 267 } 268 } 269 }() 270 271 intervalsKey := peerStreamIntervalsKey(p, s) 272 if s.Live { 273 // 274 historyKey := peerStreamIntervalsKey(p, NewStream(s.Name, s.Key, false)) 275 historyIntervals := &intervals.Intervals{} 276 err := p.streamer.intervalsStore.Get(historyKey, historyIntervals) 277 switch err { 278 case nil: 279 liveIntervals := &intervals.Intervals{} 280 err := p.streamer.intervalsStore.Get(intervalsKey, liveIntervals) 281 switch err { 282 case nil: 283 historyIntervals.Merge(liveIntervals) 284 if err := p.streamer.intervalsStore.Put(historyKey, historyIntervals); err != nil { 285 log.Error("stream set client: put history intervals", "stream", s, "peer", p, "err", err) 286 } 287 case state.ErrNotFound: 288 default: 289 log.Error("stream set client: get live intervals", "stream", s, "peer", p, "err", err) 290 } 291 case state.ErrNotFound: 292 default: 293 log.Error("stream set client: get history intervals", "stream", s, "peer", p, "err", err) 294 } 295 } 296 297 if err := p.streamer.intervalsStore.Put(intervalsKey, intervals.NewIntervals(from)); err != nil { 298 return nil, false, err 299 } 300 301 next := make(chan error, 1) 302 c = &client{ 303 Client: is, 304 stream: s, 305 priority: cp.priority, 306 to: cp.to, 307 next: next, 308 quit: make(chan struct{}), 309 intervalsStore: p.streamer.intervalsStore, 310 intervalsKey: intervalsKey, 311 } 312 p.clients[s] = c 313 cp.clientCreated() // 314 next <- nil // 315 return c, true, nil 316 } 317 318 func (p *Peer) removeClient(s Stream) error { 319 p.clientMu.Lock() 320 defer p.clientMu.Unlock() 321 322 client, ok := p.clients[s] 323 if !ok { 324 return newNotFoundError("client", s) 325 } 326 client.close() 327 return nil 328 } 329 330 func (p *Peer) setClientParams(s Stream, params *clientParams) error { 331 p.clientMu.Lock() 332 defer p.clientMu.Unlock() 333 334 if p.clients[s] != nil { 335 return fmt.Errorf("client %s already exists", s) 336 } 337 if p.clientParams[s] != nil { 338 return fmt.Errorf("client params %s already set", s) 339 } 340 p.clientParams[s] = params 341 return nil 342 } 343 344 func (p *Peer) getClientParams(s Stream) (*clientParams, error) { 345 params := p.clientParams[s] 346 if params == nil { 347 return nil, fmt.Errorf("client params '%v' not provided to peer %v", s, p.ID()) 348 } 349 return params, nil 350 } 351 352 func (p *Peer) removeClientParams(s Stream) error { 353 _, ok := p.clientParams[s] 354 if !ok { 355 return newNotFoundError("client params", s) 356 } 357 delete(p.clientParams, s) 358 return nil 359 } 360 361 func (p *Peer) close() { 362 for _, s := range p.servers { 363 s.Close() 364 } 365 } 366