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 &notFoundError{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