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