转载

量化交易系统任务框架的演化之路(2)状态管理

在上一篇文章( 量化交易系统任务框架的演化之路(1)定时任务 )的结尾提了三个问题,今天就来第一版的解决方案。

之前的实现方案中,所有任务都是无状态、无管理的,人工干预就比较麻烦。其实解决这个问题的方法很简单,那就是增加一个“状态”,看一下这个流程图:

通过这个流程图就可以很明显的看出,重入的问题一下子就解决了。道理明白了,那么实现起来就很简单了。直接把框架代码放这里,供参考。

通过注解来表示是否为要管理的任务,在这里指定了一个属性name,管理容器可以很方便通过这个名字找到对应任务实例,完成一系列的操作。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface QuantManagedTask {
    String name();
}

下面这个类是所有任务的基类,里面包含了任务的框架方法,start方法用来启动任务,启动时会检查当前任务的状态,如果没有在执行则启动,否则直接跳过;stop方法用来停止任务。

public abstract class QuantTask {
    //任务状态
    private boolean isRunning = false;

    /**
     * 启动当前任务,改变状态,执行任务
     */
    public void start(){
        //任务已经在执行中,则直接返回
        if(isRunning):
           return;
        isRunning = true;
        doTask();
        //执行完毕后停止
        stop();
    }

    // 实际的任务内容
    public abstract void doTask();

    /**
     * 停止当前任务,改变状态
     */
    public void stop(){
        isRunning = false;
    }
    /**
     * 获取任务是否在执行中
     */
    public boolean isRunning(){
        return isRunning;
    }
}

下面就是任务的管理容器,容器负责任务的启动和结束。在系统启动时,会将所有通过注解标注和继承了QuantTask的任务类预先加载进来,建立任务名称和任务实例对应的Map,那么就可以很容易的通过名字找到相应的任务实例。

@Component
public class QuantTaskManager implements BeanPostProcessor{
    protected Map<String, QuantTask> nameTaskMap = new HashMap<>();

    @Override
    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
        if(bean instanceof QuantTask) {
            try {
                QuantTask task = (QuantTask) bean;

                QuantManagedTask quantManagedTask = AopUtils.getTargetClass(bean).getAnnotation(QuantManagedTask.class);
                nameTaskMap.put(quantManagedTask.name(), task);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return bean;
    }

    public void execute(String taskName) {
        nameTaskMap.get(taskName).start();
    }
}

下面这个就是一个示例任务类,可以直接通过其名字sample_task启动它。

@QuantManagedTask(name="sample_task")
public void SampleQuantTask extends QuantTask(){
    public void doTask(){
        //Do something
    }
}

增加了管理容器,我们就可以很容易的实现在页面上对任务进行管理的功能。当然了,这里只是通过一个isRunning字段解决了最简单的状态,可是有很多时候,状态可能更加复杂,尤其是在通过页面管理时,可能还要什么时候执行过、现在是什么状态等等。

现在还有一个任务依赖的问题还没有解决,那么如果基于上面的设计,应该如何去解决呢?

原文  https://blog.csdn.net/mydeman/article/details/80450677
正文到此结束
Loading...