github.com/qjfoidnh/BaiduPCS-Go@v0.0.0-20231011165705-caa18a3765f3/pcsutil/taskframework/executor.go (about) 1 package taskframework 2 3 import ( 4 "github.com/GeertJohan/go.incremental" 5 "github.com/oleiade/lane" 6 "github.com/qjfoidnh/BaiduPCS-Go/pcsutil/waitgroup" 7 "strconv" 8 "time" 9 ) 10 11 type ( 12 TaskExecutor struct { 13 incr *incremental.Int // 任务id生成 14 deque *lane.Deque // 队列 15 parallel int // 任务的最大并发量 16 17 // 是否统计失败队列 18 IsFailedDeque bool 19 failedDeque *lane.Deque 20 } 21 ) 22 23 func NewTaskExecutor() *TaskExecutor { 24 return &TaskExecutor{} 25 } 26 27 func (te *TaskExecutor) lazyInit() { 28 if te.deque == nil { 29 te.deque = lane.NewDeque() 30 } 31 if te.incr == nil { 32 te.incr = &incremental.Int{} 33 } 34 if te.parallel < 1 { 35 te.parallel = 1 36 } 37 if te.IsFailedDeque { 38 te.failedDeque = lane.NewDeque() 39 } 40 } 41 42 // 设置任务的最大并发量 43 func (te *TaskExecutor) SetParallel(parallel int) { 44 te.parallel = parallel 45 } 46 47 //Append 将任务加到任务队列末尾 48 func (te *TaskExecutor) Append(unit TaskUnit, maxRetry int) *TaskInfo { 49 te.lazyInit() 50 taskInfo := &TaskInfo{ 51 id: strconv.Itoa(te.incr.Next()), 52 maxRetry: maxRetry, 53 } 54 unit.SetTaskInfo(taskInfo) 55 te.deque.Append(&TaskInfoItem{ 56 Info: taskInfo, 57 Unit: unit, 58 }) 59 return taskInfo 60 } 61 62 //AppendNoRetry 将任务加到任务队列末尾, 不重试 63 func (te *TaskExecutor) AppendNoRetry(unit TaskUnit) { 64 te.Append(unit, 0) 65 } 66 67 //Count 返回任务数量 68 func (te *TaskExecutor) Count() int { 69 if te.deque == nil { 70 return 0 71 } 72 return te.deque.Size() 73 } 74 75 //Execute 执行任务 76 func (te *TaskExecutor) Execute() { 77 te.lazyInit() 78 79 for { 80 wg := waitgroup.NewWaitGroup(te.parallel) 81 for { 82 e := te.deque.Shift() 83 if e == nil { // 任务为空 84 break 85 } 86 87 // 获取任务 88 task := e.(*TaskInfoItem) 89 wg.AddDelta() 90 91 go func(task *TaskInfoItem) { 92 defer wg.Done() 93 94 result := task.Unit.Run() 95 96 // 返回结果为空 97 if result == nil { 98 task.Unit.OnComplete(result) 99 return 100 } 101 102 if result.Succeed { 103 task.Unit.OnSuccess(result) 104 task.Unit.OnComplete(result) 105 return 106 } 107 108 // 需要进行重试 109 if result.NeedRetry { 110 // 重试次数超出限制 111 // 执行失败 112 if task.Info.IsExceedRetry() { 113 task.Unit.OnFailed(result) 114 if te.IsFailedDeque { 115 // 加入失败队列 116 te.failedDeque.Append(task) 117 } 118 task.Unit.OnComplete(result) 119 return 120 } 121 task.Info.retry++ // 增加重试次数 122 task.Unit.OnRetry(result) // 调用重试 123 task.Unit.OnComplete(result) 124 125 time.Sleep(task.Unit.RetryWait()) // 等待 126 te.deque.Append(task) // 重新加入队列末尾 127 return 128 } 129 130 // 执行失败 131 task.Unit.OnFailed(result) 132 if te.IsFailedDeque && result.Extra != "skip" { 133 // 加入失败队列 134 te.failedDeque.Append(task) 135 } 136 task.Unit.OnComplete(result) 137 }(task) 138 } 139 140 wg.Wait() 141 142 // 没有任务了 143 if te.deque.Size() == 0 { 144 break 145 } 146 } 147 } 148 149 //FailedDeque 获取失败队列 150 func (te *TaskExecutor) FailedDeque() *lane.Deque { 151 return te.failedDeque 152 } 153 154 //Stop 停止执行 155 func (te *TaskExecutor) Stop() { 156 157 } 158 159 //Pause 暂停执行 160 func (te *TaskExecutor) Pause() { 161 162 } 163 164 //Resume 恢复执行 165 func (te *TaskExecutor) Resume() { 166 }