Golang实现对异步任务执行状态和结果的获取

472 阅读1分钟

公有云有不少变更接口,都是异步执行。

提交变更请求后,需要持续获取任务执行过程和结果

如何抽象设计该场景需求

定义异步任务、启动异步任务、获取异步任务状态和结果 调用抽象逻辑

异步任务处理


// TaskStatus 表示任务的状态
type TaskStatus struct {
   Progress  int
   Completed bool
   Error     error
}

// AsyncTask 表示异步任务本身
type AsyncTask struct {
   StatusChan chan TaskStatus // 任务状态,类型 channel TaskStatus
   ResultChan chan string     // 任务结果,类型 channel string
}

// taskFunction 定义异步任务执行的函数签名
type taskFunction func(chan TaskStatus, chan string)

// StartAsyncTask 创建并开始一个新的异步任务
// 入参:taskFunc 函数「任务状态,类型 channel TaskStatus;任务结果,类型 channel string」
func StartAsyncTask(taskFunc taskFunction) *AsyncTask {
   task := &AsyncTask{
      StatusChan: make(chan TaskStatus),
      ResultChan: make(chan string),
   }

   go taskFunc(task.StatusChan, task.ResultChan) // 在新的goroutine中运行任务逻辑

   return task
}

// Monitor 监控 AsyncTask 的执行状态和结果
func (t *AsyncTask) Monitor() {
   for {
      select {
      case status := <-t.StatusChan:
         fmt.Printf("Progress: %d%%\n", status.Progress)
         if status.Completed {
            close(t.StatusChan)
            close(t.ResultChan)
            return
         }
      case result := <-t.ResultChan:
         fmt.Printf("Result: %s\n", result)
         return
      }
   }
}

调用&使用

任务定义

传入任务状态以及结果


func taskFunc(statusChan chan util.TaskStatus, resultChan chan string) {
   totalSteps := 10
   for i := 1; i <= totalSteps; i++ {
      time.Sleep(1 * time.Second)
      statusChan <- util.TaskStatus{Progress: i * 10}
   }
   resultChan <- "Task Finished Successfully"
}

启动任务、打印获取任务状态和结果


func TestAsyncTaskStatus(t *testing.T) {

   // 启动任务
   task := util.StartAsyncTask(taskFunc)
   task.Monitor()
}