La confusión acerca de las discusiones en flatMap del proyecto de reactor

dev123:

Estoy jugando con proyecto del reactor y repositorios MongoDB reactivos. Tengo un código siguiente:

@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document
public class Person {
    @Id
    Integer id;
    String name;
}
public interface ReactivePersonRepository extends ReactiveCrudRepository<Person, Integer> {
}

y la principal @SpringBootApplicationclase:

@SpringBootApplication
@EnableReactiveMongoRepositories
@RequiredArgsConstructor
public class ReactiveDatabaseApplication {

    private final ReactivePersonRepository reactivePersonRepository;

    public static void main(String[] args) {
        SpringApplication.run(ReactiveDatabaseApplication.class, args);
    }

    @PostConstruct
    public void postConstruct() {
        Scheduler single = Schedulers.newSingle("single-scheduler");
        IntStream.range(0, 10).forEach(i ->
                Flux.just(Person.builder()
                        .id(i)
                        .name("PersonName")
                        .build())
                        .flatMap(personToSave -> {
                            System.out.println(String.format(
                                    "Saving person from thread %s", Thread.currentThread().getName()));
                            return reactivePersonRepository.save(personToSave);
                        })
                        //.publishOn(single)
                        .flatMap(savedPerson -> {
                            System.out.println(String.format(
                                    "Finding person from thread %s", Thread.currentThread().getName()));
                            return reactivePersonRepository.findById(savedPerson.getId());
                        })
                        //.publishOn(single)
                        .flatMap(foundPerson -> {
                            System.out.println(String.format(
                                    "Deleting person from thread %s", Thread.currentThread().getName()));
                            return reactivePersonRepository.deleteById(foundPerson.getId());
                        })
                        //.publishOn(single)
                        .subscribeOn(single)
                        .subscribe(aVoid -> System.out.println(String.format(
                                "Subscription from thread %s", Thread.currentThread().getName()))));
    }
}

La Flux::subscribeOndescripción del método que dice:

Como tal, la colocación de este operador en cualquier lugar de la cadena también tendrá un impacto en la ejecución * contexto de señales onNext / OnError / onComplete desde el principio de la cadena hasta * la siguiente ocurrencia de un {@link publishOn (Scheduler) publishOn}

que es un poco confuso para mí, porque cuando no tengo ninguna publishOnespecificada en el procesamiento de la cadena, los valores impresos de nombres hilos son:

Ahorro de persona a partir de hilos de un solo programador-1 - como se esperaba

Encontrar a la persona a partir de hilos de rosca-13

Encontrar a la persona a partir de hilos de rosca-6

Encontrar a la persona a partir de hilos de rosca-15

persona Eliminación a partir de hilos de rosca-6

persona Eliminación a partir de hilos de rosca-5

persona Eliminación a partir de hilos de rosca-4

lo que no entiendo por qué. ¿No debería el planificador se especifica en el subscribeOnmétodo de utilizar para cada flatMapejecución?

Cuando me descomentar publishOnlíneas, todo lo que es ejecutado por el planificador solo dado, que es como se esperaba.

¿Alguien podría explicar por qué el único programador no es utilizada por flatMaplas operaciones, cuando no hay publishOn?

Michael Berry:

Este ejemplo artificial puede hacer que sea más claro:

Scheduler single = Schedulers.newSingle("single-scheduler");
Flux.just("Bob")
        .flatMap(x -> {
            System.out.println(String.format(
                    "Saving person from thread %s", Thread.currentThread().getName()));
            return Mono.just(x).publishOn(Schedulers.elastic());
        })
        .flatMap(x -> {
            System.out.println(String.format(
                    "Finding person from thread %s", Thread.currentThread().getName()));
            return Mono.just(x).publishOn(Schedulers.elastic());
        })
        .flatMap(x -> {
            System.out.println(String.format(
                    "Deleting person from thread %s", Thread.currentThread().getName()));
            return Mono.just(x).publishOn(Schedulers.elastic());
        })
        .subscribeOn(single)
        .subscribe(aVoid -> System.out.println(String.format(
        "Subscription from thread %s", Thread.currentThread().getName())));

Lo que dará algo similar a:

Saving person from thread single-scheduler-1
Finding person from thread elastic-2
Deleting person from thread elastic-3
Subscription from thread elastic-4

O, en otras palabras, su repositorio reactiva no está publicando en el mismo programador, y esta es la razón por la que se ve el comportamiento que haces. "Hasta la próxima ocurrencia de publishOn()" no significa que la próxima vez que sus llamadas de código publishOn()- también puede estar en cualquiera de los editores en ninguna de sus flatMap()llamadas, que usted no tendrá ningún control sobre.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=235304&siteId=1
Recomendado
Clasificación