In a Spring Boot project, I sometimes need to "fire and forget" a time-consuming task from within an already non-blocking context, and to forward the current subscriber Context to it.
I have an implementation that works but I feel it may be overcomplicated or not recommended. Here is what I'm doing:
static Mono<Object> longTask() {
return Mono.deferContextual(ctx ->
Mono.delay(Duration.ofMillis(500))
.doOnSuccess(ignored -> System.out.println("print 2nd: " + ctx.get("x")))
);
}
// Improve me
static Mono<Object> fireAndForgetLongTask() {
return Mono.deferContextual(ctx -> {
longTask()
.contextWrite(ctx)
.subscribeOn(Schedulers.single())
.subscribe();
System.out.println("print 1st");
return Mono.empty();
});
}
// Hypothetical caller
public static void main(String[] args) {
fireAndForgetLongTask()
.contextWrite(Context.of("x", "42"))
.then(Mono.delay(Duration.ofMillis(1000)))
.block();
}
Is it correct to call .subscribe() from inside Mono.deferContextual()? Is there a simpler way to write fireAndForgetLongTask()?
Reading the documentation, I was under the impression that I could just do this:
static Mono<Object> fireAndForgetLongTask() {
return longTask()
.subscribeOn(Schedulers.single())
.doOnSuccess(ignored -> System.out.println("print 1st"));
}
but this doesn't work for me, it runs longTask synchronously and prints "print 1st" last.