繁体   English   中英

如何在 Spring 集成流程中正确实现延迟

[英]How to correctly implement delay in Spring Integration Flow

我正在尝试在 Spring 集成流程中实现延迟。
我有一个流程正在另一台服务器上启动一个进程,然后我在延迟后检查该进程是否完成。
完成后,流程应进入下一阶段。
这似乎有效,它也显示在日志中(很明显,在流程本身中), runexampleScriptWaiting通道中的一长串重复。

我尝试删除该频道更改,但随后流程永远停留在该阶段,永远不会完成。

如何实现这一点,以便显示/执行单个 runexampleScriptWaiting(我猜类似于非阻塞 while 循环)?

我考虑保持原样并仅更新我的监控应用程序(一个非常小的前端,显示有效负载历史中的哪些通道)以消除重复的通道行,但我也想知道是否有更好/更强大的方法来做这个。

这是一个简化的示例:

@Bean
public IntegrationFlow exampleIntegrationFlow() {
    return IntegrationFlows
            .from(exampleConfig.runexampleScript.get())
            .<ExamplePayload>handle((payload, messageHeaders) -> examplePayloadService
                    .changeExampleServiceRequestStatus(payload, ExampleServiceStatus.STARTED))
            .<ExamplePayload>handle(
                    (payload, messageHeaders) -> exampleScriptService.runexample(payload))
            .channel(exampleConfig.runexampleScriptWaiting.get())
            .<ExamplePayload, Boolean>route(jobStatusService::areJobsFinished,
                    router -> router
                            .subFlowMapping(true, exampleSuccessSubflow())
                            .subFlowMapping(false, exampleWaitSubflow())
                            .defaultOutputToParentFlow()
            )
            .get();
}

@Bean
public IntegrationFlow exampleWaitSubflow() {
    return IntegrationFlows
            .from(exampleConfig.runexampleScriptWaiting.get())
            .<ExamplePayload>handle(
                    (payload, messageHeaders) -> {
                        interruptIgnoringSleep(1000);
                        return payload;
                    })
            .channel(exampleConfig.runexampleScriptWaiting.get()) // Commenting this gets the process stuck
            .get();

}

目前尚不清楚您的exampleConfig.runexampleScriptWaiting.get()是什么,但是到目前为止您在配置中的内容还不行。 同一频道有两个订阅者:

  1. .channel(exampleConfig.runexampleScriptWaiting.get())和下一个route()

  2. .from(exampleConfig.runexampleScriptWaiting.get())和下一个handle()

这可能会导致意外行为,例如循环消息分发。

除了ExecutorChannel之外,我还会执行filter()delay() ,因为您询问的是非阻塞重试:

.channel(exampleConfig.runexampleScriptWaiting.get())
.filter(jobStatusService::areJobsFinished, 
            filter -> filter.discardFlow(
                          discardFlow -> discardFlow
                                            .delay(1000)
                                            .channel(exampleConfig.runexampleScriptWaiting.get())))

exampleSuccessSubflow可以 go 在此filter()之后作为此流的一部分或通过to(exampleSuccessSubflow())

注意那个discardFlow :我们稍微延迟未完成的消息并将其生成回那个runexampleScriptWaiting通道以再次调用此过滤器。 如果您将此通道设为ExecutorChannel (或QueueChannel ),您的等待功能将是非阻塞的。 但与此同时,由于您继续等待回复,您的主要流程仍将被此请求阻塞。 因此,将此过滤逻辑设为非阻塞可能没有太大意义,您仍然可以使用Thread.sleep()而不是delay()

路由器解决方案也可能有效,但您不能使用该runexampleScriptWaiting通道作为该子流的输入。 可能这就是您的“进程卡住”问题背后的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM