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 }