spring-cloud-stream icon indicating copy to clipboard operation
spring-cloud-stream copied to clipboard

spring cloud stream destroys The readyness state

Open GreenRover opened this issue 5 years ago • 6 comments

Describe the issue Originally invented @philwebb with: https://github.com/spring-projects/spring-boot/issues/7656 The "readiness" framework, that enables to register "ApplicationRunner" to ensure for example a "cache" is loaded before the application is ready to server.

But when spring cloud stream is used following happend:

@org.springframework.boot.SpringApplication#run(java.lang.String...) refreshContext(context); --> ScSt wants to create the binder --> DefaultBinderFactory starts a new inner SpringApplication --> It run again: SpringApplication#run(java.lang.String...)
--> callRunners(context, applicationArguments); // will not find any "ApplicationRunner", what is correct --> listeners.running(context); // called and fire the "ReadinessState.ACCEPT". This is the BUG --> .... spring cloud stream set up its binders ... callRunners(context, applicationArguments); // will execute the "ApplicationRunner" that is set up my application cache. listeners.running(context); // The "ReadinessState.ACCEPT" event gets fired that i expect.

To Reproduce Steps to reproduce the behavior:

  1. Download: readiness.zip
  2. If you dont like the solace binder replace against what ever you want.
  3. Run the spring application
  4. Wait for "BusinessLogic: load my cache from DB" in log
  5. Open on browser: http://localhost:9007/actuator/health/readinessState Expected: status: "OUT_OF_SERVICE" Current state: status: "OK"
  6. Wait for "BusinessLogic: cache load complete" in log Expected: status: "OK" Current state: status: "OK"

GreenRover avatar Jan 15 '21 10:01 GreenRover

I read now the history of the code up and down. But dont see a very god straight forward solution.

@philwebb Would it ok for you to:

Hand over here an argument like "--lister=suppress" https://github.com/spring-cloud/spring-cloud-stream/blob/master/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java#L325

To suppress all listeners including: https://github.com/spring-projects/spring-boot/blob/6254ad634ecb0dc73034038f82fcde75fb99117a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/event/EventPublishingRunListener.java

I would add here: https://github.com/spring-projects/spring-boot/blob/6254ad634ecb0dc73034038f82fcde75fb99117a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java#L449

if (Arrays.asList(args).contains("--lister=suppress")) {
  return Collectiosn.emptyList();
}

GreenRover avatar Jan 18 '21 09:01 GreenRover

It is a bit of pain that spring.factories are currently all or nothing. I don't particularly like the idea of using the arguments to suppress the listeners. I'd probably prefer dedicated methods on SpringApplication and SpringApplicationBuilder. Perhaps we should offer some kind of SpringFactoriesFilter interface that can accept or reject specific instances. Feel free to raise an issue on the Spring Boot issue tracker for that if you think it would help.

philwebb avatar Jan 18 '21 20:01 philwebb

I think that the new config data api could be used rather than Spring application

spencergibb avatar Jan 18 '21 23:01 spencergibb

Yes please, @spencergibb. If using the config data API lets you get rid of the context hierarchy, that sounds ideal to me. It would also simplify some other problems we've seen in SCS (IIRC) with the logging system when there's a child app with a different lifecycle to its parent.

wilkinsona avatar Jan 19 '21 08:01 wilkinsona

@spencergibb and I talked about this, so it is on my list of things to do, but will admit, low in priority especially with SCSt plans for 4.0.

olegz avatar Jan 19 '21 12:01 olegz

@olegz Can you give any release estimations? Or better time ranges? Can i support you some how?

GreenRover avatar Jan 19 '21 12:01 GreenRover