造个轮子任务调度执行小框架任务执行器代理实现

2023年 8月 13日 60.9k 0

前言

不知道为啥,今天好像学不进去,没办法,那就继续编码吧。那么今天的话,加更一篇文章,那就是咱们这个任务执行器的实现。先前我们是实现到了这个部分,那么现在的话,我们实现的是这个部分。(ps:文末看到项目地址):
在这里插入图片描述

蓝色部分的内容,当然这个是完整的执行器,因此对于生命周期也会进行实现,不过在这里的话,发现先前的这个生命周期实在是冗余了,所以的话砍掉了部分内容,这部分主要是在这里:
在这里插入图片描述

这里的内容进行了简化,所以的话,使用起来看起来就没有那么吓人了。同样的这里还提供了这个简单实现的Handler,如果你需要高度定制化,那就直接实现这个接口,不要的话就继承这个handler类就可以了。当然在这个里面其实也没干啥:
在这里插入图片描述

执行器代理

okey,那么我们来看到我们的一个今天的内容吧,我们昨天的话是实现了这个,创建这个清单模板。那么接下来我们要做的就是通过这个清单模板,去创建代理执行对象,然后通过这个代理执行对象,去完成这个对应的操作。所以这里的话其实还是分为两个部分。

  • 通过任务清单模板,去创建代理对象
  • 在代理对象的基础上,我们去实现这一的一个周期
    当然现在的话,我们实现的是这个代理对象。
  • 代理对象

    ok,我们先来看到我们的代理对象。
    在这里的话我们有两个代理对象:
    在这里插入图片描述

    任务清单代理对象

    首先的话,是我们的任务清单代理对象:

    package com.huterox.todoscheduler.core.execute.proxy;
    
    import com.huterox.todoscheduler.core.enumType.TodoListElementType;
    import com.huterox.todoscheduler.core.enumType.TodoListStateType;
    import com.huterox.todoscheduler.core.wapper.ListStateWrapper;
    import com.huterox.todoscheduler.handler.*;
    
    import java.io.Serializable;
    import java.util.Comparator;
    import java.util.Map;
    import java.util.TreeMap;
    
    /**
     * 任务清单对象,这里记录的是基本的清单对象信息,
     * */
    public class TodoListExBean implements Serializable {
    
        //任务清单类型
        public TodoListElementType todoListElementType;
    
        //任务清单的名字
        public String todoListName;
    
        //当前的状态,当然服务宕机恢复任务的时候,这个是一个很重要的凭证
        public TodoListStateType todoListStateType;
    
        //任务清单的状态信息
        private ListStateWrapper stateWrapper;
    
        //执行的次数,因为有失败重新执行的东东
        private int exTimes;
    
    
    
        /*
        * 因为几个清单可能服务同一个用户,所以按照这个再给你分个类
        * 对于ClsId相同的清单是顺序执行的,所以这个是最小颗粒度的操作
        * */
        public String ClsId;
        TodoListErrorHandler todoListErrorHandler;
        TodoListAfterHandler todoListAfterHandler;
        TodoListBeforeCreateHandler todoListCreateCheckHandler;
    
    
        private final Comparator keyComparator = new Comparator() {
            @Override
            public int compare(Integer key1, Integer key2) {
                // 根据键的大小进行比较
                return key1.compareTo(key2);
            }
        };
        //对应执行的方法链路
        private final Map sortedMap = new TreeMap(keyComparator);
    
        public TodoListExBean() {
        }
    
        public TodoListExBean(TodoListElementType todoListElementType, String todoListName, TodoListErrorHandler todoListErrorHandler, TodoListAfterHandler todoListAfterHandler, TodoListBeforeCreateHandler todoListCreateCheckHandler) {
            this.todoListElementType = todoListElementType;
            this.todoListName = todoListName;
            this.todoListErrorHandler = todoListErrorHandler;
            this.todoListAfterHandler = todoListAfterHandler;
            this.todoListCreateCheckHandler = todoListCreateCheckHandler;
        }
    
        @Override
        public String toString() {
            return "The TodoList name is:"+this.todoListName;
        }
    
        public int getExTimes() {
            return exTimes;
        }
    
        public void setExTimes(int exTimes) {
            this.exTimes = exTimes;
        }
    
        public TodoListExBean(String todoListName) {
            this.todoListName = todoListName;
        }
    
        public TodoListStateType getTodoListStateType() {
            return todoListStateType;
        }
    
    
    
        public void setTodoListStateType(TodoListStateType todoListStateType) {
            this.todoListStateType = todoListStateType;
        }
    
        public ListStateWrapper getStateWrapper() {
            return stateWrapper;
        }
    
        public void setStateWrapper(ListStateWrapper stateWrapper) {
            this.stateWrapper = stateWrapper;
        }
    
        public Comparator getKeyComparator() {
            return keyComparator;
        }
    
        public Map getSortedMap() {
            return sortedMap;
        }
    
        public TodoListExBean(String todoListName, String clsId) {
            this.todoListName = todoListName;
            ClsId = clsId;
        }
    
        public TodoListElementType getTodoListElementType() {
            return todoListElementType;
        }
    
        public void setTodoListElementType(TodoListElementType todoListElementType) {
            this.todoListElementType = todoListElementType;
        }
    
        public String getTodoListName() {
            return todoListName;
        }
    
        public String getClsId() {
            return ClsId;
        }
    
        public void setClsId(String clsId) {
            ClsId = clsId;
        }
    
        public void setTodoListName(String todoListName) {
            this.todoListName = todoListName;
        }
    
        public TodoListErrorHandler getTodoListErrorHandler() {
            return todoListErrorHandler;
        }
    
        public void setTodoListErrorHandler(TodoListErrorHandler todoListErrorHandler) {
            this.todoListErrorHandler = todoListErrorHandler;
        }
    
        public TodoListAfterHandler getTodoListAfterHandler() {
            return todoListAfterHandler;
        }
    
        public void setTodoListAfterHandler(TodoListAfterHandler todoListAfterHandler) {
            this.todoListAfterHandler = todoListAfterHandler;
        }
    
        public TodoListBeforeCreateHandler getTodoListCreateCheckHandler() {
            return todoListCreateCheckHandler;
        }
    
        public void setTodoListCreateCheckHandler(TodoListBeforeCreateHandler todoListCreateCheckHandler) {
            this.todoListCreateCheckHandler = todoListCreateCheckHandler;
        }
    
    
    }
    
    

    任务清单执项对象

    然后的话,是我们的一个任务清单的执行项:

    package com.huterox.todoscheduler.core.execute.proxy;
    
    
    import com.huterox.todoscheduler.core.enumType.TodoItemElementType;
    import com.huterox.todoscheduler.core.enumType.TodoItemStateType;
    import com.huterox.todoscheduler.core.wapper.ItemStateWrapper;
    import com.huterox.todoscheduler.handler.*;
    
    import java.io.Serializable;
    import java.lang.reflect.Method;
    
    /**
     * 任务清单对应的Item,这里记录的是这个Item基本的信息
     * */
    public class TodoItemExBean implements Serializable {
    
        //任务清单项类型
        public TodoItemElementType todoItemElementType;
    
        //任务执行顺序
        public int order;
    
        //这是第几个清单的方法
        private int idx;
    
        //实例对象
        private Object wrapperInstance;
        //对应的class
        private Class wrapperClass;
        //对应的方法
        private Method wrapperMethod;
    
        //当前的状态,当然服务宕机恢复任务的时候,这个是一个很重要的凭证
        public TodoItemStateType todoItemStateType;
    
        TodoItemBeforeCreateHandler todoItemCreateHandler;
        TodoItemAfterRunningHandler todoItemAfterRunningHandler;
        TodoItemBeforeRunningHandler todoItemBeforeRunningHandler;
        TodoItemErrorHandler todoItemErrorHandler;
    
        private ItemStateWrapper stateWrapper;
    
        public TodoItemExBean() {
            //初始化的时候就进行创建
            this.stateWrapper = new ItemStateWrapper();
        }
    
        public TodoItemExBean(int order) {
            this.order = order;
        }
    
        public ItemStateWrapper getStateWrapper() {
            return stateWrapper;
        }
    
        public void setStateWrapper(ItemStateWrapper stateWrapper) {
            this.stateWrapper = stateWrapper;
        }
    
    
        public Object getWrapperInstance() {
            return wrapperInstance;
        }
    
        public void setWrapperInstance(Object wrapperInstance) {
            this.wrapperInstance = wrapperInstance;
        }
    
        public Class getWrapperClass() {
            return wrapperClass;
        }
    
        public void setWrapperClass(Class wrapperClass) {
            this.wrapperClass = wrapperClass;
        }
    
        public Method getWrapperMethod() {
            return wrapperMethod;
        }
    
        public void setWrapperMethod(Method wrapperMethod) {
            this.wrapperMethod = wrapperMethod;
        }
    
        public TodoItemStateType getTodoItemStateType() {
            return todoItemStateType;
        }
    
        public void setTodoItemStateType(TodoItemStateType todoItemStateType) {
            this.todoItemStateType = todoItemStateType;
        }
    
        public int getIdx() {
            return idx;
        }
    
        public void setIdx(int idx) {
            this.idx = idx;
        }
    
    
        @Override
        public String toString() {
            return "the order is "+this.order;
        }
    
        public TodoItemExBean(TodoItemElementType todoItemElementType, int order, TodoItemBeforeCreateHandler todoItemCreateHandler, TodoItemAfterRunningHandler todoItemAfterRunningHandler, TodoItemBeforeRunningHandler todoItemBeforeRunningHandler, TodoItemErrorHandler todoItemErrorHandler) {
            this.todoItemElementType = todoItemElementType;
            this.order = order;
            this.todoItemCreateHandler = todoItemCreateHandler;
            this.todoItemAfterRunningHandler = todoItemAfterRunningHandler;
            this.todoItemBeforeRunningHandler = todoItemBeforeRunningHandler;
            this.todoItemErrorHandler = todoItemErrorHandler;
        }
    
        public TodoItemElementType getTodoItemElementType() {
            return todoItemElementType;
        }
    
        public void setTodoItemElementType(TodoItemElementType todoItemElementType) {
            this.todoItemElementType = todoItemElementType;
        }
    
        public int getOrder() {
            return order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
    
        public TodoItemBeforeCreateHandler getTodoItemCreateHandler() {
            return todoItemCreateHandler;
        }
    
        public void setTodoItemCreateHandler(TodoItemBeforeCreateHandler todoItemCreateHandler) {
            this.todoItemCreateHandler = todoItemCreateHandler;
        }
    
        public TodoItemAfterRunningHandler getTodoItemAfterRunningHandler() {
            return todoItemAfterRunningHandler;
        }
    
        public void setTodoItemAfterRunningHandler(TodoItemAfterRunningHandler todoItemAfterRunningHandler) {
            this.todoItemAfterRunningHandler = todoItemAfterRunningHandler;
        }
    
        public TodoItemBeforeRunningHandler getTodoItemBeforeRunningHandler() {
            return todoItemBeforeRunningHandler;
        }
    
        public void setTodoItemBeforeRunningHandler(TodoItemBeforeRunningHandler todoItemBeforeRunningHandler) {
            this.todoItemBeforeRunningHandler = todoItemBeforeRunningHandler;
        }
    
        public TodoItemErrorHandler getTodoItemErrorHandler() {
            return todoItemErrorHandler;
        }
    
        public void setTodoItemErrorHandler(TodoItemErrorHandler todoItemErrorHandler) {
            this.todoItemErrorHandler = todoItemErrorHandler;
        }
    
    }
    
    

    处理handler对象

    然后在这里的话,可以看到这里还有很多Handler,这个东西,就是我们一开始看到的东西,因为我们接下来要实现一个完整的代理执行周期,因此我们必须拿到这些东西。然后进行执行。这里的话我们可以先看到我们的一个执行:在这里插入图片描述

    所以的话,这里要注意,我们为什么这里有那么多Handler。

    状态对象

    之后的话,是我们的一个状态,在执行方法的时候,我们可以保持到清单的一个状态,还有每一个清单项的状态,你都可以拿到。那么这里的话,主要是因为这个接口:
    在这里插入图片描述
    你要实现的方法里面带有这个,然后在后期执行代码的时候,我们会把这个对象给你,你可以看到这个:
    在这里插入图片描述

    代理工厂

    okey,那么接下来就是我们的代理工厂的实现了。
    那么同样的,我们当然有两个代理工厂了,一个是关于任务清单的,还有一个是关于任务项的。

    任务清单代理工厂

    先来看到我们的任务清单代理工厂:

    package com.huterox.todoscheduler.core.execute;
    
    import com.huterox.todoscheduler.core.enumType.TodoListStateType;
    import com.huterox.todoscheduler.core.execute.proxy.TodoItemExBean;
    import com.huterox.todoscheduler.core.execute.proxy.TodoListExBean;
    import com.huterox.todoscheduler.core.global.TodoListTemplateMap;
    import com.huterox.todoscheduler.core.wapper.TodoItemMethodWrapper;
    import com.huterox.todoscheduler.core.wapper.TodoListWrapper;
    import com.huterox.todoscheduler.exception.TodoListException;
    import com.huterox.todoscheduler.handler.TodoListBeforeCreateHandler;
    
    import java.io.Serializable;
    import java.util.Map;
    
    /**
     * 创建真正的任务执行清单对象,
     * 通过这个ToDoListBean的信息来进行创建
     * */
    public class TodoListFactory implements Serializable {
    
        /**
         *   创建可以执行的清单对象,然后对执行器就会执行这个对象,执行的是TodoListExBean
         *   如果返回结果为null,说明连这个清单都没有
         * */
    
        public static TodoListExBean getInstance(String listName) {
            TodoListExBean todoListExBean = new TodoListExBean();
    
            if(!TodoListTemplateMap.getInstance().containKey(listName)){
                new TodoListException("未找到任务清单失败:"+listName,-1).printStackTrace();
                todoListExBean.setTodoListStateType(TodoListStateType.CreatFailed);
                return null;
            }
            //先获取到清单的模板
            TodoListWrapper todoListTemplate = TodoListTemplateMap.getInstance().get(listName);
    
            todoListExBean.setTodoListName(todoListTemplate.getTodoListName());
            todoListExBean.setTodoListAfterHandler(todoListTemplate.getTodoListAfterHandler());
            todoListExBean.setTodoListCreateCheckHandler(todoListTemplate.getTodoListCreateCheckHandler());
            todoListExBean.setTodoListErrorHandler(todoListTemplate.getTodoListErrorHandler());
    
            //执行创建前的方法
            if(todoListExBean.getTodoListCreateCheckHandler()!=null){
                try {
                    TodoListBeforeCreateHandler todoListCreateCheckHandler = todoListExBean.getTodoListCreateCheckHandler();
                    //先执行这个获取ClsID的方法
                    try {
                        String s = todoListCreateCheckHandler.setCIds();
                        if(!("".equals(s))){
                            todoListExBean.setClsId(s);
                        }else {
                            todoListExBean.setClsId("");
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                        todoListExBean.setTodoListStateType(TodoListStateType.CreatFailed);
                        return todoListExBean;
                    }
                }catch (Exception exception){
                    exception.printStackTrace();
                    todoListExBean.setTodoListStateType(TodoListStateType.CreatFailed);
                    return todoListExBean;
                }
            }
    
            //遍历模板,然后将可执行的清单项放在我们的这个TodoListBeanEx的执行项目里面
    
            Map sortedMapEx = todoListExBean.getSortedMap();
    
            Map sortedMap = todoListTemplate.getSortedMap();
            for(Map.Entry sortedMapEntry:sortedMap.entrySet()){
                TodoItemMethodWrapper mapEntryValue = sortedMapEntry.getValue();
                Integer key = sortedMapEntry.getKey();
                TodoItemExBean instance = TodoItemFactory.getInstance(mapEntryValue,todoListExBean);
                if(instance==null){
                    //如果这个清单项创建失败,那也是失败
                    return null;
                }
                sortedMapEx.put(key,instance);
    
            }
            //此时创建完毕,但是这里每一个方法如何执行,也就是清单项是调度器考虑的事情了
            return todoListExBean;
        }
    }
    
    

    通过这个来创建到我们的清单

    清单任务项代理工厂

    之后是这个,一个清单里面包含了很多的这个执行项,因为本质上,一个执行项就是一个类方法嘛。

    package com.huterox.todoscheduler.core.execute;
    
    import com.huterox.todoscheduler.annotate.*;
    import com.huterox.todoscheduler.core.enumType.TodoItemElementType;
    import com.huterox.todoscheduler.core.execute.proxy.TodoItemExBean;
    import com.huterox.todoscheduler.core.execute.proxy.TodoListExBean;
    import com.huterox.todoscheduler.core.wapper.TodoItemMethodWrapper;
    import com.huterox.todoscheduler.handler.TodoItemAfterRunningHandler;
    import com.huterox.todoscheduler.handler.TodoItemBeforeCreateHandler;
    import com.huterox.todoscheduler.handler.TodoItemBeforeRunningHandler;
    import com.huterox.todoscheduler.handler.TodoItemErrorHandler;
    
    import java.io.Serializable;
    import java.lang.reflect.Method;
    
    /**
     * 负责将方法解析出来
     * */
    public class TodoItemFactory implements Serializable {
    
        //当这个方法返回null的时候,说明创建失败
        public static TodoItemExBean getInstance(TodoItemMethodWrapper todoItemMethodWrapper, TodoListExBean todoListExBean){
    
            TodoItemExBean todoItemExBean = new TodoItemExBean();
            todoItemExBean.setOrder(todoItemMethodWrapper.getOrder());
            todoItemExBean.setTodoItemElementType(todoItemMethodWrapper.getTodoItemElementType());
            todoItemExBean.setIdx(todoItemMethodWrapper.getIdx());
            todoItemExBean.setWrapperMethod(todoItemMethodWrapper.getWrapperMethod());
            todoItemExBean.setWrapperClass(todoItemMethodWrapper.getWrapperClass());
            todoItemExBean.setWrapperInstance(todoItemMethodWrapper.getWrapperInstance());
    
            //解析注解
            Method wrapperMethod = todoItemMethodWrapper.getWrapperMethod();
            wrapperMethod.setAccessible(true);
            if(wrapperMethod.isAnnotationPresent(TodoItemBeforeCreate.class)){
                //这个时候要先去执行一下这个初始化创建的代码
                TodoItemBeforeCreate annotationTodoItemBeforeCreate = wrapperMethod.getAnnotation(TodoItemBeforeCreate.class);
                Class[] todoItemBeforeCreates = annotationTodoItemBeforeCreate.todoItemBeforeCreates();
                Class todoItemBeforeCreateHandlerClass = todoItemBeforeCreates[todoItemExBean.getIdx()];
                try {
                    TodoItemBeforeCreateHandler todoItemBeforeCreateHandler = todoItemBeforeCreateHandlerClass.newInstance();
                    //把这个状态Wrapper给它,这个时候是直接执行这个家伙
                    try {
                        todoItemBeforeCreateHandler.concierge(todoItemExBean.getStateWrapper(),todoListExBean.getStateWrapper());
                    }catch (Exception e){
                        //判断一下类型,是属于哪一种,是那种可以跳过执行的清单项
                        if(todoItemExBean.getTodoItemElementType()== TodoItemElementType.CONTINUTEITEM){
                            //继续happy执行往下走继续
                            System.err.println("当前清单项创建失败执行方法:"+wrapperMethod.getName()
                                            +"对应的类为:"+todoItemExBean.getWrapperClass().getName()
                                    );
                            e.printStackTrace();
                        }else {
                            //不能继续往下happy了,直接先执行修复
                            try {
                                todoItemBeforeCreateHandler.repair(todoItemExBean.getStateWrapper(),todoListExBean.getStateWrapper());
                            }catch (Exception e1){
                                //连修复都G了,没了
                                e1.printStackTrace();
                            }
                            return null;
                        }
                        //还是必须要强制执行的清单项
                        e.printStackTrace();
                    }
    
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
    
            if(wrapperMethod.isAnnotationPresent(TodoItemBefore.class)){
                TodoItemBefore annotationTodoItemBefore = wrapperMethod.getAnnotation(TodoItemBefore.class);
                Class[] todoItemBeforeRunningHandlerClasses = annotationTodoItemBefore.todoItemBefores();
                Class todoItemBeforeRunningHandlerClass = todoItemBeforeRunningHandlerClasses[todoItemExBean.getIdx()];
                TodoItemBeforeRunningHandler todoItemBeforeRunningHandler = null;
                try {
                    todoItemBeforeRunningHandler = todoItemBeforeRunningHandlerClass.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                    return null;
                }
                todoItemExBean.setTodoItemBeforeRunningHandler(todoItemBeforeRunningHandler);
            }
    
            if(wrapperMethod.isAnnotationPresent(TodoItemAfterHandler.class)){
                TodoItemAfterHandler annotationTodoItemAfterHandler = wrapperMethod.
                        getAnnotation(TodoItemAfterHandler.class);
    
                Class[] todoItemAfterRunningHandleClasses = annotationTodoItemAfterHandler.
                        todoItemAfterHandlers();
    
                Class todoItemAfterRunningHandleClass = todoItemAfterRunningHandleClasses[todoItemExBean.getIdx()];
    
                TodoItemAfterRunningHandler todoItemAfterRunningHandler = null;
                try {
                    todoItemAfterRunningHandler = todoItemAfterRunningHandleClass.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                    return null;
                }
                todoItemExBean.setTodoItemAfterRunningHandler(todoItemAfterRunningHandler);
            }
    
            if(wrapperMethod.isAnnotationPresent(TodoItemError.class)) {
                TodoItemError annotationTodoItemError = wrapperMethod.getAnnotation(TodoItemError.class);
                Class[] todoItemErrorHandlerClasses = annotationTodoItemError.todoItemErrors();
                Class todoItemErrorHandlerClass = todoItemErrorHandlerClasses[todoItemExBean.getIdx()];
                TodoItemErrorHandler todoItemErrorHandler = null;
                try {
                    todoItemErrorHandler = todoItemErrorHandlerClass.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                    return null;
                }
                todoItemExBean.setTodoItemErrorHandler(todoItemErrorHandler);
            }
    
            //此时我们的清单项封装实例化完毕
            return todoItemExBean;
        }
    }
    
    

    总结

    那么到这里,我们就完成了这个任务清单的代理实现。当然这里面用到了很多的一些Wrapper类,但是核心就是上面说到的东西。

    之后的话,通过差不多天半的开发:我们(团队成员the only one is me) 完成了这个项目的开发,现在的话在写这个开发教程。所以今天的话,大概是有3更。本来是说慢慢做的,但是发现有这个事情,然后每天写一点的话不连贯。重新想的时候好慢,所以没有办法,今天是特意专门拿出一天的时间拿过来开发。因为昨天干到两点,没啥精神,考研的话看不下去。一直有心事,压在身上很不舒服。

    然后项目地址:gitee.com/Huterox/hto… 当然这里面还有很多工作要做,只是核心功能做好了。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论