Why does subscribe work and block doesn't in Spring reactive Mongo?
I think this might be a Spring Framework bug / usability issue.
First, let me underline the difference between subscribe
and block
:
- the
subscribe
method kicks off the work and returns immediately. So you get no guarantee that the operation is done when other parts of your application run. block
is a blocking operation: it triggers the operation and waits for its completion.
For initialisation work, composing operations and calling block once is probably the best choice:
val jim: Mono<Person> = template.save(Person("Jim"))
val john: Mono<Person> = template.save(Person("John"))
val jack: Mono<Person> = template.save(Person("Jack"))
jim.then(john).then(jack).block();
As you've stated, using block
hangs the application. I suspect this might be an Spring context initialisation issue - If I remember correctly, this process might assume a single thread in some parts and using a reactive pipeline there schedules work on many threads.
Could you create a minimal sample application (using just Java/Spring Boot/Spring Data Reactive Mongo) and report that on https://jira.spring.io?
I had a similar situation where by calling "reactiveMongoTemplate.save(model).block()" the application was hanging.
The issue was caused by the @PostConstruct in one of my classes designed to create my system users after the application initialization. I think somehow It was invoked before full Spring context initialization.
@Configuration
public class InitialDataPostLoader {
private Logger logger = LogManager.getLogger(this.getClass());
@PostConstruct
public void init() {
logger.info(String.format(MSG_SERVICE_JOB, "System Metadata initialization"));
createDefaultUsers();
}
By replacing @PostConstruct with ContextRefreshEvent listener the issues got resolved.
@Configuration
public class InitialDataPostLoader implements
ApplicationListener<ContextRefreshedEvent> {
private Logger logger = LogManager.getLogger(this.getClass());
@Override
public void onApplicationEvent(ContextRefreshedEvent arg0) {
logger.info(String.format(MSG_SERVICE_JOB, "System Metadata initialization"));
createDefaultUsers();
}