github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/protocol/download/task.go (about)

     1  package download
     2  
     3  import (
     4  	"sort"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/libp2p/go-libp2p-core/peer"
     9  )
    10  
    11  // task datastruct
    12  type tasks []*taskInfo
    13  
    14  type taskInfo struct {
    15  	ID      string        //一次下载任务的任务ID
    16  	TaskNum int           //节点同时最大处理任务数量
    17  	Pid     peer.ID       //节点ID
    18  	Index   int           // 节点在任务列表中索引,方便下载失败后,把该节点从下载列表中删除
    19  	Latency time.Duration // 任务所在节点的时延
    20  	mtx     sync.Mutex
    21  }
    22  
    23  //Len size of the Invs data
    24  func (t tasks) Len() int {
    25  	return len(t)
    26  }
    27  
    28  //Less Sort from low to high
    29  func (t tasks) Less(a, b int) bool {
    30  	return t[a].Latency < t[b].Latency
    31  }
    32  
    33  //Swap  the param
    34  func (t tasks) Swap(a, b int) {
    35  	t[a], t[b] = t[b], t[a]
    36  }
    37  
    38  func (t tasks) Remove(task *taskInfo) tasks {
    39  	task.mtx.Lock()
    40  	defer task.mtx.Unlock()
    41  	if task.Index+1 > t.Size() {
    42  		return t
    43  	}
    44  
    45  	t = append(t[:task.Index], t[task.Index+1:]...)
    46  	return t
    47  }
    48  
    49  func (t tasks) Sort() tasks {
    50  	sort.Sort(t)
    51  	return t
    52  }
    53  
    54  func (t tasks) Size() int {
    55  	return len(t)
    56  }
    57  
    58  func (p *Protocol) initJob(pids []string, jobID string) tasks {
    59  	var JobPeerIds tasks
    60  	var pIDs []peer.ID
    61  	for _, pid := range pids {
    62  		pID, err := peer.Decode(pid)
    63  		if err != nil {
    64  			log.Error("initJob", "IDB58Decode", err)
    65  			continue
    66  		}
    67  		pIDs = append(pIDs, pID)
    68  	}
    69  	if len(pIDs) == 0 {
    70  		pIDs = p.ConnManager.FetchConnPeers()
    71  
    72  	}
    73  
    74  	for _, pID := range pIDs {
    75  		if pID == p.Host.ID() {
    76  			continue
    77  		}
    78  		var job taskInfo
    79  		job.Pid = pID
    80  		job.ID = jobID
    81  		job.Latency = p.Host.Peerstore().LatencyEWMA(pID)
    82  		if job.Latency == 0 { //如果查询不到节点对应的时延,就设置非常大
    83  			job.Latency = time.Second
    84  		}
    85  		job.TaskNum = 0
    86  		JobPeerIds = append(JobPeerIds, &job)
    87  	}
    88  	return JobPeerIds
    89  }
    90  
    91  func (p *Protocol) checkTask(taskID string, pids []string, faildJobs map[string]interface{}) {
    92  
    93  	select {
    94  	case <-p.Ctx.Done():
    95  		log.Warn("checkTask", "process", "done+++++++")
    96  		return
    97  	default:
    98  		break
    99  	}
   100  	v, ok := faildJobs[taskID]
   101  	if !ok {
   102  		return
   103  	}
   104  	defer delete(faildJobs, taskID)
   105  
   106  	faildJob := v.(map[int64]bool)
   107  	for blockheight := range faildJob {
   108  		jobS := p.initJob(pids, taskID)
   109  		log.Warn("checkTask<<<<<<<<<<", "taskID", taskID, "faildJob", blockheight)
   110  		p.downloadBlock(blockheight, jobS)
   111  
   112  	}
   113  }
   114  
   115  func (p *Protocol) availbTask(ts tasks, blockheight int64) *taskInfo {
   116  
   117  	var limit int
   118  	if len(ts) > 10 {
   119  		limit = 20 //节点数大于10,每个节点限制最大下载任务数为20个
   120  	} else {
   121  		limit = 50 //节点数较少,每个节点节点最大下载任务数位50个
   122  	}
   123  	for i, task := range ts {
   124  		//check blockHeight
   125  		peerHeight := p.PeerInfoManager.PeerHeight(task.Pid)
   126  		if peerHeight < blockheight {
   127  			continue
   128  		}
   129  		task.mtx.Lock()
   130  		if task.TaskNum < limit {
   131  			task.TaskNum++
   132  			task.Index = i
   133  			log.Debug("getFreeJob", " taskNum", task.TaskNum, "latency", task.Latency, "peerid", task.Pid)
   134  			task.mtx.Unlock()
   135  
   136  			return task
   137  		}
   138  		task.mtx.Unlock()
   139  	}
   140  
   141  	return nil
   142  
   143  }
   144  
   145  func (p *Protocol) releaseJob(js *taskInfo) {
   146  	js.mtx.Lock()
   147  	defer js.mtx.Unlock()
   148  	js.TaskNum--
   149  	if js.TaskNum < 0 {
   150  		js.TaskNum = 0
   151  	}
   152  }