Skip to content

任务机制

任务机制贯穿整个项目,在/pkg/task 目录下定义。任何逻辑在设计时,必须先考虑使用任务机制来实现,这样可以保证被观测,也可以捕获 panic 等等。

概念定义

继承

任务机制中,所有任务都是通过继承来实现的。 go语言没有继承,但可以通过嵌入来实现。

宏任务

宏任务又叫父任务,可以包含多个子任务的执行,本身也是一个任务。

子任务协程

每一个宏任务都会启动一个协程,用来执行子任务的 Start、 Run、 Dispose 方法。因此,拥有同一个父任务的子任务,可以避免并发执行问题。这个协程可能不会一开始就创建,也就是可能会是懒加载。

任务的定义

任务通常通过继承 task.Tasktask.Jobtask.Worktask.ChannelTasktask.TickTask 来定义。 例如:

go
type MyTask struct {
	task.Task
}
  • task.Task 是所有任务的基类,定义了任务的基本属性和方法。
  • task.Job 可包含子任务,子任务全部结束后,Job 会结束。
  • task.Work 同 Job,但子任务结束后,Work 会继续执行。
  • task.ChannelTask 自定义信号的任务,通过 覆盖 GetSignal 方法来实现。
  • task.TickTask 定时任务,继承自 task.ChannelTask ,通过 覆盖 GetTickInterval 方法来控制定时器间隔。

定义任务启动方法

通过定义一个方法 Start() error 来实现任务的启动。

其中返回的 error 可以用来判断任务是否启动成功。如果为空则代表任务成功启动了。否则代表启动失败(特殊情况,返回 Complete 代表任务完成)。

通常在 Start 中包含资源的创建,例如打开文件,建立网络连接等。

Start 方法是可选的,如果没有定义,则默认启动成功。

定义任务的执行过程

通过定义一个方法 Run() error 来实现任务的执行过程。

这个方法通常用来执行耗时操作,同时会阻塞父任务的子任务协程。

还有一个非阻塞的方式来运行耗时操作,就是定义 Go() error 方法。

error 返回的值如果是 nil 则代表任务执行成功,否则代表执行失败(特殊情况,返回 Complete 代表任务完成)。

Run 和 Go 也是可选的,如果不定义则任务会处于正在运行状态。

定义任务的销毁过程

通过定义一个方法 Dispose() 来实现任务的销毁过程。

这个方法通常用来释放资源,例如关闭文件,关闭网络连接等。

Dispose 方法也是可选的,如果没有定义,则任务结束不做任何操作。

钩子机制

通过 OnStart、OnBeforeDispose、OnDispose 方法来实现钩子机制。

等待任务开始和结束

通过 WaitStarted() 和 WaitStopped() 方法来实现等待任务开始和结束。这种方式会阻塞当前协程。

重试机制

通过设置 Task 的 RetryCount 和 RetryInterval 来实现重试机制。有一个设置方法,SetRetry(maxRetry int, retryInterval time.Duration)。

触发条件

  • 当 Start 失败时,会重试调用 Start 直到成功。

  • 当 Run 或者 Go 失败时,则会先调用 Dispose 释放资源后再调用 Start 开启重试流程。

终止条件

  • 当重试次数满了之后就不再重试了。
  • 当 Start 或者 Run、Go 返回 ErrStopByUser 、 ErrExit 、ErrTaskComplete 时,则终止重试。

启动一个任务

通过调用父任务的 AddTask 方法来启动一个任务。 不可以直接主动调用任务的 Start 方法。Start 方法必须是被父任务调用。

任务的停止

通过调用 Stop(err error) 方法来实现任务的停止。err 不能传入 nil。定义任务时不要覆盖 Stop 方法。

任务的停止原因

通过调用 StopReason() 方法可以检查任务的停止原因。

Call 方法

调用 Job 的 Call 会创建一个临时任务,用来在子任务协程中执行一个函数,通常用来访问 map 等需要防止并发读写的资源。由于该函数会在子任务协程中运行,因此不可以调用 WaitStarted 和 WaitStopped 以及其他阻塞协程的逻辑,否则会导致死锁。

基于 AGPL 许可发布