当前位置:文档之家› activiti源码分析

activiti源码分析

activiti源码分析
activiti源码分析

ExecutionEntity内部含有parent,是一个执行树或执行路径,应该是一个流程实例的执行过程,一个实例对应一个ExecutionEntity,通过getActivity得到的是当前正在执行的activity.

Activiti之流程部署:

流程文件部署主要涉及到3个表,分别是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。主要完成“部署包”-->“流程定义文件”-->“所有包内文件”的解析部署关系

流程定义的部署需要完成如下操作:

●初始化到数据库,完成三张表的插入,一个部署包里可以有N个流程定义,所以

PROCDEF表内对应N条数据,BYTEARRAY表内对应N+条记录,每个xml文件一条记录,图片也会另外存放一条记录。DEPLOYMENT内会存放一条记录

●解析后的流程定义存入DeploymentCache

流程部署的序列图:

repositoryService DeploymentBuilder commandExecutor DeploymentManager DbSqlSession ResourceManager DeploymentCache createDeployment

execute(new DeployCmd(deploymentBuilder))

insertDeployment(DeploymentEntity)

insert(DeploymentEntity)

流程部署已后,启动流程时,会调用StartProcessInstanceCmd,来启动流程。StartProcessInstanceCmd在查找ProcessDefinitionEntity时,会从deploymentCache 中查找,当cache中不存在时,会执行deploymentCache.deploy()

Activiti之Query查询:

缓存查询:

Activiti 之manager:

创建流程实例:

创建流程实例:runtimeService.startProcessInstanceByKey("financialReport") 执行步骤:

1.0 首先根据” financialReport”在数据库中查找流程定义

2.0 查找到流程定义后,再从processDefinitionCache 中获取已经缓存的、部署完成的(xml

文件被解析的)流程定义,如果processDefinitionCache 中不存在,那么执行流程的解析过程

query

+++++++

升续 ()降续 ()list ()

listPage ()

Operation_5 ()singleResult ()count ()

userQuery

+++++

userId ()

userFirstName ()userEmail ()

memberOfGroup ()orderByUserId ()...

: userQuery : userQuery : userQuery : userQuery : userQuery

Command

+execute (CommandContext context): T

AbstractQuery

++++++

升序 ()降序 ()list ()

listPage ()count ()

sigleResult ()

UserQueryImpl

TaskQuery

TaskQueryImpl

session ++flush ()close ()...

AbstractManager

++++

insert (PersistentObject record)delete (PersistentObject record)getDbSqlSession ()getManager ()

TaskManager

++deleteTask ()findTask (): TaskEntity

ExecutionManager

+

++++

deleteProcessInstances ()findProcessInstance ()findExecutions ()

findChildExecutions ()findSubProcessInstance ()...

: ProcessInstance : ExecutionEntity : ExecutionEntity : ExecutionEntity

3.0创建流程实例

代码执行过程:

1.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationProcessStart

2.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationProcessStartInitial 3.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute

4.ProcessInstance[805] executes Activity(theStart):

org.activiti.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior 5.Leaving activity 'theStart'

流程启动:

流程启动执行:ExecutionEntity.performOperation(AtomicOperation.PROCESS_START) ,接着执行:execution.performOperation(PROCESS_START_INITIAL);

接着执行:execution.performOperation(ACTIVITY_EXECUTE);其内部执行逻辑为:ActivityBehavior activityBehavior = activity.getActivityBehavior();

activityBehavior.execute(execution);

activityBehavior有很多的实现类,比如:当流程启动时,启动节点的activityBehavior实际上是NoneStartEventActivityBehavior的实例。给每个节点装配ActivityBehavior应该是在流程解析时完成的,一个类型的节点装配特定类型的Behavior,固定写死的。

Activiti之数据操作

Insert、update、delete三种操作,先更新cache,在一个cmd中,把所有需要insert的数据放入一个map,执行完cmd后,统一进行insert、update、delete操作

每个Service的“命令执行者”都是由

“LogInterceptor-->CommandContextInterceptor-->CommandExecutorImpl”组成的执行链状结构。日志—>执行前后操作(比如:transaction的开启及commit) 执行命令

Activiti之任务分配

任务分配时,根据流程定义,首先根据人工活动定义的Assignee,直接进行分配,如果Assignee有值,此时该任务处于已认领状态。然后继续执行任务的候选人分配,候选人分两种:候选组表达式及候选人表达式,解析表达式,进行公共任务分配。任务应该没有状态,标记是已经被认领时,是根据该任务的属性:task.getAssignee()是否有值进行判断

Activiti之任务认领

1.0没有找到判断是否有权限进行认领操作

2.0 如果该任务属性:task.getAssignee()有值,说明已经被认领,如果和当前认领人不同,抛出异常,is already claimed by someone else

执行认领操作,数据库操作步骤(分别对应三张表):

1.update HistoricActivityInstanceEntity

2.update HistoricTaskInstanceEntity

3.update TaskEntity

Activiti之任务完成

在创建一个新人工任务时,在数据表IdentityLinkEntity中删除当前已完成的这条数据,当流程实例结束时,删除execution表中的当前流程数据。

完成一个人工任务时,完成的数据库表操作:

1.insert HistoricActivityInstanceEntity

2.insert TaskEntity

3.insert HistoricTaskInstanceEntity

4.insert IdentityLinkEntity

5.update ExecutionEntity

6.update HistoricActivityInstanceEntity

7.update HistoricTaskInstanceEntity

8.delete IdentityLinkEntity

9.delete TaskEntity

完成任务时,走的过程:

1.Leaving activity 'writeReportTask'

[org.activiti.engine.impl.bpmn.behavior.BpmnActivityBehavior]

2.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyLis tenerEnd

3.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyLis tenerEnd@1c09624

4.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroySc ope

5.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyLis tenerTake

6.ProcessInstance[605] takes transition

(writeReportTask)--flow2-->(verifyReportTask)

[org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyLi stenerTake]

7.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionCreateSco pe

8.AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyLis tenerStart 9. AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyLis tenerStart 10. AtomicOperation:

org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute@1478a2d on https://www.doczj.com/doc/cc2620825.html,mandContext 11. ProcessInstance[605] executes Activity(verifyReportTask):

https://www.doczj.com/doc/cc2620825.html,erTaskActivityBehavior

Activiti 其它

Activiti 之executionEntity:

PvmExecution +++++

signal ()

getActivity ()hasVariable ()setVariable ()getVariable ()...

PvmProcessInstance

+++++

start ()

findExecution ()

findActiveActivityIds ()isEnded ()

deleteCascade ()...InterpretableExecution

ActivityExecution

++++++++

getActivity ()take (PvmTransition 入参)createExecution ()createSubProcessInstance ()getParent ()end ()

executeActivity ()takeAll ()...

: PvmActivity : ActivityExecution : ActivityExecution DelegateExecution

++++

getProcessBusinessKey ()getId ()

getProcessInstanceId ()getEventName ()...

VariableScope ++++

getVariables ()setVariable ()hasVariables ()removeVariable ()...

ExecutionListenerExecution

+++getEventName ()

getEventSource ()getDeleteReason ()...

: PvmProcessElement VariableScopeImpl

ExecutionEntity

Execution

+++getId ()isEnded ()

getProcessInstanceId ()...

ProcessInstance

++getProcessDefinitionId ()getBusinessKey ()...

ExecutionImpl

Activiti 之定义模型:

Activiti 之优缺点:

1.0 一直没能理解它的executionEntity 的模型,它提供了三个接口:pvmexecution 、execution 、

activityExecution ,是它的名字起的不好还是有其它的思想?

2.0 当流程结束时,删除对应的记录,这种操作很巧妙的支持了集群环境

3.0 见识了把一个流程从开始到结束的抽象:分解成各种cmd 和AtomicOperation

4.0 通过一个执行链完成transaction 的编程式事物控制

5.0 不支持组织机构的扩展,与业务系统进行集成时,要写很多的event 来完成任务分配

6.0 可以记录冗余业务数据来组合查询任务

7.0 把已完成的流程做数据清理并备份

最后:文档比较粗糙,希望感兴趣的朋友多多交流以:whdwsl@https://www.doczj.com/doc/cc2620825.html,

RuntimeService

++++++++

startProcessInstance ()deleteProcessInstance ()getActiveActivity ()signal ()

getVariables ()setVariable ()

createExecutionQuery ()createProcessInstanceQuery (): ProcessInstance : ExecutionQuery

: ProcessInstanceQuery

ServiceImpl

-executor : CommandExecutor ++getCommandExecutor ()setCommandExecutor ()

RuntimeServiceImpl

ProcessDefinition +++getId ()

getDeploymentId ()getVersion ()...

ProcessDefinitionEntity

+createProcessInstance (String businessKey)...

: ExecutionEntity ProcessDefinitionImpl

++createProcessInstance ()getInitial (): PvmProcessInstance : ActivityImpl

ScopeImpl

--activities namedActivities : ActivityImpl

: Map+createActivity ()...

: ActivityImpl ProcessElementImpl PvmProcessElement

+++getId ()

getProcessDefinition ()getProperty ()...

: PvmProcessDefinition PvmScope

++getActivities ()findActivity ()...

: PvmActivity : PvmActivity ActivityImpl

----parent

outgoingTransitions incomingTransitions activityBehavior

: int : int : int : int

++++

createOutgoingTransition ()findOutgoingTransition ()setIncomingTransitions ()位置相关方法 ()

PvmActivity

++++++

isAsync ()isExclusive ()getParent ()

getIncomingTransitions ()getOutgoingTransitions ()findOutgoingTransition ()...

ReadOnlyProcessDefinition

++++

getName ()

getDescription ()getInitial ()getDiagramResourceName ()...

: PvmActivity PvmProcessDefinition

++getDeploymentId ()

createProcessInstance ()...

: PvmProcessInstance PvmTransition

+++getProcessDefinition ()getId ()

getProperty ()...

TransitionImpl

---source destination executionListeners : ActivityImpl : ActivityImpl : int ++get 属性 ()set 属性 ()...

memcacheQ 配置

memcacheQ 配置 什么是memcacheQ ? memcacheQ是一个基于memcache协议、BDB持久数据存储、高性能轻量级队列服务程序。 特点是: 1.简单高效,基于memcache协议,这意味着只要客户端支持memcache协议即可使用。 2.队列数据存储于BDB,持久保存。 3.并发性能好。 4.支持多条队列。 并发量较的web环境,特别是数据库写入操作过多的情景,使用队列可大大缓解因并发问题造成的数据库锁死问题。生产环境中使用效果非常好。 先决条件: memcacheQ依赖于libevent,libevent-devel和BDB (BerkleyDB) 1.先检查libevent, libevent-devel是否已经安装: rpm -qa|grep libevent 输出中必须包含libevent, libevent-deve, 如果缺失,使用以下命令安装: yum install libevent yum install libevent-devel 安装完毕再复查之:rpm -qa|grep libevent, 确保安装正确。 注意事项:libevent, libevent-devel优先使用yum安装源,光盘镜像中的rpm包安装,这样稳定性和兼容性可得到保证,网上流传的使用源码安装libevent的方法会有问题,因为很可能系统已经安装libevent, 再使用源码安装,必然导致冲突,造成意外问题,所以一定要使用上述命令检查系统是否已经安装相应的库。 2.安装BerkleyDB cd /usr/local/src wget http://219.239.89.57/deploy/db-5.2.28.tar.gz tar zxvf db-5.2.28.tar.gz cd db-5.2.28 cd build_unix ../dist/configure make make install 3.准备安装memcacheQ cd /usr/local/src wget http://219.239.89.57/deploy/memcacheq-0.2.0.tar.gz tar zxvf memcacheq-0.2.0.tar.gz cd memcacheq-0.2.0 修改configure文件,找到bdbdir="/usr/local/BerkeleyDB.4.7",修改为 bdbdir="/usr/local/BerkeleyDB.5.2", 否则执行configure时会产生找不到BDB的错误。

libevent

libevent源码深度剖析 张亮 Email: sparling.liang@https://www.doczj.com/doc/cc2620825.html,

回想刚开始写时,就冠以“深度剖析”的名称,也是为了给自己一些压力,以期能写好这一系列文章,对libevent源代码的各方面作详细的分析;现在看来也算是达到了最初的目的。希望能给学习和使用libevent的朋友们有所帮助。 Email:sparkling.liang@https://www.doczj.com/doc/cc2620825.html, 张亮

目录 libevent源码深度剖析 (1) 目录 (3) 一序幕 (5) 1 前言 (5) 2 Libevent简介 (5) 3 学习的好处 (5) 二Reactor模式 (6) 1 Reactor的事件处理机制 (6) 2 Reactor模式的优点 (6) 3 Reactor模式框架 (6) 4 Reactor事件处理流程 (8) 5 小结 (9) 三基本使用场景和事件流程 (10) 1 前言 (10) 2 基本应用场景 (10) 3 实例代码 (11) 4 事件处理流程 (11) 5 小结 (12) 四 libevent源代码文件组织 (13) 1 前言 (13) 2 源代码组织结构 (13) 3 小结 (14) 五 libevent的核心:事件event (15) 1 libevent的核心-event (15) 2 libevent对event的管理 (16) 3 事件设置的接口函数 (17) 4 小结 (18) 六初见事件处理框架 (19) 1 事件处理框架-event_base (19) 2 创建和初始化event_base (20) 3 接口函数 (20) 4 小节 (23) 七事件主循环 (24) 1 阶段性的胜利 (24) 2 事件处理主循环 (24) 3 I/O和Timer事件的统一 (27) 4 I/O和Signal事件的统一 (27) 5 小节 (27) 八集成信号处理 (28) 1 集成策略——使用socket pair (28)

Memcached源码剖析笔记

Memcached 源码剖析笔记 Xguru Memcached是一个自由、源码开放、高性能、分布式 内存对象缓存系统,目的在于通过减轻数据库负载来使 动态Web应用程序提速。

目录 1.背景 (3) 2.memcached的安装 (4) 3.memcached的配置 (5) 4.memcached的使用 (6) 4.1.存储命令 (7) 4.2.读取命令 (8) 4.3.删除命令 (8) 4.4.高级命令 (9) 4.5.其他命令 (10) 5.Memcached内部工作机制 (11) 5.1.Memcached基本的数据结构 (11) 5.2.基本设计概念和处理流程 (12) 5.3.内部Hash机制 (15) 5.3.1.Hash函数及冲突解决 (15) 5.3.2.HashTable主要函数 (15) 5.4.slab内存处理机制 (17) 5.4.1.slab主要函数 (17) 5.4.2.slab机制中所采用的LRU算法 (19) 5.5.控制item各种函数 (20) 5.6.守护进程机制 (22) 5.7.Socket处理机制 (23) 1

5.7.1.Unix域协议 (23) 5.7.2.TCP/UDP协议 (24) 5.8.多线程处理机制 (25) 5.9.事件处理机制 (25) 6.未完善之处 (27) 7.参考文献 (28) 2

1.背景 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。 Memcached是一个自由、源码开放、高性能、分布式内存对象缓存系统,目的在于通过减轻数据库负载来使动态Web应用程序提速。 Memcached是一个在内存中对任意的数据(比如字符串,对象等)所使用的key-value 存储。数据可以来自数据库调用,API调用,或者页面渲染的结果。 Memcached设计理念就是小而强大,它简单的设计促进了快速部署、易于开发,并解决面对大规模的数据缓存的许多难题。所开放的API能用于大部分流行的程序语言 3

基于Libevent的HTTP Server

基于Libevent的HTTP Server 简单的Http Server 使用Libevent内置的http相关接口,可以很容易的构建一个Http Server,一个简单的Http Server如下: #include #include #include #include #include #include int init_win_socket() { WSADATA wsaData; if(WSAStartup(MAKEWORD(2,2) , &wsaData) != 0) { return -1; } return0; } void generic_handler(struct evhttp_request *req, void *arg) { struct evbuffer *buf = evbuffer_new(); if(!buf) { puts("failed to create response buffer \n"); return; } evbuffer_add_printf(buf, "Server Responsed. Requested: %s\n", evhttp_request_get_uri(req)); evhttp_send_reply(req, HTTP_OK, "OK", buf); evbuffer_free(buf); } int main(int argc, char* argv[]) { #ifdef WIN32 init_win_socket();

深度剖析KMP

深度剖析KMP,让你认识真正的Next KMP算法,想必大家都不陌生,它是求串匹配问题的一个经典算法(当然如果你要理解成放电影的KMP,请退出本页面直接登录各大电影网站,谢谢),我想很多人对它的理解仅限于此,知道KMP能经过预处理然后实现O(N*M)的效率,比brute force(暴力算法)更优秀等等,其实KMP算法中的Next函数,功能十分强大,其能力绝对不仅仅限于模式串匹配,它并不是KMP的附属品,其实它还有更多不为人知的神秘功能^_^ 先来看一个Next函数的典型应用,也就是模式串匹配,这个相信大家都很熟悉了: POJ 3461 Oulipo——很典型的模式串匹配问题,求模式串在目标串中出现的次数。 #include #include #include #include #include using namespace std; #define MAX 1000001 char t[MAX]; char s[MAX]; int next[MAX]; inline void calnext(char s[],int next[]) { int i; int j; int len=strlen(s); next[0]=-1; j=-1; for(i=1;i=0&&s[i]!=s[j+1]) j=next[j]; if(s[j+1]==s[i])//上一个循环可能因为j=-1而不做,此时不能知道s[i]与s[j+1]的关系。故此需要此条件。 j++; next[i]=j; } } int KMP(char t[],char s[]) { int ans=0; int lent=strlen(t); int lens=strlen(s); if(lent

libevent

libevent源码深度剖析一 ——序幕 张亮 1 前言 Libevent是一个轻量级的开源高性能网络库,使用者众多,研究者更甚,相关文章也不少。写这一系列文章的用意在于,一则分享心得;二则对libevent代码和设计思想做系统的、更深层次的分析,写出来,也可供后来者参考。 附带一句:Libevent是用c语言编写的(MS大牛们都偏爱c语言哪),而且几乎是无处不函数指针,学习其源代码也需要相当的c语言基础。 2 Libevent简介 上来当然要先夸奖啦,Libevent 有几个显著的亮点: 事件驱动(event-driven),高性能; 轻量级,专注于网络,不如ACE那么臃肿庞大; 源代码相当精炼、易读; 跨平台,支持Windows、Linux、*BSD和Mac Os; 支持多种I/O多路复用技术,epoll、poll、dev/poll、select和kqueue等; 支持I/O,定时器和信号等事件; 注册事件优先级; Libevent已经被广泛的应用,作为底层的网络库;比如memcached、Vomit、Ny lon、Netchat等等。 Libevent当前的最新稳定版是1.4.13;这也是本文参照的版本。 3 学习的好处 学习libevent有助于提升程序设计功力,除了网络程序设计方面外,Libevent的代码里有很多有用的设计技巧和基础数据结构,比如信息隐藏、函数指针、c语言的多态支持、链表和堆等等,都有助于提升自身的程序功力。 程序设计不止要了解框架,很多细节之处恰恰也是事关整个系统成败的关键。只对libevent 本身的框架大概了解,那或许仅仅是一知半解,不深入代码分析,就难以了解其设计的精巧之处,也就难以为自己所用。 事实上Libevent本身就是一个典型的Reactor模型,理解Reactor模式是理解libevent 的基石;因此下一节将介绍典型的事件驱动设计模式——Reactor模式。 libevent源码深度剖析二 ——Reactor模式

httpsqs源码分析

Httpsqs是一个消息队列服务器,他调用的接口是tokyocabinet,tokyocabinet是一个数据库的持久化库,保存。 Httpsqs1.6 设计到的第3方库: Libevent: 这个不用介绍了 Tokyocabinet:数据库的持久化库 Httpsqs1.6 采用的是单线程通信,通信的采用的是libevent,因为Tokyocabinet的处理速度很快,在业务处理方面不存在阻塞的问题,所以采用单线程。 整体流程: httpsqs_handler 图1 整体流程

httpsqs_handler的处理流程 图 2 上面的处理流程只列出了put,get 2种命令,其实还有其他的命令,处理很put,get差不多 上面2个图,就是httpsqs的大概的流程。 Tokyocabinet 是一个的持久化数据库,怎么能做成队列呢? 下面以一个队列来举例说明: 假如我们要往LogQueue队列插入数据,LogQueue并不是一个Key值,他的Key值是LogQueue:1,LogQueue:2,LogQueue:3 ………….. LogQueue:10000…….,哪这个1,2,3…………….10000是怎么控制的呢,这又设计到另为2个Key值,LogQueue:get, LogQueue:put。具体操作见源码。 上面是httpsqs1.6的大概分析。 目前在项目中遇到的问题: 1往一个队列中插入数据时,插入数据OK,但取数据的时候,数据为空原因:初步认为是调用tcbdbput2失败了,httpsqs1.6在调用这个接口时没有返回 值,httpsqs1.6本身根本就不知道是否保存成功。 根据以上,改了一个httpsqs2.6的版本 1 httpsqs1.6采用的B+树的方式(见Tokyocabinet代码),把httpsqs1.6中所有的tcb

相关主题
文本预览
相关文档 最新文档