【问题标题】:Start/Stop mule flow programmatically以编程方式启动/停止 mule 流
【发布时间】:2017-11-10 15:30:39
【问题描述】:

我让我的一个流程说“流程 A”处于“停止”状态作为初始状态。然后在另一个流程中说“流程 B”,使用 groovy 脚本或 MEL 表达式;我正在启动相同的“流程 A”。在“流程 A”结束时,我以编程方式停止流程。

现在,如果我再次通过“流 B”启动“流 A”,它会失败,说“流 A”已经启动;无法重启。

对此的任何解决方案。

我想随时开始我的流程,将初始状态保持为已停止,最后再次使用脚本停止流程。

代码如下:

<flow name="FlowB">
    <poll doc:name="Poll">
        <logger level="INFO" doc:name="Logger"/>
    </poll>
    <logger level="INFO" doc:name="Logger" message="triggered"/>
    <scripting:component doc:name="Groovy">
        <scripting:script engine="Groovy"><![CDATA[muleContext.registry.lookupFlowConstruct('FlowB').start()]]></scripting:script>
    </scripting:component>
    <logger level="INFO" doc:name="Logger"/>
    <expression-component doc:name="Expression"><![CDATA[app.registry.FlowA.stop();]]></expression-component>
</flow>
<flow name="FlowA" initialState="stopped">
    <sqs:receive-messages config-ref="Amazon_SQS__Configuration" doc:name="Amazon SQS (Streaming)"/>
    <logger level="INFO" doc:name="Logger"/>
</flow> 

我正在使用轮询器来启动流程 A。所以,如果我再次运行流程 B 来启动流程 A;它抛出一个异常。

【问题讨论】:

    标签: groovy mule flow


    【解决方案1】:

    要么停止 flowA 不起作用(无论出于何种原因),要么您尝试在停止 flowA 后立即启动它。 AFAIK 的启动/停止是异步进行的,这意味着即使 stop() 方法已经返回,flowA 也可能处于启动状态。

    这是一个暴露/stop 和/start http-endpoints 的工作示例。

    <mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:spring="http://www.springframework.org/schema/beans" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
    http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
    http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
    http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
    http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd">
        <http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
    
        <flow name="flowA">
            <logger message="foobar" level="INFO" doc:name="Logger"/>
        </flow>
    
        <flow name="flowB_start">
            <http:listener config-ref="HTTP_Listener_Configuration" path="/start" doc:name="HTTP"/>
            <expression-transformer expression="#[groovy:muleContext.registry.get('flowA').start()]" doc:name="Expression"/>
        </flow>
    
        <flow name="flowB_stop">
            <http:listener config-ref="HTTP_Listener_Configuration" path="/stop" doc:name="HTTP"/>
            <expression-transformer expression="#[groovy:muleContext.registry.get('flowA').stop()]" doc:name="Expression"/>
        </flow>
    </mule>
    

    我可以随意启动/停止flowA。

    【讨论】:

    • 我认为你是对的。返回 stop() 后无法再次启动流程,因为它们正在异步工作。请看我的代码。
    • 您可以在流程停止后再次启动流程......但您必须等到将状态从启动切换到停止完成。解决这个时间问题的一个可能方法是结合使用 Anirbans isStarted-check 和增加轮询频率。
    【解决方案2】:

    这很容易处理,而且方法非常简单。您可以使用If else 条件来控制它。如果 FlowA 已经启动,它将忽略,否则它将按以下方式启动。

      <flow name="flowA" initialState="stopped">
            <http:listener config-ref="HTTP_Listener_Configuration" path="/flowA" doc:name="HTTP"/>
            <logger message="In flow A" level="INFO" doc:name="Logger"/>
        </flow>
    
        <flow name="flowB">
            <http:listener config-ref="HTTP_Listener_Configuration" path="/flowB" doc:name="HTTP"/>
            <scripting:component>
        <scripting:script engine="groovy">
        if(muleContext.registry.lookupFlowConstruct('flowA').isStarted())
        {
        System.out.println("flowA already started ... ignoring and do nothing")
        }
        else
        {
          muleContext.registry.lookupFlowConstruct('flowA').start()
         }
        </scripting:script>
    </scripting:component>
        </flow>
    

    更新

    <flow name="FlowB">
        <poll doc:name="Poll">
            <fixed-frequency-scheduler frequency="3000" />
            <logger level="INFO" doc:name="Logger" message="FlowB" />
        </poll>
        <logger message="test" level="INFO" doc:name="Logger" />
    
        <scripting:component doc:name="Script">
            <scripting:script engine="groovy"><![CDATA[
    if(muleContext.registry.lookupFlowConstruct('FlowA').isStarted())
    {
    System.out.println("flowA already started ... ignoring and do nothing")
    }
    else
    {
      muleContext.registry.lookupFlowConstruct('FlowA').start()
     }]]>
            </scripting:script>
        </scripting:component>
    
        <flow-ref name="FlowA" doc:name="FlowA" />
        <expression-component doc:name="Expression"><![CDATA[app.registry.FlowA.stop();]]></expression-component>
    </flow>
    
    
    <flow name="FlowA" initialState="stopped">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP" />
        <logger level="INFO" doc:name="Logger" message="In flowA" />
    </flow>
    

    【讨论】:

    • 感谢您的回复。我可以使用上述方法启动流程。但我的要求是在开始相同的流程后,我想在一段时间后停止。如果它是可能的?如果是,那么如果我执行相同的脚本来启动流程,它就会失败。抛出异常,提示此流程已启动,无法重新启动。所以,我猜 stop() 方法不起作用。
    • 你试过了吗?您只需将停止脚本放在 flowA 的末尾。一旦 flowA 启动并执行,它将在最后停止
    • 对于“此流程已启动,无法重新启动。”问题,它在 flowB 中处理,你不会再得到它了
    • 是的,我也试过了。重新启动后会抛出异常。
    • 你试过什么?你有什么例外?请找到符合您要求的更新答案
    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 2011-06-13
    • 2016-11-13
    • 1970-01-01
    相关资源
    最近更新 更多