如何在多个并行CPF流水线执行完成后触发事件?
How to trigger an event after the completion of multiple, parallel CPF pipeline execution?
我有一个客户 ID 列表。对于它们中的每一个,我都需要从外部系统(通过 Web 服务)收集一些信息,然后创建一个报告。创建完所有客户报告后,我想根据所有报告自动生成一个摘要文档。
我的计划是使用 MarkLogic 内容处理框架 (CPF) 来处理每个客户 ID 的 Web 请求和报告生成。但是,我不知道如何在 所有 客户报告管道完成后触发摘要文档的操作。
更新基于 (2019-03-04)
根据我对 Mary 的建议的理解,我应该改为只有一个管道直接处理客户 ID 文档,并创建顺序处理 ID 的操作,然后在终端状态生成摘要生成操作。我对这种设计的唯一担心是错误处理,因为我不能再依赖 CPF 状态来跟踪每个单独的报告。我应该如何设计 states/actions 以有效地处理故障?
这将很难完全正确。您最终会造成瓶颈或差距,这些瓶颈或差距可能会导致某些事情被跳过,或两者兼而有之。总体计划是在 "create report" 之后进行转换,该转换具有检查所有客户 ID 的状态并在它们都在正确位置时启动摘要操作的条件。为了让它有希望成为可靠的,您可能需要创建一个代表批次的单个文档,并让各个客户 ID 的管道更新它(这将确保有一个您可以依靠的闩锁,它的缺点是创建了一个闩锁,它们都会阻塞。)但是,如果可以避免的话,我不建议这样做。
CPF 旨在对一个文档执行一系列步骤。因此,将它操作的文档设为批处理,并将操作设为对批处理起作用的操作。这可能意味着单个步骤 运行 更长(尽管如果您可以控制您的网络服务 API 您也可以使其面向批处理,这可能会有所帮助),但您的吞吐量最终可能会更好。在任何情况下都不要产生或调用 CPF 操作。
错误处理设计肯定会很棘手,并且需要权衡取舍。您可以让批处理中任何成员的所有错误导致整个批处理失败:直接的代码可以做到这一点。或者,如果你想知道批次中的所有失败,但批次仍然失败,你可以收集所有单独的错误并将它们重新传播为单个包装失败,例如在一个动作的标准 try/catch 模式中,类似于:
let $errors :=
for $id in $list-of-ids return
try { let $work := do-stuff() return () } catch ($e) { <error><id>{$id}</id>{$e}</error> }
return
if (empty($errors)) then ( (: OK! :) )
else fn:error((), "MY-BATCHERROR", $errors)
虽然您可以为错误状态添加一个转换来实现这一点,但这确实使得用它们自己的错误标记单个文档变得棘手:查看批处理错误并将其放在每个引用的文档上。
我有一个客户 ID 列表。对于它们中的每一个,我都需要从外部系统(通过 Web 服务)收集一些信息,然后创建一个报告。创建完所有客户报告后,我想根据所有报告自动生成一个摘要文档。
我的计划是使用 MarkLogic 内容处理框架 (CPF) 来处理每个客户 ID 的 Web 请求和报告生成。但是,我不知道如何在 所有 客户报告管道完成后触发摘要文档的操作。
更新基于 (2019-03-04)
根据我对 Mary 的建议的理解,我应该改为只有一个管道直接处理客户 ID 文档,并创建顺序处理 ID 的操作,然后在终端状态生成摘要生成操作。我对这种设计的唯一担心是错误处理,因为我不能再依赖 CPF 状态来跟踪每个单独的报告。我应该如何设计 states/actions 以有效地处理故障?
这将很难完全正确。您最终会造成瓶颈或差距,这些瓶颈或差距可能会导致某些事情被跳过,或两者兼而有之。总体计划是在 "create report" 之后进行转换,该转换具有检查所有客户 ID 的状态并在它们都在正确位置时启动摘要操作的条件。为了让它有希望成为可靠的,您可能需要创建一个代表批次的单个文档,并让各个客户 ID 的管道更新它(这将确保有一个您可以依靠的闩锁,它的缺点是创建了一个闩锁,它们都会阻塞。)但是,如果可以避免的话,我不建议这样做。
CPF 旨在对一个文档执行一系列步骤。因此,将它操作的文档设为批处理,并将操作设为对批处理起作用的操作。这可能意味着单个步骤 运行 更长(尽管如果您可以控制您的网络服务 API 您也可以使其面向批处理,这可能会有所帮助),但您的吞吐量最终可能会更好。在任何情况下都不要产生或调用 CPF 操作。
错误处理设计肯定会很棘手,并且需要权衡取舍。您可以让批处理中任何成员的所有错误导致整个批处理失败:直接的代码可以做到这一点。或者,如果你想知道批次中的所有失败,但批次仍然失败,你可以收集所有单独的错误并将它们重新传播为单个包装失败,例如在一个动作的标准 try/catch 模式中,类似于:
let $errors :=
for $id in $list-of-ids return
try { let $work := do-stuff() return () } catch ($e) { <error><id>{$id}</id>{$e}</error> }
return
if (empty($errors)) then ( (: OK! :) )
else fn:error((), "MY-BATCHERROR", $errors)
虽然您可以为错误状态添加一个转换来实现这一点,但这确实使得用它们自己的错误标记单个文档变得棘手:查看批处理错误并将其放在每个引用的文档上。