Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Preempter 抽象 #21

@flycash

Description

@flycash

这算是一个前瞻抽象。

也就是我们单独把抢占和释放这个过程抽象出来。大体上的接口设计是:

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)
    Releasectx, tid) error
}

那么对于调用者来说,用起来的感觉就是:

 t, err := p.Preempt(ctx)

// 要开一个 Goroutine
errChan, err := p.AutoRefresh()
refreshErr := <- errChan // 续约失败

// 搞完了。
p.Release()

从实践上来说,大部分用户不知道怎么处理续约失败的场景(比如说我们 Scheduler 通知用户说续约失败,他们都不能理解这个概念)。所以第一种设计,并不是不可接受。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions