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