繁体   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