工作流系统之三十八 工作流软件中的定时器处理

工作流软件中的定时器处理,一般分为两种:

应用服务启动就启动的定时器

这种类型和通常的web系统中的定时器处理一样。应用服务器启动后,定时器就启动了,然后按照定制的时间段轮询处理。当应用服务器关闭的时候,这种定时器才会关闭。这种定时器通常是对所有需要定时处理的记录来做的,在工作流软件中,就对应到所有的业务流程,所有的流程实例。

这种类型的定时器,在报表软件,报表产品中经常有用到,比如 每天晚上定时生成按日汇总表,每个月未生成月结汇总表。在工作流软件系统中,可以利用这种定时器按计划启动业务流程的流程实例。按计划扫描执行那些过期需要自动处理的任务等等。


由流程的流转来启动定时器
当流程示例流转到某个节点时,启动这个节点的定时器,按定时器设置的时间间隔轮询执行处理。当流程流转流程实例离开这个节点了,这个定时器就关闭了。这种类型的定时器,和流程的特定节点关联,每个流程实例都会经历定时器的 启动->执行->关闭 这样整个过程。

在eworkflow工作流系统中 定时器有三种处理方式:
1. 应用服务器启动就启动的定时器。
2. 流程的节点中挂接的定时器。
3. 定制实现的定时器处理。

下面详解三种处理方式:
1. 应用服务器启动就启动的定时器。
  定时器的执行程序,轮询的间隔时间,以及相关参数设置都在fcconfig.xml文件中。
  当应用程序启动的时候,从fcconfig.xml中查找定时器的配置信息。根据配置信息启动定时器。
 
  一个典型的fcconfig.xml文件中的配置信息如下:
    <workflow-timer flowName="wf_series_timer" flowVersion="1" className="cn.com.fcsoft.workflow.timer.StartWorkflowJob">
  <cronExpression>0 0 1 * * ?</cronExpression>   
  <userId>USR_0000001</userId>
  <dsnName></dsnName>
  <triggerName>trigger:1</triggerName>
  <groupName>group:1</groupName>
  <jobName>job:1</jobName>
  <arg name="leave_days">3</arg>   
 </workflow-timer>
 
 <workflow-timer flowName="wf_series_timer" flowVersion="1" className="cn.com.fcsoft.workflow.timer.DoActionWorkflowJob">
  <cronExpression>0 0/1 * * * ?</cronExpression>   
  <userId>USR_0000001</userId>
  <dsnName></dsnName>
  <triggerName>trigger:2</triggerName>
  <groupName>group:2</groupName>
  <jobName>job:2</jobName>
  <arg name="leave_days">3</arg>   
 </workflow-timer> 

  一个<workflow-timer>节点为一个定时器的定义。
  属性 className 中设置的类为定时器启动后,按时间点执行的代码
  cn.com.fcsoft.workflow.timer.StartWorkflowJob   是定时启动指定流程实例的处理代码。
 
  <cronExpression>0 0 1 * * ?</cronExpression>  <!--表示每天晚上1点执行一次-->
  这个节点定义是轮询的时间间隔,节点值的设置,从左到右的意义如下:
 字段名    允许的值      允许的特殊字符
  秒     0-59  ,       - * /
  分     0-59  ,       - * /
  小时   0-23  ,       - * /
  日     1-31  ,       - * ? / L W C
  月     1-12 or JAN-DEC  , - * /
  周几   1-7 or SUN-SAT  , - * ? / L C #
 年 (可选字段)  empty  ,  1970-2099  , - * /
 
  一些典型的 cronExpression表达式的含义如下:
 "0 0 12 * * ?"  每天中午十二点触发
 "0 15 10 ? * *"  每天早上10:15触发
 "0 15 10 * * ?"  每天早上10:15触发
 "0 15 10 * * ? *"  每天早上10:15触发
 "0 15 10 * * ? 2005"  2005年的每天早上10:15触发
 "0 * 14 * * ?"  每天从下午2点开始到2点59分每分钟一次触发
 "0 0/5 14 * * ?"  每天从下午2点开始到2:55分结束每5分钟一次触发
 "0 0/5 14,18 * * ?"  每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发
 "0 0-5 14 * * ?"  每天14:00至14:05每分钟一次触发
 "0 10,44 14 ? 3 WED"  三月的每周三的14:10和14:44触发
 "0 15 10 ? * MON-FRI"  每个周一、周二、周三、周四、周五的10:15触发
 "0 15 10 15 * ?"  每月15号的10:15触发
 "0 15 10 L * ?"  每月的最后一天的10:15触发
 "0 15 10 ? * 6L"  每月最后一个周五的10:15触发
 "0 15 10 ? * 6L"  每月最后一个周五的10:15触发
 "0 15 10 ? * 6L 2002-2005"  2002年至2005年的每月最后一个周五的10:15触发
 "0 15 10 ? * 6#3"  每月的第三个周五的10:15触发
 
 
 
  <userId>USR_0000001</userId> 为启动流程的用户userid,如果这个用户没有权限则流程实例不能启动。
 
  <dsnName></dsnName> 为初始化流程需要访问的数据库连接的连接名
  节点是fcconfig.xml中定义的数据库连接信息的dsn名称。即<ds name="daqin" dbType="sqlserver" ..... 节点中 name属性后面设置的名称。如果此节点值为空或没有设置此节点,则用fcconfig.xml中的第一个ds节点中设置的数据库连接信息。
 
 
   <triggerName>trigger:1</triggerName>
  <groupName>group:1</groupName>
  <jobName>job:1</jobName>
  这几个节点为定时器中的triggerName,groupName,jobName等。通常是每个每个定时器中的名称不一样。用于标识定时器启动后,需要执行的job。
  
  <arg name="leave_days">3</arg> 这种<arg name="xxxx">这种节点为传递业务数据的节点,有几个需要传递到流程中的业务数据,就设置几个<arg 的节点。在流程初始化的时候,会将这种节点的数据加载到流程的上下文中。
  
  
  
 2、流程的节点中挂接的定时器
 这种类型的定时器,是利用流程节点的前置函数挂接 "计划执行触发器的定时器类" 来启动的。
 当流程实例流转到这个节点时,执行前置函数,启动定时器。按设置的时间轮询,执行这个前置函数中定义的触发器。触发器类为定时执行的业务处理。
 当流程实例离开这个节点时,后置函数中,挂接"取消执行触发器的定时器", 关闭这个定时器。
 
 一个典型的应用,前置函数中的设置如下:
      <pre-functions>
        <function type="class">
          <arg name="local">true</arg>
          <arg name="groupName">test</arg>
          <arg name="triggerName">testTrigger</arg>
          <arg name="triggerId">10</arg>                   ------对应触发器的id号
          <arg name="class.chn">计划执行触发器的定时器类</arg>
          <arg name="passWord">test</arg>
          <arg name="schedulerStart">true</arg>
          <arg name="cronExpression">0,5,10,15 * * * * ?</arg>
          <arg name="class.name">cn.com.fcsoft.workflow.util.ScheduleJob</arg>
          <arg name="jobName">testJob</arg>
        </function>
      </pre-functions>
     
      <post-functions>
        <function type="class">
          <arg name="class.name">cn.com.fcsoft.workflow.util.UnscheduleJob</arg>
          <arg name="groupName">test</arg>                  <!--需要和前置函数中的groupName一样-->
          <arg name="triggerName">testTrigger</arg>         <!--关闭的定时器的triggerName,需要和前置函数中triggerName一样-->
          <arg name="class.chn">取消执行触发器的定时器</arg>
        </function>
      </post-functions>
  
  在eworkflow工作流软件中触发器类也是前置函数类,实现了FunctionProvider接口,能获得流程上下文中的信息。在触发器类中,做实际的业务处理。
  
  
 3、定制实现的定时器处理


 这种类型的定时器处理,是按应用系统的业务需要,定制实现。
 既不是在服务器启动的时候,启动定时器,也不是在流程的流转当中启动定时器。而是在应用系统的界面中,增加启动定时器,和关闭定时器的功能。
 
 例如 一个流程实例启动了,在显示运行轨迹的界面上,增加启动定时器的功能,定时执行此流程实例的动作,达到自动执行此流程的效果,当流程实例运行结束后,就关闭此定时器,避免资源的浪费。也可以由操作员点击关闭此定时器,达到灵活的控制。

原文地址:https://www.cnblogs.com/webreport/p/1987220.html