码迷,mamicode.com
首页 > 其他好文 > 详细

SharePoint Workflow架构(二)Workflow 事件处理(Event Processing)

时间:2015-01-09 14:23:29      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:sharepoint workflow   event processing   

[译者按]Andy Li这篇文章,是我看过的最好的,最透彻的关于SharePoint Workflow架构的文章。通过阅读他的文章,我才清楚的了解了SharePoint Workflow的运作机制,并且在遇到问题的时候,知道如何下手查找问题。因此翻译过来,希望对Workflow的开发人员有帮助。


这篇博客是由Andy Li贡献的,他是SharePoint开发人员支持组的处理疑难问题的工程师。原文地址这个关于Workflow的系列,是他贡献给社区的,帮助大家更好的理解Workflow运行时的内部机制,以及如何和SharePoint交互。

这篇文章由SPFarmer翻译。


前三篇地址:

宿主服务(HostService): SPWinOeHostService

SharePoint 和Workflow Runtime的结合

Workflow 事件处理管道(Event Processing Pipeline)


High Level Event Processing

大多数workflow都是事件驱动型的workflow。当workflow到达特定的需要从外部输入的Activitiesworkflow runtime就会调用SharePoint持久化服务,把workflow实例的数据保存到内容数据库里。下面的数据流图表简要的描述了SharePoint workflow是如何响应外部的event的。

技术分享

1. Eventreceiver 响应用户操作

就像我们之前说的, 有几种 workflow event receivers 可以响应用户操作SPWinOEItemEventReceiver  响应 task list item 事件, 比如 ItemUpdated andItemDeleted这些事件包含如下信息:

- 和这个事件关联的task 或者 list item.

- 有改动的Task或者List itemBeforeProperties AfterProperties.

- 事件类型, 可以是 ItemAdded, ItemUpdatedItemDeleted orSharePoint event receiver处理的任何类型的事件.

Event receiver 发送事件数据给SPWorkflowManager.

2. En-queuing event

SPWorkflowManager会尝试运送事件给对应的workflow 实例(每一个task 都有一个“WorkflowInstanceID”属性, 这也是SharePoint 如何知道应该把事件发送给哪个workflow实例).

SPWorkflowManager在把事件传递之前,以WorkItem的形式,把事件加到内容数据库的队列里(ScheduleWorkItem).  这个是因为,实际上,事件传递过程可能是长,并且可能失败。因此加到队列里,很简单是为了能够容错。如果传递这个事件出错,我们可以重新获取这个事件,然后重新尝试传递。 我们会介绍如何通过读取数据库来查找workflow事件传递失败的原因。

3. Delivering event

SPWorkflowManager通过把事件发送给SharePoint workflow runtime (SPWinOeHostService)来继续传输事件。宿主服务负责加载workflow实例到runtime里,并且提交事件到workflow实例里。这个时候,就会调用OnTaskChanged activityMethodInvoked 方法。

4. Dequeuing event

如果workflow 实例成功的处理了事件,我们会在ScheduleWorkItems表里面删除这个事件,并把这个事件管道标记成结束。

Event Pipeline

为了更好的了解这些组件是如何在一起工作的,让我们看一下SharePoint处理task相关的activity的典型的情景。这个过程过程始于 workflow 运行CreateTask activity.  结束于workflow 完成CompleteTask activity.

技术分享

1. CreateTask activity继承了CallExternalMethodActivity.  这个 activityworkflow instance SharePoint开始数据交换会话的地方。  TaskId 也是在这个时候初始化的。

2. Workflowruntime 调用SPWinOeTaskService.CreateTask来创建一个真正的task item.  记住SPListeitem只是在内存里面被创建了,并且没有被提交到数据库里。真正的提交是在workflow持久化之前,由WorkBatch service实现的。

3. Workflow的下一个activity  OnTaskChanged activity  Workflow runtime 会调用 Subscription Service, 它会在我们刚才创建的task上,建立一个用来处理ItemUpdated时间的event receiver

4. Workflowruntime会创建一个event sink来响应OnTaskChanged 事件。

5. 现在workflow实例没有其他事情要做了,因为他在等待用户提交task。持久化服务会调用,保存workflow实例到内容数据库。记住,内存里的SPListitem也是在这个时候被提交。

6. 用户通过Task表单提交对task的修改。Task表单实际上一个apsx页面,通过调用Object Module来更新task item.  Task表单调用的是SPWorkflowTask.AlterTask() API 来提交对task的修改。这个会触发以前注册上来的event receiverItemUpdated事件。

NOTE: 你可能会初一到,每一个workflow task都有一个特别的field“WorkflowVersion”.  这个列的值,被SPWorkflowTask.AlterTask()设置成一个大一1的值(表示这个tasklock) ,这个表示这个task上面有一个更新,并且需要相应的workflow实例来做一些action。这个同时也意味着,在被workflow实例处理之前,这个task被保持在lock状态。

问题:如果我多次调用了AlterTask() API,我收到了一个“taskloack”的异常,为什么呢?

答案: AlterTask API 内部调用了SPListItem.Update(). 如果他检测到这个task属于一个正在运行的workflow instance, 它会把“WorkflowVersion” 列的值设置成一个大于1的值。现在如果你尝试再次调用SPListItem.Update() , 他会检测 “WorkflowVersion”这个列,如果他的值大于1, 我们停止更新,并且抛出这个异常。通过这种方式,我们在workflow处理完OnTaskChange事件之前,阻止对于item的任何修改。 只有在OnTaskChanged activity workflow实例处理完之后, “WorkflowVersion” 会被设置成1,表示这个task被解锁(unlock)了。

7. 现在我们继续。Event receiver 会响应SPListItem.Update()并且通过调用SPWorkflowManager.RunWorkflow尝试把事件传输给workflow runtime

8.SPWorkflowManager 生成一个 WorkItem 并且把它放到数据库里(enqueuing, ScheduledWorkItems ).  WorkItem记录的是,在workflow实例处理之前的,处于pending状态的taskItemUpdate事件。我们保存这个事件在内容数据库里是为了容错处理。如果因为任何原因,这个事件没有传递成功,workflowtimer job可以从数据库里找到这个WorkItem,并且继续处理他。

9.SPWorkflowManager 继续传输这个事件到SharePoint workflow runtime(SPWinOeHostService).  SPWinOeHostService 检查这个事件,并且从这个事件获取两个数据: WorkflowInstanceID TaskID.  It 加载workflow实例到 workflow runtime. 并且提交OnTaskChanged 事件到 workflow 实例,你的OnTaskChanged.OnInvoked() 里面的自定义代码在这个时期被调用。

问题:TaskId存储在哪里?

答案:每一个workflow task都有一个列叫做“GUID”, 这个就是 TaskID.

10. workflowruntime 执行完 OnTaskChanged activity之后, 他把 WorkItem 从数据库里面删掉。Task “WorkflowVersion” 列会被设置成 “1” (unlocked) 然后 event receiver is deleted from the tasklist.

关于Workflow Timer Jobs

我们曾经说过,当SPWorkflowManager 尝试去传送事件到宿主服务(SPWinOEHostService), 他需要检查几个条件。 其中的一个条件是确认workflow 没有锁住并且没有在其他地方运行。一个SharePoint场环境,可以有多个前端服务器(web frontend servers)workflow runtime可以寄宿在其中的任何一个server。我们需要确保workflow instance在任何时间内,只被其中的一个workflow runtime 处理。SharePoint的机制是在数据库里设置一个flag,来标识锁定状态。SPWorkflowManager可以简单的查出workflow 是否被锁定。如果这个workflow被锁定了, SPWorkflowManager 会把 WorkItem 放到数据库的队列里,timer job 会异步处理这个事件。

Workflow timerjob 负责处理队列里的WorkItems.  这种情况下timer service就是 workflow runtime的宿主。这里有3个和workflow 相关的timer job ,它们处理不同的作业。下面的表格列出了它们的主要的功能:

Job

Description

SPWorkflowFailOverJobDefinition

一个workflow可能因为多种原因失败。如果他在中途失败,他会被锁定并且不能够重新启动。Fail-over timer job 的作用是解锁这些workflow,使它们能继续运行。

SPWorkflowJobDefinition

处理ScheduleWorkItem 队列里的WorkItems.  w3wp.exe 总是尝试在第一时间传输事件到workflow。但是如果workflow被别的进程锁住了,它会把事件放到数据库队列里。默认情况下,这个 timer job 会处理这些事件。

SPWorkflowAutoCleanJobDefinition

清楚数据库里的旧的workflow instances。默认情况下,这个job会清楚60天之前完成的workflows。你可以通过修改SPWorkflowAssociation.AutoCleanupDays属性来设置默认值 

每五分钟,SPWorkflowJobDefinition被唤醒并且在数据库里查找 WorkItems 。数据库里的WorkItem记录包含了所有pending状态的工作。比如workflow instance ID, task item ID, event type等等。对于每一个WorkItems, timer job通过WorkItem记录重新组装 SPWorkflowEvents对象。他调用SPWorkflowManager.RunWorkflow() 并且把事件传递给Workflow实例。


未完待续。

SharePoint Workflow架构(二)Workflow 事件处理(Event Processing)

标签:sharepoint workflow   event processing   

原文地址:http://blog.csdn.net/spfarm/article/details/42553325

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!