![](/img/trans.png)
[英]How to convert Java Spring Flow to Spring Integration Work Flow with retry?
[英]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()
是什么,但是到目前为止您在配置中的内容还不行。 同一频道有两个订阅者:
.channel(exampleConfig.runexampleScriptWaiting.get())
和下一个route()
.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.