RukaDo
RukaDo

Reputation: 165

Can I use AtomicReference to get value of a Mono and code still remain reactive

Sorry, I am new to reactive paradigm. Is is possible to use AtomicReference to get value of a Mono since reactive code can run asynchronously and different events run on different thread. Please see the sample below. I am also not sure if this piece of code is considered reactive

sample code:

public static void main(String[] a) {
  AtomicReference<UserDTO> dto = new AtomicReference<>();
  Mono.just(new UserDTO())
      .doOnNext(d -> d.setUserId(123L))
      .subscribe(d -> dto.set(d));
  UserDTO result = dto.get();
  dto.set(null);
  System.out.println(result); // produce UserDTO(userId=123)
  System.out.println(dto.get()); // produce null
}

Upvotes: 1

Views: 1914

Answers (1)

Michael McFadyen
Michael McFadyen

Reputation: 3005

The code snippet you have shared is not guaranteed to always work. There is no way to guarantee that the function inside doOnNext will happen before dto.get(). You have created a race condition.

You can run the follow code to simulate this.

    AtomicReference<UserDTO> dto = new AtomicReference<>();
    Mono.just(new UserDTO())
            .delayElement(Duration.ofSeconds(1))
            .doOnNext(d -> d.setUserId(123L))
            .subscribe(dto::set);
    UserDTO result = dto.get();
    System.out.println(result); // produces null

To make this example fully reactive, you should print out in the subscribe operator

Mono.just(new UserDTO())
        .doOnNext(d -> d.setUserId(123L))
        .subscribe(System.out::println)

In a more "real world" example, your method would return a Mono<UserDTO> and you would then perform transformations on this using map or flatMap operators.

** EDIT **

If you are looking to make a blocking call within a reactive stream this previous stack overflow question contains a good answer

Upvotes: 4

Related Questions