检测并终止 JavaScript 活动中的无限循环
在流程实例中运行的 JavaScript 和 Java 代码中可能会出现无限循环。 您可以在 100Custom.xml 文件中配置循环检测参数来检测无限循环并可选择结束它们。
当 JavaScript 代码中出现无限循环时,这会影响其他资源。 例如,工作流程服务器线程会丢失,直到服务器停止为止,这会影响服务器可用性。 为了检测无限循环, Business Automation Workflow 会监视每个脚本活动中已执行的 JavaScript 指令数。 其设置指令阈值和超时以检查脚本活动的持续时间。 当达到指令阈值时, JavaScript 引擎将调用 Business Automation Workflow 提供的回调,该回调用于检查脚本持续时间是否超过配置的超时。 如果超过超时,那么 Business Automation Workflow 将抛出 loop-detection-exception 或记录错误消息,具体取决于配置。 指令阈值的缺省值为 250,000 万条 JavaScript 指令。
备注信息:
- 对 Java 方法或 Business Automation Workflow JavaScript API 调用 (例如
tw.system.executeServiceByName) 的调用计为一条指令。 - 由服务器端组件引用的受管服务器端文件内的 JavaScript 代码记作个别指令,而不仅是一条指令。
通过使用以下循环检测参数,可以配置 Business Automation Workflow 提供回调的超时和指令阈值。 如果脚本持续时间超过超时,您可以选择停止脚本。
- loop-detection-duration:如果超过 loop-detection-duration 参数指定的超时值,那么假定活动处于无限循环中。 缺省持续时间设置为 20 秒,但可进行配置(请参阅以下示例)。
- loop-detection-exception: 缺省情况下,检测到无限循环时, Business Automation Workflow 引擎会将警告写入 SystemOut.log 文件,但脚本活动会继续执行。 要配置 Business Automation Workflow 引擎以停止无限循环脚本活动,请将 loop-detection-exception 参数设置为
true。如果 loop-detection-exception 参数设置为false,那么会向 SystemOut.log 文件中写入以下某条消息:CWLLG2261W: Infinite loop suspected after {0} seconds in ''UKNOWN'' activity. If this script is not in a loop, increase the loop-detection-duration property.CWLLG2263W: Infinite loop suspected after {0} seconds in ''{1}'', for BPD ''{2}'', script activity ''{3}''. If this script is not in a loop, increase the loop-detection-duration property.CWLLG2265W: Infinite loop suspected after {0} seconds in service ''{1}''. If this service is not in a loop, increase the loop-detection-duration property
如果 loop-detection-exception 参数设置为true,那么会向 SystemOut.log 文件中写入以下某条消息:CWLLG2262E: Infinite loop detected after {0} seconds, ''UKNOWN'' activity terminated. If this script is not in a loop, increase the loop-detection-duration property.CWLLG2264E: Infinite loop detected after {0} seconds in ''{1}'', for BPD ''{2}'', script activity ''{3}'' terminated. If this script is not in a loop, increase the loop-detection-duration property.CWLLG2266E: Infinite loop detected after {0} seconds, service ''{1}'' terminated. If this service is not in a loop, increase the loop-detection-duration property.
- instruction-threshold:在 JavaScript 代码在循环中进行 Java 调用并且大部分执行时间用于 Java 代码时,检测无限循环所用时间可能超过最佳时间。 250,000 万条 JavaScript 指令的缺省阈值所用时间可能远远超过配置的超时,并且脚本可能仍然长时间连续运行。 例如, JAR 文件的代码路径中的循环会阻止其返回到 Business Automation Workflow 引擎以进行处理,这将延长 JavaScript 活动的持续时间。 您可以使用 instruction-threshold 属性以在先前的循环检测的回调调用之间指定较小数量的 JavaScript 指令。
Business Automation Workflow 在指示 JavaScript 引擎调用循环检测回调之前,将配置的值乘以 1000。 缺省值为 250。 这意味着 JavaScript 引擎每 250,000 个 JavaScript 指令调用 Business Automation Workflow 循环检测回调。
以下示例说明如何在 100Custom.xml 文件中配置 JavaScript 循环检测参数:
<common merge="mergeChildren">
<javascript-engine>
<loop-detection-duration merge="replace">90</loop-detection-duration>
<loop-detection-exception merge="replace">true</loop-detection-exception>
<instruction-threshold merge="replace">250</instruction-threshold>
</javascript-engine>
</common>