-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Description
这算是一个前瞻抽象。
也就是我们单独把抢占和释放这个过程抽象出来。大体上的接口设计是:
type Preempter struct {
Preempt(ctx context.Context) (Task, cancelFunc, error)
}这种设计类似于 Context 的设计,要求返回一个 cancelFunc,它的效果是:
- 在调用 Preempt 的时候,会执行抢占,抢占之后 Preempt 会自动续约,也就是说,Scheduler 不再管理续约的事情;
- 当 Scheduler 运行完任务,或者出现异常需要让出这个状态的时候,就调用 cancelFunc
这种优势是非常简单,并且将抢占、续约和释放的逻辑内聚到了一起。但是这种形态有一个缺陷,即调用者没有办法知道是否续约失败了,缺乏一个机制通知调用者续约失败了。
另外一种可行的设计是:
type Preempter interface {
Preempt(ctx context.Context) (Task, error)
AutoRefresh(ctx, tid) (chan error, error)
Release(ctx, tid) error
}那么对于调用者来说,用起来的感觉就是:
t, err := p.Preempt(ctx)
// 要开一个 Goroutine
errChan, err := p.AutoRefresh()
refreshErr := <- errChan // 续约失败
// 搞完了。
p.Release()从实践上来说,大部分用户不知道怎么处理续约失败的场景(比如说我们 Scheduler 通知用户说续约失败,他们都不能理解这个概念)。所以第一种设计,并不是不可接受。
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels