DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

流程引擎解析(1)

整个流程引擎应该分为三个部分,config, context组成构成process的基本部分,template作为整个process串联的基础,生成weavable,然后通过weavable,并辅助相关的scm的状态,最后拼接成一串的process节点,即完成整个流程的渲染过程。

  • 首先config方面,基本存储静态的变量,如key, name, description等,

    • 这里面有一个小技巧,由于config可以有多种的实现方式,于是其接口config只是定义基本的get方法,由各种实现去具体实现get方法,这样其他类来调用的时候,只需调用get方法就有取到相应的静态变量,而不需要特意在接口处定义变量。
      如下面所示

      1
      2
      3
      4
      5
      6
      public interface Config extends Serializable {
      public Integer getId();
      public String getKey();
      public String getName();

      }
  • 关于config的实现,现有2个基本的实现,一是commonConfig,即普通的节点的config,如申请四位版本,模块编译等,主要是scm的操作的一些process;另一种是actionConfig,即由baseinfo定义的一些action转化的process。这里有一个感想,针对我们后面的统一化管理,可以将这两种都归结于actionConfig,申请四位版本和模块编译等,都可以作为action来存储在icafe中,icafe在开发任务task中加入相关的action即可。

  • 然后是template部分。这里的template以baseinfo的模板作为基础,根据不同的任务,进行相关的操作,并生成weavable。这里的weavable,作为一个list,其实已经是简版的流程节点的串联,其包含相应的process的key以及process后需的节点的key和相应的type。

    • 以开发任务的action为例,首先是判断该action是否被裁剪掉了,来判断是否要加入到weavable中去;然后设置相应的weavable的key和weaveType;最后转化相应的action的信息,放入到configMap中去,方便后面调用。

    • 这里重点讲一下addOnline方面。

      • 首先对于上线部分,其作为一个大的task存在,这里有个小技巧,将task转化为action,从而可以同上面的addAction相同的处理
      1
      ActionConfigAdapter config = new ActionConfigAdapter(convert(task));
  • 其次,针对上线方式部分,采用获取从icafe中相关的上线方式,然后将相关action转化为sqaActionTemplate后,作为process的child节点加入到weavable中去.

      
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(ActionInfo act : actionInfos){
    String key = ConfigDataUtil.getKeyActionByProcssDefineId(act.getActionDefineid());
    w.setWeaveKey(key);
    w.setWeaveType(WeaveType.CHILD.name());
    weavables.add(w);

    ActionConfigAdapter actConfig = new ActionConfigAdapter(convert(act));
    configMap.put(key, actConfig);

    w = new Weavable();
    w.setKey(pk);
    }

这里有部分不能理解的是上线方式居然是从icafe中获取,而不是从baseinfo中获取。这里影射出icafe同baseinfo之间的关系若即若离,icafe既想同baseinfo切除关系,但是又很多的内容依赖于baseinfo,这层关系还需慢慢梳理,慢慢切除。

  • 完成了template部分的解析,就会得到两个比较重要的变量,即
    List<Weavable> weavablesMap<String, Config> configMap ,前者即为流程串联的list,后者为相关的config信息,后面就是weaver部分,这部分就是将这两者加入scm的一些辅助状态,一起串联成为我们所谓的process串。同样,这个串联过程大致分为三个部分:

    1. context的相关信息的初始化。前面讲到了context里存放着process的上下文环境,这里主要是一些scm的状态。这里拿到的是scmProcessContext,实际上映射着DefaultScmContext(吐槽一句:这个东西能不能相同命名,不然还需要去xml去寻找相应的对应关系,命令的规范遵循的是什么。。。),这里拿到codePath
      codeVersion,以及最重要的Map<String, ScmOperateBean> scmOperates但是,在这个串联的后续步骤中,个人感觉这个东西没有用到。。
    2. 随后便是遍历List<Weavable> weavables结构,首先从相关的configMap依据相应的weavable的key值取得相应的config,然后通过
    1
    process = (Process) applicationContext.getBean(beanName, Process.class);

来初始化相应的process,同时将process加入到Map<String, Process> processMap中。
随后,从processMap中选取第一个节点作为headProcess返回即可。

感想:

  • context这个变量的设计感觉毫无头绪。首先对于scmOperates的初始化,可以放在template的解析中,同样也是属于状态的解析;其次,对于processMap,依然可以放在template的解析中;这样导致就是process中的context变量还有没有意义?

  • 对于processMap的设计初衷是什么?既然是遍历weavables,然后按顺序将生成的process加入到processMap中去,为什么不继续复用weavables,而要另开一个map?

  • 对于SqaTaskTemplateAdapter这个结构的extends关系,感觉不是很理解,为后面的扩展性的需要有什么帮助?直接作为引擎的一个实现,这才是他的核心吧

  • 得到headProcess之后,然后就是processRender的工作。这方面没什么好说的。

至此,整个流程模板的渲染过程大致介绍完毕。下图是流程的介绍说明。