2013-12-16 50 views
3

我有一个线程安全问题围绕异步范围和流量变量和flow-ref组件。骡异步范围与流量参考和流量变量

以例如下列:

<flow> 
    <set-variable variableName="numericalValue" value="5" /> 
    <async> 
     <flow-ref name="calculate" /> 
    </async> 

    <set-variable variableName="numericalValue" value="10" /> 
    <async> 
     <flow-ref name="calculate" /> 
    </async> 
</flow> 

即时猜测流动VAR“numericalValue”可以从5第一流REF之前被改变为10被实际处理?

是否安全做到以下几点:

<flow> 

    <async> 
     <set-variable variableName="numericalValue" value="5" /> 
     <flow-ref name="calculate" /> 
    </async> 


    <async> 
     <set-variable variableName="numericalValue" value="10" /> 
     <flow-ref name="calculate" /> 
    </async> 
</flow> 

有人能解释这是如何工作的?

PS。 我的计算流量是一家民营异步流:

<flow name="calculate" processingStrategy="asynchronous"> 

回答

3

两种方法都是容易出现问题。让我解释一下为什么。

正如你可以在这里看到:https://github.com/mulesoft/mule/blob/mule-3.x/core/src/main/java/org/mule/processor/AsyncDelegateMessageProcessor.java#L112

// Clone event and make it async 
MuleEvent newEvent = new DefaultMuleEvent(
     (MuleMessage) ((ThreadSafeAccess) event.getMessage()).newThreadCopy(), event, false); 

骡子克隆处理async块之前的事件。所以人们可以认为一切都很好,克隆的事件与原始事件没有关系。

这是不幸的是没有的情况下,因为克隆的事件是原始事件的流程变量的支持,如下所示:https://github.com/mulesoft/mule/blob/mule-3.x/core/src/main/java/org/mule/DefaultMuleEvent.java#L328

if (rewriteEvent instanceof DefaultMuleEvent) 
{ 
    this.processingTime = ((DefaultMuleEvent) rewriteEvent).processingTime; 
    this.flowVariables = ((DefaultMuleEvent) rewriteEvent).flowVariables; 
} 

然后骡子消息被引用到这些流程变量这里https://github.com/mulesoft/mule/blob/mule-3.x/core/src/main/java/org/mule/DefaultMuleEvent.java#L953,因此可以通过Invocation属性范围访问它们。

所有这一切都导致在一个线程中更改的流变量在另一个线程中可见。

所以,如果你想完全隔离创建另一个流量变量或使用出站邮件属性,后者被复制不交叉引用每个:https://github.com/mulesoft/mule/blob/mule-3.x/core/src/main/java/org/mule/DefaultMuleMessage.java#L222