리액터에서 이런 함수는 왜 있는걸까? 목적이 뭘까?

결론만 말하면 비동기 Mono / Flux 를 동기적으로 기다려서 값을 꺼내기 위해 있다. Futureget 과 유사함.

val mono = Mono.just("hello")
    .delayElement(Duration.ofSeconds(1))

// 결과가 나올 때까지 현재 스레드 블로킹
val result: String? = mono.block()

println(result) // "hello" (1초 후 출력)

mono.block()                        // 무한 대기
mono.block(Duration.ofSeconds(3))   // 타임아웃 지정
flux.blockFirst()                   // Flux의 첫 번째 값
flux.blockLast()                    // Flux의 마지막 값

참고로 blockLast() 에서 값을 받으려면 마지막 값이라서 모든 Flux가 완료될때까지 블로킹되어야 한다.

이런 상황이 왜 필요할까?

리액티브코드와 동기식 코드의 경계에서 유용할 수 있다.

// 리액티브 세계
val userMono: Mono<User> = userService.find(1L)

// 명령형 세계로 꺼내야 할 때
val user: User = userMono.block()!!

WebFlux에서는 함부로 사용하면 안된다.

WebFlux서버는 쓰레드를 매우 적게 사용한다. 기본 설정이 CPU 코어수 * 2임. 그런데 block을 사용하면 이 몇 없는 쓰레드 하나를 점유해버린다. 그럼 다른 요청들이 처리될 쓰레드가 부족해져 처리량이 매우 떨어지거나 데드락 생길 수 있음.