工作流引擎外部任务_独特的定时器要求

独特的定时器要求

     默认情况下,多个工作人员可以使用相同的workerId。为了确保workerId服务器端的唯一性,可以激活“唯一工人请求”标志。该配置标志仅影响长轮询请求,而不影响普通的“获取并锁定”请求。如果激活了“唯一工作人员请求”标志,workerId则在收到新请求时,具有该请求的未决请求将被取消。

     为了使“独特的工人请求”标志,则engine-rest/WEB-INF/web.xml包含在文件引擎休息 神器需要通过设置环境参数调整fetch-and-lock-unique-worker-request到true。请考虑以下配置片段:

  fetch-and-lock-unique-worker-request

  true

Java API

用于外部任务的Java API的入口点是ExternalTaskService。可以通过访问processEngine.getExternalTaskService()。

以下是一个交互示例,该交互可提取10个任务,循环处理这些任务,并且对于每个任务,要么完成任务,要么将其标记为失败。

List tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")

  .topic("AddressValidation", 60L * 1000L)

  .execute();

for (LockedExternalTask task : tasks) {

  try {

    String topic = task.getTopicName();

    // if the work is successful, mark the task as completed

    if(success) {

      externalTaskService.complete(task.getId(), variables);

    }

    else {

      // if the work was not successful, mark it as failed

      externalTaskService.handleFailure(

        task.getId(),

        "externalWorkerId",

        "Address could not be validated: Address database not reachable",

        1, 10L * 60L * 1000L);

    }

  }

  catch(Exception e) {

    //... handle exception

  }}

以下各节ExternalTaskService将更详细地介绍不同的交互。

抓取任务

   为了实现轮询工作程序,可以使用方法执行获取操作ExternalTaskService#fetchAndLock。此方法返回一个流畅的构建器,该构建器允许定义一组主题以为其提取任务。考虑以下代码片段:

List tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")

  .topic("AddressValidation", 60L * 1000L)

  .topic("ShipmentScheduling", 120L * 1000L)

  .execute();

for (LockedExternalTask task : tasks) {

  String topic = task.getTopicName();

  ...}

      此代码最多可提取主题AddressValidation和的10个任务ShipmentScheduling。结果任务只为ID为的工作人员锁定externalWorkerId。锁定意味着从获取时间开始为该工作者保留任务一定时间,并防止在锁定有效时其他工作者可以获取同一任务。如果锁到期并且任务尚未完成,则其他工作人员可以获取该锁,以使发生故障的工作人员不会无限期地阻止执行。确切的持续时间在单个主题访存说明中给出:的任务AddressValidation被锁定60秒(60L * 1000L毫秒),而的任务ShipmentScheduling被锁定120秒(120L * 1000L毫秒)。锁定到期时间不应短于预期的执行时间。如果这意味着太长的超时时间(如果在工作人员无提示的情况下重试任务),则该时间也不应太高。

可以与任务一起获取执行任务所需的变量。例如,假设AddressValidation任务需要一个address变量。使用此变量获取任务可能类似于:

List tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")

  .topic("AddressValidation", 60L * 1000L).variables("address")

  .execute();

for (LockedExternalTask task : tasks) {

  String topic = task.getTopicName();

  String address = (String) task.getVariables().get("address");

  ...}

然后,结果任务将包含所请求变量的当前值。请注意,变量值是从外部任务的执行在作用域层次结构中可见的值。有关详细信息,请参见“ 可变范围和可变可见性 ”一章。

为了获取所有变量,variables()应省略对方法的调用

List tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")

  .topic("AddressValidation", 60L * 1000L)

  .execute();

for (LockedExternalTask task : tasks) {

  String topic = task.getTopicName();

  String address = (String) task.getVariables().get("address");

  ...}

为了对序列化变量值(通常是存储自定义Java对象的变量)进行反序列化,必须调用enableCustomObjectDeserialization()。否则,一旦从变量映射中检索到序列化变量,就会引发一个异常,即该对象未反序列化。

List tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")

  .topic("AddressValidation", 60L * 1000L)

  .variables("address")

  .enableCustomObjectDeserialization()

  .execute();

for (LockedExternalTask task : tasks) {

  String topic = task.getTopicName();

  MyAddressClass address = (MyAddressClass) task.getVariables().get("address");

  ...}

外部任务优先级

外部任务优先级与工作优先级相似。饥饿也存在同样的问题,应予以考虑。有关更多详细信息,请参见“ 作业优先级 ”部分。

为外部任务优先级配置流程引擎

本节说明如何在配置中启用和禁用外部任务优先级。可以在流程引擎配置上设置两个相关的配置属性:

producePrioritizedExternalTasks:控制流程引擎是否为外部任务分配优先级。默认值为true。如果不需要优先级,则producePrioritizedExternalTasks可以将流程引擎配置属性设置为false。在这种情况下,所有外部任务的优先级都为0。有关如何指定外部任务优先级以及流程引擎如何为其分配优先级的详细信息,请参阅以下“ 指定外部任务优先级”部分

指定外部任务优先级

外部任务优先级可以在BPMN模型中指定,也可以在运行时通过API覆盖。

BPMN XML中的优先级

可以在流程或活动级别分配外部任务优先级。为此,pangu:taskPriority可以使用pangu扩展属性。

为了指定优先级,既支持常量值也支持表达式。使用恒定值时,会将相同的优先级分配给流程或活动的所有实例。另一方面,表达式允许为流程或活动的每个实例分配不同的优先级。表达式必须计算为Java long范围内的数字。具体值可以是复杂计算的结果,也可以基于用户提供的数据(来自任务表或其他来源)。

流程级别的优先级

在流程实例级别配置外部任务优先级时,pangu:taskPriority需要将该属性应用于bpmn 元素:

  ...

结果是,流程中的所有外部任务都继承相同的优先级(除非在本地将其优先级覆盖)。上面的示例显示了如何使用常数值设置优先级。这样,将相同的优先级应用于流程的所有实例。如果需要以不同的优先级执行不同的流程实例,则可以使用表达式:

  ...

在上面的示例中,优先级是根据priority变量的属性确定的order。

服务任务级别的优先级

在服务任务级别配置外部任务优先级时,pangu:taskPriority需要将该属性应用于bpmn 元素。服务任务必须是具有属性的外部任务pangu:type="external"。

  

               pangu:type="external"

pangu:topic="externalTaskTopic"

pangu:taskPriority="8"/>

  ...

结果是为已定义的外部任务设置了优先级(覆盖流程taskPriority)。上面的示例显示了如何使用常数值设置优先级。这样,在流程的不同实例中,相同的优先级将应用于外部任务。如果需要以不同的外部任务优先级执行不同的流程实例,则可以使用以下表达式:

  ...

  

               pangu:type="external"

   pangu:topic="externalTaskTopic"

   campanguunda:taskPriority="${order.priority}"/>

  ...

在上面的示例中,优先级是根据priority变量的属性确定的order。

优先获取外部任务

要根据优先级提取外部任务,可以使用ExternalTaskService#fetchAndLock带有参数的重载方法usePriority。没有boolean参数的方法可以任意返回外部任务。如果指定了参数,则返回的外部任务将按降序排列。请参阅以下有关外部任务优先级的示例:

List tasks =

  externalTaskService.fetchAndLock(10, "externalWorkerId", true)

  .topic("AddressValidation", 60L * 1000L)

  .topic("ShipmentScheduling", 120L * 1000L)

  .execute();

for (LockedExternalTask task : tasks) {

  String topic = task.getTopicName();

  ...}

 技术支持:盘古BPM工作流平台

相关教程