公有云有不少变更接口,都是异步执行。
提交变更请求后,需要持续获取任务执行过程和结果
如何抽象设计该场景需求
定义异步任务、启动异步任务、获取异步任务状态和结果 调用抽象逻辑
异步任务处理
// 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()
}