试图找出以递归方式调用Mule流的正确方法。
我们有一个流程,它在运行时构建要执行的工作数组,然后使用“For Each”块中的“Flow Reference”递归调用自身。问题是,我们还没有想出将参数传递给这个递归流的正确方法,所以我们没有得到我们期望的结果。
我们尝试使用流属性(Groovy中的setInvocationParameter())传递参数,但似乎这些参数在流的多个实例之间共享。 举个例子,我们让ForEach数组迭代一个包含[2。但是,根据时间的不同,这些值中的一些会丢失(我们通常会看到2,然后是4两次 - 跳过3)。
我们尝试了不同的骡子处理策略而没有任何运气。 Mule的默认排队异步具有上述问题。同步似乎根本不起作用(因为我们的递归模型可能需要两个实例运行至少)才有意义。
这是配置XML的相关部分(整个流程非常大)。在流程的最后是:
<foreach collection="#[sessionVars['actionArray']]"
counterVariableName="actionIndex"
rootMessageVariableName="actionVar" doc:name="For Each">
<scripting:component doc:name="Run Each Action">
<scripting:script engine="Groovy">
<![CDATA[def aa = message.getSessionProperty('actionArray')
def this_item = aa.get(message.getInvocationProperty('actionIndex'))
// Pass the desired action for the recursive call
message.setInvocationProperty('FlowAction', this_item)
log.info "Running $this_item" // <- Shows the correct item
return]]>
</scripting:script>
</scripting:component>
<flow-ref name="DoAction" doc:name="Do Action"/>
</foreach>
在流程的前面,有一个记录器显示“FlowAction”流量变量。当我们使用我的[2,3,4]数组进行测试时,此记录器语句被驱动三次(如预期的那样),但通常值为2,4和4.
我们在Mule 3.7和我们拥有的3.4系统(两者都是Community Edition)上获得了相同的结果。
感谢Mule专家的任何建议......
答案 0 :(得分:0)
我不确定这是100%正确,但这就是我们所做的......
在花费大量时间试图让“For Each”和“Flow reference”方法可靠地工作之后,我们放弃了并转而使用不同的技术。我们的替代方法是删除For Each块并从一个简短的Groovy脚本递归驱动流:
. . .
// Invoke the flow recursively for every item in the array
Flow flow = muleContext.getRegistry().lookupFlowConstruct("flow name")
actions.each // actions is an array of integers built earlier
{ item->
MuleMessage msg = message.createInboundMessage()
DefaultMuleSession sess = new DefaultMuleSession(flow, muleContext)
DefaultMuleEvent event = new DefaultMuleEvent(msg, MessageExchangePattern.ONE_WAY, sess)
// Copy the current inbound properties to the new message
message.getInboundPropertyNames().each
{
event.getMessage().setProperty(it, message.getInboundProperty(it), PropertyScope.INBOUND)
}
// Copy the current session variables to the new message too
message.getSessionPropertyNames().each
{
event.setSessionVariable(it, message.getSessionProperty(it))
}
// Now set the item we want processed as a flow variable
event.setFlowVariable("Action", item.toString())
// Finally, trigger the flow (which runs asynchronously)
flow.process(event).getMessage()
}
现在,这在我们的环境中正常运行。