인프런 커뮤니티 질문&답변

superpil님의 프로필 이미지

작성한 질문수

Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부

Sinks Example 코드 설명

Sinks multicast의 subscribe에 질문있습니다.

해결된 질문

작성

·

584

·

수정됨

2

안녕하세요.

Sinks multicast 예제에서 질문이 있습니다.

 

질문1

Many<String> sinks = Sinks.many().multicast().onBackpressureBuffer();
    Flux<String> flux = sinks.asFlux();

    sinks.emitNext("1", EmitFailureHandler.FAIL_FAST);
    sinks.emitNext("2", EmitFailureHandler.FAIL_FAST);

    flux.subscribe(data -> System.out.println("Subscribe1 : " + data));
    flux.subscribe(data -> System.out.println("Subscribe2 : " + data));

    sinks.emitNext("3", EmitFailureHandler.FAIL_FAST);

위 코드를 실행하면 결과는 아래와 같이 출력됩니다.
Subscribe1 : 1

Subscribe1 : 2

Subscribe1 : 3

Subscribe2 : 3

강사님이 말씀하신대로면
Subscribe1 : 1
Subscribe1 : 2

Subscribe2 : 1

Subscribe2 : 2

Subscribe1 : 3

Subscribe2 : 3
이렇게 동작될것같은데 다르게 출력되어 질문올립니다.

 

질문2

sinks.emitNext("3", EmitFailureHandler.FAIL_FAST);

마지막 emitNext는 2개의 subscribe()가 동작이되고 다음에 동작되는데 어떻게 subscribe를 할 수 있는걸까요?

답변 2

2

@Superpil 님

작성자님께서 생각했던 코드가 노출되려면 아래와 같이 작성하면 되더라구요

 

ColdSequence로 바꾸려면 multicast()메서드 대신 replay()를 사용하면 됩니다. 저도 질문보고 더 공부해보고 싶어서 찾아봤는데 이렇게 하면 되더라구요~~

 



참고 코드입니다.

@Slf4j
public class SinkManyExample03 {
    public static void main(String[] args) {
        Sinks.Many<Integer> unicastSink = Sinks.many()
                                               .replay().all();
                                               
        Flux<Integer> fluxView = unicastSink.asFlux();
        unicastSink.emitNext(1, FAIL_FAST);
        unicastSink.emitNext(2, FAIL_FAST);
        fluxView.subscribe(data -> log.info("Subscriber1 {}", data));
        fluxView.subscribe(data -> log.info("Subscriber2 {}", data));
        unicastSink.emitNext(3, FAIL_FAST);
    }
}

 

귀찮아서 변수명은 안바꿨네요 ㅋㅋㅋ...

2

Kevin님의 프로필 이미지
Kevin
지식공유자

안녕하세요? 좋은 질문 주셔서 감사합니다.

먼저 질문 주신 부분에 빠르게 답변을 드리겠습니다.

 

질문1

질문자님께서 실행 시킨 출력 결과가 맞습니다.

Sinks는 Hot Sequence로 동작하기 때문에 첫 번째 구독이 발생하는 시점에 숫자 1과 2를 전달 받습니다.

(Hot Sequence에는 두 가지 동작이 있는데 Subscriber가 구독을 하지 않아도 emit이 되는 방식, 그리고 최초의 구독이 있어야 비로소 emit이 되는 방식, 이렇게 두 가지가 있습니다. 여기서 후자의 방식을 Warm up 이라고 표현합니다.)
그리고 두 번째 구독이 발생하는 시점에는 이미 emit이 된 상태이기 때문에 숫자 1, 2를 전달 받지 않습니다.

마지막으로 숫자 3은 멀티캐스트로 전송되기 때문에 모든 Subscriber에게 전달이 됩니다.

 

결론적으로 제가 레코딩한 영상을 다시 돌려보니 제 설명이 틀렸네요.

실제 출간한 도서에는 정확하게 설명을 드렸습니다.

이해하는데 혼란스럽게 해드렸다면 죄송하구요.

업로드 되어 있는 영상을 수정하거나 별도로 공지해서 틀린 내용을 바로 잡도록 하겠습니다.

 

질문 2

앞에서 언급했지만 한번 더 말씀드리면 subscribe()가 두 번 호출된 시점에 이미 두 개의 Subscriber가 구독 중인 상태입니다. 위 예제 코드는 멀티캐스트 방식으로 동작하기 때문에 구독 중인 Subscriber가 모두 emit된 숫자 3을 전달 받습니다.

아마도 결과가 질문자님이 의도한 대로 출력이 되지 않아서 이해하는데 역시 혼란스러워진것 같습니다.

 

좋은 질문 주셔서 감사드리고, 다른 궁금한 점이 있으시면 언제든지 편하게 질문주시면 감사드리겠습니다.

superpil님의 프로필 이미지
superpil
질문자

답변감사합니다!

superpil님의 프로필 이미지

작성한 질문수

질문하기