Hot Flux vs Cold Flux in Reactor

Author: Shazin Sadakath


Reactor Project is the defacto standard when it comes to developing Reactive applications using Spring Framework 5.0 and Spring Boot 2.0. Eventhough RxJava is supported Reactor Project has more support out of the box. Reactor Project provides constructs such as Flux and Mono to process data based on the occurence of the data.

When we talk about Flux which can hold a zero to infinity event stream, there are two most popular way of consuming or subscribing to that stream.

  1. Television (Hot) style of subscribing where you will be watching an active on going transmission and will get to view what is being transmitted from the time you switch on the Television onwards.
  2. Youtube (Cold) style of subscribing where you can always view from the beginning regardless of time joining.

These two styles of data transmission can be implemented using Reactor Flux construct similar to the following:

@Service
public class TelevisionService {

    public ConnectableFlux getTransmission() {
        return Flux.interval(Duration.ofSeconds(1)).map(s -> "Transmission "+s).publish();
    }
}

In the above TelevisionService, the method getTransmission will return a ConnectableFlux which is a specialized version of Flux implemented to support Hot data transmission when the publish method is invoked on the Flux. When we test this method as below:

public class TelevisionServiceTest {

    private TelevisionService televisionService = new TelevisionService();

    @Test
    public void hotFluxTest() throws Exception {
        ConnectableFlux hotFlux = televisionService.getTransmission();

        hotFlux.subscribe(c -> System.out.println("Subscribe 1 : "+c));
        hotFlux.connect();

        Thread.sleep(5000);

        hotFlux.subscribe(c -> System.out.println("Subscribe 2 : "+c));

        Thread.sleep(10000);
    }
}

We can see an output similar to below where Subscribe 1 will have the transmission from the beginning and Subscribe 2 would have missed the transmission sent during the previous 5 seconds before connecting.

Subscribe 1 : Transmission 0
Subscribe 1 : Transmission 1
Subscribe 1 : Transmission 2
Subscribe 1 : Transmission 3
Subscribe 1 : Transmission 4
Subscribe 1 : Transmission 5
Subscribe 2 : Transmission 5
Subscribe 1 : Transmission 6
Subscribe 2 : Transmission 6
Subscribe 1 : Transmission 7
Subscribe 2 : Transmission 7
Subscribe 1 : Transmission 8
Subscribe 2 : Transmission 8
Subscribe 1 : Transmission 9
Subscribe 2 : Transmission 9
Subscribe 1 : Transmission 10
Subscribe 2 : Transmission 10
Subscribe 1 : Transmission 11
Subscribe 2 : Transmission 11
Subscribe 1 : Transmission 12
Subscribe 2 : Transmission 12
Subscribe 1 : Transmission 13
Subscribe 2 : Transmission 13
Subscribe 1 : Transmission 14
Subscribe 2 : Transmission 14

Where as if we have a look at the YoutubeService.getPackets() method below which just returns a Flux:

@Service
public class YoutubeService {

    public Flux getPackets() {
        return Flux.interval(Duration.ofSeconds(1)).map(s -> "Packet "+s);
    }
}

And testing it with the below test case:

public class YoutubeServiceTest {

    private YoutubeService youtubeService = new YoutubeService();

    @Test
    public void coldFluxTest() throws Exception {
        Flux packets1 = youtubeService.getPackets();
        packets1.subscribe(c -> System.out.println("Packet Receiver 1 : "+c));

        Thread.sleep(5000);

        Flux packets2 = youtubeService.getPackets();
        packets2.subscribe(c -> System.out.println("Packet Receiver 2 : "+c));

        Thread.sleep(10000);
    }
}

Will print the following output:

Packet Receiver 1 : Packet 0
Packet Receiver 1 : Packet 1
Packet Receiver 1 : Packet 2
Packet Receiver 1 : Packet 3
Packet Receiver 1 : Packet 4
Packet Receiver 1 : Packet 5
Packet Receiver 2 : Packet 0
Packet Receiver 1 : Packet 6
Packet Receiver 2 : Packet 1
Packet Receiver 1 : Packet 7
Packet Receiver 2 : Packet 2
Packet Receiver 2 : Packet 3
Packet Receiver 1 : Packet 8
Packet Receiver 2 : Packet 4
Packet Receiver 1 : Packet 9
Packet Receiver 1 : Packet 10
Packet Receiver 2 : Packet 5
Packet Receiver 1 : Packet 11
Packet Receiver 2 : Packet 6
Packet Receiver 1 : Packet 12
Packet Receiver 2 : Packet 7
Packet Receiver 1 : Packet 13
Packet Receiver 2 : Packet 8
Packet Receiver 2 : Packet 9
Packet Receiver 1 : Packet 14

Where eventhough the Packet Receiver 2 starts subscribing 5 seconds after Packet Receiver 1 would still receive all the packets emitted by the Flux.

In summary a Cold Flux won't start emitting until a subscriber is attached to the Flux and will emit all the events to subscribers where a Hot Flux begins emitting data on creation/connection and each subscriber will get only the latest data from the point of subscription onwards.



Tags: Hot Cold Flux Reactor
Views: 370

Comments

Please login or register to post a comment.


There are currently no comments.