user2038596
user2038596

Reputation: 569

how to guaranty orderly start/stop of multiple integration-flows

let's say that my application has the 2 following flows:

    @Bean
    IntegrationFlow flow1() {
        return IntegrationFlows.from(() -> LocalDateTime.now(), c -> c.poller(Pollers.fixedDelay(Duration.ofSeconds(10))))
                .channel("DIRECT_CHANNEL")
                .get();
    }

    @Bean
    IntegrationFlow flow2() {
        return IntegrationFlows.from("DIRECT_CHANNEL")
                .handle(lateToStartOutboundAdapter)
                .get();
    }

How do I guaranty that flow1 doesn't start sending messages before all components in flow2 are ready ?
More generally, how can I orderly start my integration-flows ?

My current way to do it, is as follows:
1) I define a controlBus Integration-flow:

@Bean
public IntegrationFlow controlBusFlow() {
    return IntegrationFlows.from("CONTROL_CHANNEL").controlBus().get();
}

2) I set the first endpoint component in all the other integration-flows to autoStart=false:

    @Bean
    IntegrationFlow flow1() {
        return IntegrationFlows.from(() -> LocalDateTime.now(),
                    c -> c.poller(Pollers.fixedDelay(Duration.ofSeconds(10)))
                            .autoStartup(false)
                            .id("flow1Component"))
                .transform(p -> p)
                .channel("DIRECT_CHANNEL")
                .get();
    }

    @Bean
    IntegrationFlow flow2() {
        return IntegrationFlows.from("DIRECT_CHANNEL")
                .transform(p -> p,
                        c -> c.autoStartup(false)
                              .id("flow2Component"))
                .log(LoggingHandler.Level.INFO, m -> m.toString())
                .get();
    }

3) finally I define a Server component where I start all my flows through the control-bus:

@Component
public class Server implements SmartLifecycle {

    private boolean running;
    List<String> flowComponents = ImmutableList.of("flow2Component","flow1Component")

    @Autowired
    @Qualifier("CONTROL_CHANNEL")
    private MessageChannel controlChannel;

    public void start() {
        flowComponents.forEach(s -> 
            controlChannel.send(MessageBuilder.withPayload("@" + s + ".start()").build());
        running = true;
    }

    public void stop() {
        flowComponents.reverse().forEach(s -> 
            controlChannel.send(MessageBuilder.withPayload("@" + s + ".stop()").build());
        running = false;
    }

    public boolean isRunning() {
        return running;
    }

Is above a valid way to orderly start/stop my integration-flows ?
Thank you very much in advance for your expertise. Best Regards

Upvotes: 1

Views: 437

Answers (1)

Gary Russell
Gary Russell

Reputation: 174544

There is no need to set autoStartup to false on a consumer from a DirectChannel; such components are not "active". All that start() does there is subscribe the consumer to the channel.

You only need to set it on the poller, and start that one when you are ready.

Upvotes: 2

Related Questions