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  }