量化交易系统任务框架的演化之路(3)基于多状态的任务依赖解决

量化交易系统任务框架的演化之路(2)状态管理中为任务引入了一个状态,解决了任务的重入问题,那么还有一个悬而未决的问题:如何解决任务之间的依赖关系?那么今天就来看看如何基于多状态解决任务直接的依赖关系。
假定有两个每天执行一次的任务A和B,任务B要在任务A的执行完毕后才能启动。在设计时,应该考虑到:

  1. 对于任务A来讲,任务B应该是透明,也就是说任务A不应该知道任务B的存在,这样即使任务B失效了或者不再需要任务B,也不会影响任务A的正常运行。
  2. 同时还应该考虑到任务状态的时效性,因为在业务场景中已经规定了A和B都是每天运行的,B的执行一定基于A的今天执行的结束,而不是之前的结束状态。

基于上面两点考虑,可以通过以下方案解决:为任务设定多个执行状态,并数据库存储任务的执行状态和执行时间。

状态定义:

public enum TaskStatusEnum {
    Running,     //正在执行
    Stopped,     //正常结束
    Error;       //发生异常
}

数据库定义(MySQL语法):

create table task_status(
    id           INT NOT NULL AUTO_INCREMENT,
    task         VARCHAR(20) NOT NULL UNIQUE
    comment '任务名称',
    status       VARCHAR(20)
    comment '任务状态,通过TaskStatusEnum定义'
    update_time  DATETIME
    comment '任务状态的最后更新时间',

    PRIMARY KEY(id)
);

实现的逻辑分为两部分

首先是独立的任务A的执行逻辑,这里面没有考虑重入的问题。

Created with Raphaël 2.1.2 开始 启动任务 更新数据库中状态和更新时间,status=Running 正常结束 更新数据库中状态和更新时间,status=Stopped 结束 更新数据库中状态和更新时间,status=Error yes no

接下来看依赖于A的任务B的执行过程

Created with Raphaël 2.1.2 开始 启动任务 从数据库中查询出A的任务状态 任务A的update_time > 任务B的update_time 任务A的 status == Stopped 执行和A一样的流程 结束 yes no yes no

通过一个简单的轮询机制配合A的状态持久化,咱们就可以解决任务之间的依赖问题,何况并且A和B还实现了一定程度的解耦。
在这种场景下轮询机制的效率是比较低的,尤其是任务比较多,依赖关系比较复杂的情况下,那么有没有比较高效的方法可以解决这个问题。

猜你喜欢

转载自blog.csdn.net/mydeman/article/details/80489986