工作流持久性和书签作为工作流故障转移
Workflow persistence and bookmarks as a workflow failover
我有一组自定义活动,用于复杂的工作流程。
我想让它们(自定义活动)持久化,而不需要让工作流处于空闲状态。它应该是一种故障转移系统,因此每当在执行工作流期间出现问题时,它可能是:
- 被用户暂停(在任何时间),稍后从暂停的 bookmark/point 恢复(例如,用户注意到外部系统已关闭,他想暂时暂停工作流程)。
- 如果出现未处理的异常,我们可以及时从上次 bookmark/point 重新开始执行
- WorkflowApplication 主机随时可能停止,我们可以及时从上次 bookmark/point 重新开始执行
我已经在工作流持久性方面工作了几天,但我不确定我是否可以用它实现我的目标。为什么?
- 我可以在每个自定义 activity 中使用阻止书签,但阻止工作流并重新启动它只是为了让它持久化看起来不太有希望。
- 我可以使用非阻塞书签,但我无法在数据库中看到它们并从中恢复。
你能给我一些建议吗,工作流书签是这里的出路吗?
我看到了 notblocking bookmarks 的一些亮点,但我无法坚持它们并稍后恢复。你能给我一些提示,告诉我如何为以后的简历保留一个非阻塞书签吗?
编辑:
在 wf3 中有一个属性 PersistOnClose
足以满足我的要求。
在 wf4 中它被替换为 Persist
activity,这也可能有用,但是我不想在我已经很复杂的工作流程中有额外的活动。
理想情况下,能够从 NativeActivityContext
执行 context.RequestPersist(callback)
会很棒,但是此方法是内部方法(并且其中的所有内容在原始程序集之外都不可见。
如果我理解你的问题是正确的,那么你有以下要求。
- 工作流的持久化和恢复。
- 用户可以暂停和继续。
- 如果出现任何异常,工作流将继续并从下一个 activity 继续。
您可以使用以下步骤进行处理。
- 您可以使用 WF + WCF 服务来执行和托管您的工作流。
- 使用像 Sql 服务器这样的数据库添加持久性和跟踪,如果您使用的是 oracle,则可以使用 Devart。
- 将 ControlEnpont 配置为暂停和恢复。
- 明智地使用 try/Catch 和持久性 activity 来处理异常。
如有任何问题和需要定制的问题,请进行相同的讨论。:) 因为我开发的工作流程与您的工作流程类似。
这是我带来的:
- 非阻塞书签不是一个选项。虽然非阻塞书签不会阻止创建 activity 完成,但它也不会导致工作流实例变为空闲 - 这意味着它不会被持久化。一旦 activity(创建它的)完成,非阻塞书签将被丢弃。仅当创建 activity 尚未完成时才能恢复此书签。
- 使用
PersistOnCloseAttribute
不是一个选项,因为我使用的是 WF4 并且此属性仅为 .NET 3.x WF。
- 不能使用阻止书签,因为它们会阻止工作流的执行,这是不希望的。
解决方案是在每个自定义 activity 中使用 Persist
activity(必须扩展可以安排子活动的 NativeActivity
):
//class field
Activity childActivity = new Persist();
为了使其正常工作,必须将其作为 ImplmentationChild 添加到元数据中:
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.AddImplementationChild(this.childActivity);
}
最后一件事是从 Execute 方法调度子 activity(不管在哪里,只有在调用 activity 完成后才会持久化*)。
protected override void Execute(NativeActivityContext context)
{
//...
context.ScheduleActivity((Activity)this.childActivity);
}
为了在未处理异常后保持工作流持续存在,必须将这段代码添加到 WorkflowApplication:
application.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
return UnhandledExceptionAction.Abort;
};
*return 来自 Execute
方法并不一定意味着 activity 是 "completed" - 即 activity 中有阻塞书签(请参阅下面的缺点)。
此解决方案有几个缺点:
- 解决方案只保留工作流的一个状态(最后一个状态)。
- 只有在 activity 完成后才会发生持久化。这意味着 persist/resume 不能从 activity.
的中间完成
- 它不适用于并行 loops/sequences - 来自并行 loop/sequence 的活动在整个并行事情完成后仍然存在。它与常规 loops/sequences.
一起正常工作
- 阻止书签对此解决方案有巨大影响(如果它们是在创建 activity 或其他创建 activity 的子活动中创建的)。它们导致 activity 未完成,即使执行方法 returned。最终 Persist 将执行(在完成 activity 之后或进入空闲状态之前)。
我有一组自定义活动,用于复杂的工作流程。
我想让它们(自定义活动)持久化,而不需要让工作流处于空闲状态。它应该是一种故障转移系统,因此每当在执行工作流期间出现问题时,它可能是:
- 被用户暂停(在任何时间),稍后从暂停的 bookmark/point 恢复(例如,用户注意到外部系统已关闭,他想暂时暂停工作流程)。
- 如果出现未处理的异常,我们可以及时从上次 bookmark/point 重新开始执行
- WorkflowApplication 主机随时可能停止,我们可以及时从上次 bookmark/point 重新开始执行
我已经在工作流持久性方面工作了几天,但我不确定我是否可以用它实现我的目标。为什么?
- 我可以在每个自定义 activity 中使用阻止书签,但阻止工作流并重新启动它只是为了让它持久化看起来不太有希望。
- 我可以使用非阻塞书签,但我无法在数据库中看到它们并从中恢复。
你能给我一些建议吗,工作流书签是这里的出路吗?
我看到了 notblocking bookmarks 的一些亮点,但我无法坚持它们并稍后恢复。你能给我一些提示,告诉我如何为以后的简历保留一个非阻塞书签吗?
编辑:
在 wf3 中有一个属性 PersistOnClose
足以满足我的要求。
在 wf4 中它被替换为 Persist
activity,这也可能有用,但是我不想在我已经很复杂的工作流程中有额外的活动。
理想情况下,能够从 NativeActivityContext
执行 context.RequestPersist(callback)
会很棒,但是此方法是内部方法(并且其中的所有内容在原始程序集之外都不可见。
如果我理解你的问题是正确的,那么你有以下要求。
- 工作流的持久化和恢复。
- 用户可以暂停和继续。
- 如果出现任何异常,工作流将继续并从下一个 activity 继续。
您可以使用以下步骤进行处理。
- 您可以使用 WF + WCF 服务来执行和托管您的工作流。
- 使用像 Sql 服务器这样的数据库添加持久性和跟踪,如果您使用的是 oracle,则可以使用 Devart。
- 将 ControlEnpont 配置为暂停和恢复。
- 明智地使用 try/Catch 和持久性 activity 来处理异常。
如有任何问题和需要定制的问题,请进行相同的讨论。:) 因为我开发的工作流程与您的工作流程类似。
这是我带来的:
- 非阻塞书签不是一个选项。虽然非阻塞书签不会阻止创建 activity 完成,但它也不会导致工作流实例变为空闲 - 这意味着它不会被持久化。一旦 activity(创建它的)完成,非阻塞书签将被丢弃。仅当创建 activity 尚未完成时才能恢复此书签。
- 使用
PersistOnCloseAttribute
不是一个选项,因为我使用的是 WF4 并且此属性仅为 .NET 3.x WF。 - 不能使用阻止书签,因为它们会阻止工作流的执行,这是不希望的。
解决方案是在每个自定义 activity 中使用 Persist
activity(必须扩展可以安排子活动的 NativeActivity
):
//class field
Activity childActivity = new Persist();
为了使其正常工作,必须将其作为 ImplmentationChild 添加到元数据中:
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.AddImplementationChild(this.childActivity);
}
最后一件事是从 Execute 方法调度子 activity(不管在哪里,只有在调用 activity 完成后才会持久化*)。
protected override void Execute(NativeActivityContext context)
{
//...
context.ScheduleActivity((Activity)this.childActivity);
}
为了在未处理异常后保持工作流持续存在,必须将这段代码添加到 WorkflowApplication:
application.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
return UnhandledExceptionAction.Abort;
};
*return 来自 Execute
方法并不一定意味着 activity 是 "completed" - 即 activity 中有阻塞书签(请参阅下面的缺点)。
此解决方案有几个缺点:
- 解决方案只保留工作流的一个状态(最后一个状态)。
- 只有在 activity 完成后才会发生持久化。这意味着 persist/resume 不能从 activity. 的中间完成
- 它不适用于并行 loops/sequences - 来自并行 loop/sequence 的活动在整个并行事情完成后仍然存在。它与常规 loops/sequences. 一起正常工作
- 阻止书签对此解决方案有巨大影响(如果它们是在创建 activity 或其他创建 activity 的子活动中创建的)。它们导致 activity 未完成,即使执行方法 returned。最终 Persist 将执行(在完成 activity 之后或进入空闲状态之前)。