Open flycash opened 2 months ago
你这个想法有点奇怪,那要还是要有getTasks的抽象,把任务都查出来,进行探查或者抢占,然后就比较尴尬了,可能其他节点也会查出这个任务来
不会的,因为你抢占只会有一个节点抢占成功。你可以理解为,是在已有抢占成功的基础上,看看非正常释放任务,上一次有咩有执行完毕
目前main和dev都没办法跑起来,有能跑的分支吗?
类似这样吗?
if t.LastStatus == mysql.TaskStatusRunning {
// 根据 Task.ID 获取 execute id
execution, err := p.executionDAO.GetByTid(ctx, t.ID)
if err != nil {
return
}
// 再根据 eid 查询 上次执行情况
ch := exec.Explore(ctx, execution.ID, t)
select {
case res, ok := <-ch:
if !ok {
return
}
switch res.Status {
// 还在执行的任务
case executor.StatusRunning:
//TODO 只定时探查 不调度
return
default:
}
case <-ctx.Done():
return
}
}
// 正常调度 执行
是的。不过我们没有这个 LastStatus 的字段,理论上来说,我们抢占是先查询出来了 Task,而后再抢占,所以查询出来的状态本身就是 Running。抢占只是改了数据库的,但是已经查询出来的没改
在我们的主动探查机制里面,有一个问题: 假设说我当次任务在节点 A 上被调度,理论上来说,它也可以应该在 A 上探查。但是如果此时 A 节点宕机了,那么后续即使 A 节点恢复了,它也无法继续探查。因为目前我们的探查是基于内存实现的,虽然有执行记录,但是 A 节点恢复之后无法从执行记录里面找到哪些是自己需要继续探查的。
我们可以进一步借助抢占机制来解决这个问题。
在我们抢占的时候,有一个条件是如果一个任务已经被抢占了,但是更新时间超过了最大续约时间。换句话来说,没人给它续约。这个时候我们就有道理认为,这个节点之前抢占了这个任务,但是并没有正常释放。
这个时候,在找到这样一个任务之后,就要先去看一眼这个任务最近的一次执行记录,是否已经结束。如果没有结束,那么就要发起探查。而后根据结果来考虑: