首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Activiti Java服务任务:无需接收任务即可钝化

Activiti Java服务任务:无需接收任务即可钝化
EN

Stack Overflow用户
提问于 2016-05-10 20:55:44
回答 2查看 464关注 0票数 2

这个问题已经得到了回答,但解决方案对我来说还不是很有效。

Activiti异步行为相当简单,只允许用户启用一个标志,该标志告诉activiti引擎在执行队列(管理线程池)中插入此类任务。

我想要的不是将java服务任务插入池中,而是使其行为钝化,并且仅在接收到外部信号和/或调用回调时才完成此类任务。

我的尝试是:

代码语言:javascript
复制
class customAsyncTask extends TaskActivityBehavior {
  override def execute(execution: ActivityExecution): Unit = {
    val future = Future {
      println(s"Executing customAsyncTask -> ${execution.getCurrentActivityName}, ${cur}")
    }

    future.onComplete {
      case Success(result) => leave(execution)
      case _ => // whatever
    }
 }
  def signal(processInstanceId : String, transition : String) = {
    val commandExecutor =      main.processEngine.getProcessEngineConfiguration.asInstanceOf[ProcessEngineConfigurationImpl].getCommandExecutor
    val command = new customSignal(processInstanceId, transition)
    commandExecutor.execute(command)
  }

}

在我之前的代码示例中,我注册了一个scala future回调,当调用它时,它将终止当前的活动并转到下一个活动。

我还有一个signal方法,它构建一个自定义信号,它基于processId和一个名称调用execution.take,并进行适当的转换。

在这两种情况下,我都得到了以下错误(底层堆栈有一点变化)

代码语言:javascript
复制
java.lang.NullPointerException
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:636)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:629)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.take(ExecutionEntity.java:453)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.take(ExecutionEntity.java:431)
at org.activiti.engine.impl.bpmn.behavior.BpmnActivityBehavior.performOutgoingBehavior(BpmnActivityBehavior.java:140)
at org.activiti.engine.impl.bpmn.behavior.BpmnActivityBehavior.performDefaultOutgoingBehavior(BpmnActivityBehavior.java:66)
at org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.leave(FlowNodeActivityBehavior.java:44)
at org.activiti.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior.leave(AbstractBpmnActivityBehavior.java:47)

不幸的是,引擎很可能会在execute方法返回时擦除有关执行的信息,即使没有调用complete/leave/take。即使我的回调在上下文中有execution对象,当我使用它的进程ID查询信息时,我收到的所有信息都是空的。

那么,我到底做错了什么呢?我怎样才能达到我想要的行为?

EN

回答 2

Stack Overflow用户

发布于 2016-05-11 22:48:49

我没有看到任何具体的东西,我会说你需要扩展一个实现SignalableActivityBehavior的类,但我认为TaskActivityBehavior实际上做到了这一点。

虽然堆栈表明NPE来自leave(),但我搞不懂为什么leave调用" take“,因为take是一个转换事件,实际上应该只在标记为同步的任务上发生。

我所能提供的是,Camunda有一个类似于您的场景的示例实现。你也许可以用这个来帮助你:

https://github.com/camunda/camunda-bpm-examples/tree/master/servicetask/service-invocation-asynchronous

票数 1
EN

Stack Overflow用户

发布于 2016-05-12 00:41:32

看起来activiti使用了线程局部变量,这意味着从scala线程(scala执行器上下文)调用方法是没有意义的,因为它们不共享上下文。

要解决这个问题,我需要从回调中做的所有事情就是发出一个信号调用,就像我从远程系统调用一样。唯一的区别是我不需要保存我的流程实例标识符。

代码如下所示:

代码语言:javascript
复制
class AsynchronousServiceTask extends AbstractBpmnActivityBehavior {

  val exec_id : String = "executionId"

  override def execute(execution : ActivityExecution) = {
    val future = Future { println("Something") }

    future onComplete {
      case _ => myobject.callSignalForMe(execution.getId)
    }
  }

  override def signal(execution : ActivityExecution, signalName : String, signalData : AnyRef) = {
    println("Signal called, leaving current activity..")
    leave(execution)
  }
}

基本上,myobject持有runTimeEngine并将在ThreadLocal上下文中注入信号。一切都很干净,并按预期工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37139222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档