简体   繁体   English

如何中断或取消Spring Integration Java DSL流?

[英]How to Interrupt or Cancel a Spring Integration Java DSL flow?

Contemplating implementation of a feature wherein a JdbcRepositoryHandler (implemnting MessageHandler ) might listen for an outside event (eg, CancelRunEvent ). 考虑某个功能的实现,其中JdbcRepositoryHandler (实现MessageHandler )可能会监听外部事件(例如CancelRunEvent )。

I think I'd use Spring' ApplicationEvent support to publish an event via a REST controller endpoint. 我想我会使用Spring的ApplicationEvent支持来通过REST控制器端点发布事件。 And I would guess I'd have the aforementioned handler implement ApplicationListener to listen for a particular event? 我猜想我会使用前面提到的处理程序实现ApplicationListener来监听特定事件吗?

The question is: if the handler is saturated with messages it needs to process, how would I signal termination of all subsequent messages that may have emanated upstream eg, from a FileSplitter ? 问题是: 如果处理程序中充满了需要处理的消息,我该如何终止可能从上游发出的所有后续消息(例如,来自FileSplitter 信号)的终止

While I could easily construct a condition to be checked before calling a method responsible eg, for a persistence operation (based on some state received from the CancelRunEvent ), how could I interrupt the flow entirely ? 虽然我可以在调用负责持久性操作的方法(基于从CancelRunEvent接收到的某些状态)之前轻松构造要检查的条件,但如何完全中断流程

For illustrative purposes, imagine a flow like: 出于说明目的,请设想如下流程:

@Bean
protected IntegrationFlow s3ChannelFlow() {
    // @see http://docs.spring.io/spring-integration/reference/html/files.html#file-reading
    // @formatter:off
    return IntegrationFlows
        .from(s3Channel())
        .enrichHeaders(h -> h.headerFunction(RunStats.FILE_TOKEN, f -> UUID.randomUUID().toString()))
        .channel(runStatsChannel())
        .transform(new FileToInputStreamTransformer())
        .split(new FileSplitter())
        .transform(new JsonToObjectViaTypeHeaderTransformer(new Jackson2JsonObjectMapper(objectMapper), typeSupport))
        .publishSubscribeChannel(p -> p.subscribe(persistenceSubFlow()))
        .get();
    // @formatter:on
}

@Bean
protected IntegrationFlow persistenceSubFlow() {
    // @formatter:off
    return f -> f
            // @see http://docs.spring.io/spring-integration/reference/html/messaging-routing-chapter.html#agg-and-group-to
            .aggregate(a -> a
                    .correlationStrategy(new HeaderAttributeCorrelationStrategy(RunStats.FILE_TOKEN))
                    .releaseStrategy(new MessageCountReleaseStrategy(persistenceBatchSize))
                    .sendPartialResultOnExpiry(true)
                    .expireGroupsUponCompletion(true)
                    .groupTimeoutExpression(persistenceBatchReleaseTimeoutMillis)
            )
            .handle(new JdbcRepositoryHandler(typeSupport, metricRegistry, runStatsRepository));
    // @formatter:on
}

It's not entirely clear what you mean or why you would need the JdbcRepositoryHandler to manage this rather than some other ApplicationListener . 目前尚不清楚您的意思是什么,或者为什么需要JdbcRepositoryHandler来管理它而不是其他ApplicationListener

Your flow is running on some thread upstream of s3Channel() . 您的流在s3Channel()上游的某个线程上运行。 Depending on what that is, you could stop() the message source and no new messages will be emitted after the current one (or ones if it's multi-threaded). 根据具体情况,您可以stop()消息源,并且在当前消息(或多线程消息)之后不会发出新消息。

However, you may (likely will) end up with a partial aggregation sitting in memory until the group times out. 但是,您可能(可能会)最终在内存中停留部分聚合,直到组超时。

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

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