簡體   English   中英

在Spring Integration中從直接通道流返回值並進行異步流

[英]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)

createreload渠道的下游是什么?

您如何在控制器中使用“ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM