![](/img/trans.png)
[英]Spring Integration DSL - Wait for input from channel in the flow
[英]Returning a value from direct channel flow and proceeding with async flow in Spring Integration
我的Web應用程序中具有以下集成配置:
@Bean
IntegrationFlow giraFlow() {
return IntegrationFlows.from(
MessageChannels.direct("gira.input"))
.split()
.transform(transformer)
.handle(parserService)
.channel(routerChannel())
.get();
}
@Bean
MessageChannel routerChannel() {
return MessageChannels.queue("routerChannel", 10)
.get();
}
@Bean
IntegrationFlow routerChannelFlow() {
return IntegrationFlows.from(
routerChannel())
.route(p -> p.getKind().name(),
m -> m.suffix("Channel")
.channelMapping(TaskKind.CREATE.name(), "create")
.channelMapping(TaskKind.RELOAD.name(), "reload")
.get();
}
和一個網關:
@MessagingGateway
public interface GW {
@Gateway(requestChannel = "gira.input")
Task gira(Collection<Request> messages);
}
和一個parserService
@Service
@Slf4j
public class ParserService {
public Task handle(IssueTrackerTask task) {
log.info("Parser service handling task {}", task);
return task;
}
}
我從Spring MVC控制器調用網關方法,我希望它向我返回一個Task
對象, parserService
在其body方法中返回該對象。 重要的是,我希望控制器被阻止,直到它從parserService
獲得值parserService
。 在獲得該值之后,我希望我的集成流程與routerChannelFlow
異步進行,以便Web控制器方法將盡快返回,並且routerChannelFlow
所有繁重的操作都將在不阻塞控制器的情況下完成。
這是具有此網關方法調用的控制器的一部分:
...
Task gira = gw.gira(messages);
log.info("Result {}", gira);
...
問題在於,永遠無法log.info
並且永遠gira()
網關。
我怎樣才能達到我期望的行為?
PS實際上我的應用程序中不需要parserService
,這正是我認為可以幫助我為網關定義返回值的東西,但實際上並沒有幫助:(
UPDATE
所以這是加里·羅素發表評論后得到的:
@Bean
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(10);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
return pool;
}
@Bean
MessageChannel routerChannel() {
return MessageChannels
.publishSubscribe("routerChannel", executor())
.get();
}
@Bean
IntegrationFlow routerChannelFlow() {
return IntegrationFlows
.from(routerChannel())
.publishSubscribeChannel(s -> s
.subscribe(f -> f
.bridge(null))
.subscribe(process()))
.get();
}
@Bean
IntegrationFlow process() {
return f ->
f.<IssueTrackerTask, String>route(p -> p.getKind().name(),
m -> m.suffix("Channel")
.channelMapping(TaskKind.CREATE.name(), "create")
.channelMapping(TaskKind.RELOAD.name(), "reload")
}
當我嘗試使用此管道時,出現以下錯誤Dispatcher has no subscribers for channel 'application:development:9000.dummy'
。 這絕對是一個配置錯誤的問題,但是我無法弄清楚我在做什么錯。
UPDATE
將channel("dummy")
更改為bridge(null)
。
create
和reload
渠道的下游是什么?
您如何在控制器中使用“ Task
結果(除了對其進行記錄)?
如果不需要結果,請將網關返回值更改為void並在網關下游添加執行程序通道。
如果要返回Task
對象,則需要routerChannel
成為具有執行者和兩個訂閱者的發布/訂閱通道-無處可通的橋梁(輸入通道和無輸出通道),它將Task
返回到網關,路由器,它將把Task路由到一個單獨的線程上; 路由器的下游流一定不能返回結果(網關將在很長一段時間內停止等待結果)。
無需將執行程序添加到routerChannel
,而是可以使兩個路由器通道的執行程序通道成為替代。
您的最后一個解決方案幾乎已經存在,您只需要使用.channel("dummy")
,而無需使用.publishSubscribeChannel()
第一.bridge(null)
訂閱者中的.bridge(null)
.publishSubscribeChannel()
。
您只需要將消息發送回網關的replyChannel
,即消息頭中的TemporaryReplyChannel
。
BridgeHandler
是“無所事事”的最佳方法,而只是將消息從標replyChannel
送到相應的replyChannel
。
如果您的.transform()
和.hanlde()
邏輯足夠繁重,還可以考慮在.split()
之后的通道中添加executor
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.