0

I created a QueueChannel with capacity=500 and send 1000 messages there. Not all of them are printed; the number of the last one is 567. Why is this the case?

Here is the code:

@SpringBootApplication
@IntegrationComponentScan
public class QueueChannelResearch {

    @Bean
    public IntegrationFlow lambdaFlow() {
        return f -> f.channel(c -> c.queue(500))

            .handle(System.out::println);
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(QueueChannelResearch.class, args);

        MessageChannel inputChannel = ctx.getBean("lambdaFlow.input", MessageChannel.class);
        for (int i = 0; i < 1000; i++) {
            inputChannel.send(MessageBuilder.withPayload("w" + i)
                .build());
        }

        ctx.close();

    }

}

Here is the output:

GenericMessage [payload=w1, headers={id=d97946f2-1cf6-d681-fa88-08a4e708e61e, timestamp=1541524850590}]
...
GenericMessage [payload=w567, headers={id=83ab8720-f1c1-a4b1-b2ac-2a24a93bd00c, timestamp=1541524850590}]
GenericMessage [payload=w566, headers={id=d97946f2-1cf6-d681-fa88-08a4e708e61e, timestamp=1541524850590}]
GenericMessage [payload=w567, headers={id=83ab8720-f1c1-a4b1-b2ac-2a24a93bd00c, timestamp=1541524850590}]
Joel
  • 1,564
  • 7
  • 12
  • 20
Ekaterina
  • 1,642
  • 3
  • 19
  • 36

1 Answers1

2

Since messages are polled from the queue in the separate scheduling thread, you need really wait until you get all of them.

Since you don't have any hook in your application to track messages I only can suggest to add a Thread.sleep(10000) before that ctx.close().

Or you can add a hook to wait for the input from user in the console:

    System.out.println("Hit 'Enter' to terminate");
    System.in.read();
    ctx.close();

Or just don't close the ctx and rely on the JVM termination.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • thank you. And why does the program work without PollerMetadata bean whereas in [Cafe DSL](https://github.com/spring-projects/spring-integration-samples/blob/master/dsl/cafe-dsl/src/main/java/org/springframework/integration/samples/dsl/cafe/lambda/Application.java) app we have this bean: `@Bean(name = PollerMetadata.DEFAULT_POLLER) public PollerMetadata poller() { return Pollers.fixedDelay(10000) .get(); }` When should we define it? – Ekaterina Nov 06 '18 at 19:47
  • 1
    Probably you have some dependency which provides for your a default poller. I have just created an application with the code copied from your question and I ended up with this exception: `Caused by: java.lang.IllegalArgumentException: No poller has been defined for endpoint 'lambdaFlow.org.springframework.integration.config.ConsumerEndpointFactoryBean#1', and no default poller is available within the context.` – Artem Bilan Nov 06 '18 at 19:52