Bug of Webflux

Spring Boot version: 3.3.3 Spring version: 6.1.11

A Webflux reactive controller method that responses a Mono, within which method it calls an 'Async' service method with the responses of a CompletableFuture. When the web request cancelled, the within async running method was not cancelled, stilling running, unless it was not running but queueing.

    @GetMapping("long-task")
    public Mono<LocalDateTime> longTask() throws InterruptedException {
        log.info("controller longTask entered");

        CompletableFuture<LocalDateTime> task = priceItemService.longTask();
        return Mono.fromCompletionStage(task)
                .doOnCancel(() -> {
                    task.cancel(true);
                    log.info("handler: longTask cancelled");
                })
                ;
    }
    @Async("single")
    public CompletableFuture<LocalDateTime> longTask() throws InterruptedException {
        log.info("service longTask entered");
        Thread.sleep(4000);

        log.info("longTask stage 2");
        log.info(".isInterrupted, {}", Thread.currentThread().isInterrupted());
        return CompletableFuture.completedFuture(LocalDateTime.now())
                ;
    }

or

    @GetMapping("long-task-a")
    public Mono<LocalDateTime> longTaskA() {
        log.info("controller longTaskA entered");

        return Mono.fromCallable(() -> {
                    TimeUnit.SECONDS.sleep(5);

                    log.info("longTaskA stage 2");
                    return LocalDateTime.now();
                })
                .doOnCancel(() -> {
                    log.info("handler: longTask cancelled");
                })
                ;
    }

Comment From: bclozel

I'm not sure what your code snippets are supposed to demonstrate and what's the expected behavior in each case. Anyway, I think that the current behavior is: * Reactor (Mono and Flux) will forward the cancel signal to the CompletableFuture instances, as expected * CompletableFuture has a specific behavior when it comes to cancellation

This behavior might not be consistent, but it is out of Spring Framework's control so I'm closing this. Thanks!