Search in sources :

Example 11 with Disposable

use of reactor.core.Disposable in project spring-data-mongodb by spring-projects.

the class ReactiveMongoTemplateTests method changeStreamEventsShouldBeFilteredCorrectly.

// DATAMONGO-1803
@Test
@Disabled("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
@EnableIfReplicaSetAvailable
void changeStreamEventsShouldBeFilteredCorrectly() throws InterruptedException {
    template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
    BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
    Disposable disposable = template.changeStream("person", ChangeStreamOptions.builder().filter(newAggregation(Person.class, match(where("age").gte(38)))).build(), Person.class).doOnNext(documents::add).subscribe();
    // just give it some time to link to the collection.
    Thread.sleep(500);
    Person person1 = new Person("Spring", 38);
    Person person2 = new Person("Data", 37);
    Person person3 = new Person("MongoDB", 39);
    // 
    Flux.merge(template.save(person1), template.save(person2), template.save(person3)).as(// 
    StepVerifier::create).expectNextCount(// 
    3).verifyComplete();
    // just give it some time to link receive all events
    Thread.sleep(500);
    try {
        assertThat(documents.stream().map(ChangeStreamEvent::getBody).collect(Collectors.toList())).containsExactly(person1, person3);
    } finally {
        disposable.dispose();
    }
}
Also used : Disposable(reactor.core.Disposable) StepVerifier(reactor.test.StepVerifier) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) VersionedPerson(org.springframework.data.mongodb.core.MongoTemplateTests.VersionedPerson) EnableIfReplicaSetAvailable(org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable) Test(org.junit.jupiter.api.Test) Disabled(org.junit.jupiter.api.Disabled)

Example 12 with Disposable

use of reactor.core.Disposable in project spring-data-mongodb by spring-projects.

the class ReactiveMongoTemplateTests method resumesAtTimestampCorrectly.

// DATAMONGO-2012, DATAMONGO-2113
@Test
@EnableIfMongoServerVersion(isGreaterThanEqual = "4.0")
@EnableIfReplicaSetAvailable
void resumesAtTimestampCorrectly() throws InterruptedException {
    template.dropCollection(Person.class).onErrorResume(it -> Mono.empty()).as(StepVerifier::create).verifyComplete();
    template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
    BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
    Disposable disposable = template.changeStream("person", ChangeStreamOptions.empty(), Person.class).doOnNext(documents::add).subscribe();
    // just give it some time to link to the collection.
    Thread.sleep(500);
    Person person1 = new Person("Spring", 38);
    Person person2 = new Person("Data", 37);
    Person person3 = new Person("MongoDB", 39);
    // 
    template.save(person1).delayElement(Duration.ofSeconds(1)).as(// 
    StepVerifier::create).expectNextCount(// 
    1).verifyComplete();
    // 
    template.save(person2).as(// 
    StepVerifier::create).expectNextCount(// 
    1).verifyComplete();
    // just give it some time to link receive all events
    Thread.sleep(500);
    disposable.dispose();
    // skip first
    documents.take();
    // take 2nd
    Instant resumeAt = documents.take().getTimestamp();
    template.save(person3).as(StepVerifier::create).expectNextCount(1).verifyComplete();
    BlockingQueue<ChangeStreamEvent<Person>> resumeDocuments = new LinkedBlockingQueue<>(100);
    template.changeStream("person", ChangeStreamOptions.builder().resumeAt(resumeAt).build(), Person.class).doOnNext(resumeDocuments::add).subscribe();
    // just give it some time to link receive all events
    Thread.sleep(500);
    try {
        assertThat(resumeDocuments.stream().map(ChangeStreamEvent::getBody).collect(Collectors.toList())).containsExactly(person2, person3);
    } finally {
        disposable.dispose();
    }
}
Also used : Disposable(reactor.core.Disposable) Instant(java.time.Instant) StepVerifier(reactor.test.StepVerifier) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) VersionedPerson(org.springframework.data.mongodb.core.MongoTemplateTests.VersionedPerson) EnableIfMongoServerVersion(org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion) EnableIfReplicaSetAvailable(org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable) Test(org.junit.jupiter.api.Test)

Example 13 with Disposable

use of reactor.core.Disposable in project spring-data-mongodb by spring-projects.

the class ReactiveChangeStreamOperationSupportTests method changeStreamEventsShouldBeConvertedCorrectly.

// DATAMONGO-1803
@Test
@EnableIfMongoServerVersion(isGreaterThanEqual = "4.0")
public void changeStreamEventsShouldBeConvertedCorrectly() throws InterruptedException {
    BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
    Disposable disposable = // 
    template.changeStream(Person.class).listen().doOnNext(documents::add).subscribe();
    // just give it some time to link to the collection.
    Thread.sleep(500);
    Person person1 = new Person("Spring", 38);
    Person person2 = new Person("Data", 39);
    Person person3 = new Person("MongoDB", 37);
    Flux.merge(template.insert(person1).delayElement(Duration.ofMillis(2)), template.insert(person2).delayElement(Duration.ofMillis(2)), // 
    template.insert(person3).delayElement(Duration.ofMillis(2))).as(// 
    StepVerifier::create).expectNextCount(// 
    3).verifyComplete();
    // just give it some time to link receive all events
    Thread.sleep(500);
    try {
        assertThat(documents.stream().map(ChangeStreamEvent::getBody).collect(Collectors.toList())).containsOnly(person1, person2, person3);
    } finally {
        disposable.dispose();
    }
}
Also used : Disposable(reactor.core.Disposable) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) StepVerifier(reactor.test.StepVerifier) EnableIfMongoServerVersion(org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion) Test(org.junit.jupiter.api.Test)

Example 14 with Disposable

use of reactor.core.Disposable in project spring-data-mongodb by spring-projects.

the class ReactiveMongoRepositoryTests method shouldUseTailableCursor.

// DATAMONGO-1444
@Test
void shouldUseTailableCursor() throws Exception {
    // 
    template.dropCollection(Capped.class).then(// 
    template.createCollection(// 
    Capped.class, CollectionOptions.empty().size(1000).maxDocuments(100).capped())).as(// 
    StepVerifier::create).expectNextCount(// 
    1).verifyComplete();
    template.insert(new Capped("value", Math.random())).as(StepVerifier::create).expectNextCount(1).verifyComplete();
    BlockingQueue<Capped> documents = new LinkedBlockingDeque<>(100);
    Disposable disposable = cappedRepository.findByKey("value").doOnNext(documents::add).subscribe();
    assertThat(documents.poll(5, TimeUnit.SECONDS)).isNotNull();
    template.insert(new Capped("value", Math.random())).as(StepVerifier::create).expectNextCount(1).verifyComplete();
    assertThat(documents.poll(5, TimeUnit.SECONDS)).isNotNull();
    assertThat(documents).isEmpty();
    disposable.dispose();
}
Also used : Disposable(reactor.core.Disposable) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) StepVerifier(reactor.test.StepVerifier) Test(org.junit.jupiter.api.Test)

Example 15 with Disposable

use of reactor.core.Disposable in project reactor-core by reactor.

the class FluxPublishOnTest method mapNotifiesOnce.

/**
 * See #294 the consumer received more or less calls than expected Better reproducible
 * with big thread pools, e.g. 128 threads
 *
 * @throws InterruptedException on interrupt
 */
@Test
public void mapNotifiesOnce() throws InterruptedException {
    final int COUNT = 10000;
    final Object internalLock = new Object();
    final Object consumerLock = new Object();
    final CountDownLatch internalLatch = new CountDownLatch(COUNT);
    final CountDownLatch consumerLatch = new CountDownLatch(COUNT);
    final AtomicInteger internalCounter = new AtomicInteger(0);
    final AtomicInteger consumerCounter = new AtomicInteger(0);
    final ConcurrentHashMap<Object, Long> seenInternal = new ConcurrentHashMap<>();
    final ConcurrentHashMap<Object, Long> seenConsumer = new ConcurrentHashMap<>();
    Sinks.Many<Integer> s = Sinks.many().multicast().onBackpressureBuffer();
    Flux<Integer> d = s.asFlux();
    /*Disposable c = */
    d.publishOn(Schedulers.parallel()).parallel(8).groups().subscribe(stream -> stream.publishOn(Schedulers.parallel()).map(o -> {
        synchronized (internalLock) {
            internalCounter.incrementAndGet();
            long curThreadId = Thread.currentThread().getId();
            Long prevThreadId = seenInternal.put(o, curThreadId);
            if (prevThreadId != null) {
                fail(String.format("The object %d has already been seen internally on the thread %d, current thread %d", o, prevThreadId, curThreadId));
            }
            internalLatch.countDown();
        }
        return -o;
    }).subscribe(o -> {
        synchronized (consumerLock) {
            consumerCounter.incrementAndGet();
            long curThreadId = Thread.currentThread().getId();
            Long prevThreadId = seenConsumer.put(o, curThreadId);
            if (prevThreadId != null) {
                fail(String.format("The object %d has already been seen by the consumer on the thread %d, current thread %d", o, prevThreadId, curThreadId));
            }
            consumerLatch.countDown();
        }
    }));
    final long start = System.currentTimeMillis();
    for (int i = 0; i < COUNT; i++) {
        long busyLoops = 0;
        while (s.tryEmitNext(i).isFailure()) {
            busyLoops++;
            if (busyLoops % 5000 == 0 && System.currentTimeMillis() - start >= 10_0000) {
                throw new RuntimeException("Busy loop timed out");
            }
        }
    }
    internalLatch.await(5, TimeUnit.SECONDS);
    assertThat(internalCounter).as("after 5s").hasValue(COUNT);
    consumerLatch.await(5, TimeUnit.SECONDS);
    assertThat(internalCounter).as("after 10s").hasValue(COUNT);
}
Also used : Arrays(java.util.Arrays) StepVerifier(reactor.test.StepVerifier) Schedulers.fromExecutorService(reactor.core.scheduler.Schedulers.fromExecutorService) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Random(java.util.Random) Disabled(org.junit.jupiter.api.Disabled) FluxOperatorTest(reactor.test.publisher.FluxOperatorTest) AfterAll(org.junit.jupiter.api.AfterAll) CoreSubscriber(reactor.core.CoreSubscriber) Attr(reactor.core.Scannable.Attr) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BeforeAll(org.junit.jupiter.api.BeforeAll) Duration(java.time.Duration) Schedulers.fromExecutor(reactor.core.scheduler.Schedulers.fromExecutor) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Executors(java.util.concurrent.Executors) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Fuseable(reactor.core.Fuseable) Assertions.fail(org.assertj.core.api.Assertions.fail) Exceptions(reactor.core.Exceptions) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) LongAdder(java.util.concurrent.atomic.LongAdder) Disposable(reactor.core.Disposable) Scannable(reactor.core.Scannable) Tuple2(reactor.util.function.Tuple2) Scheduler(reactor.core.scheduler.Scheduler) AtomicReference(java.util.concurrent.atomic.AtomicReference) Nullable(reactor.util.annotation.Nullable) ArrayList(java.util.ArrayList) Queues(reactor.util.concurrent.Queues) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Assertions.assertThatExceptionOfType(org.assertj.core.api.Assertions.assertThatExceptionOfType) Schedulers(reactor.core.scheduler.Schedulers) MockUtils(reactor.test.MockUtils) LinkedList(java.util.LinkedList) Subscriber(org.reactivestreams.Subscriber) ExecutorService(java.util.concurrent.ExecutorService) Publisher(org.reactivestreams.Publisher) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) Executors.newCachedThreadPool(java.util.concurrent.Executors.newCachedThreadPool) ForkJoinPool(java.util.concurrent.ForkJoinPool) FAIL_FAST(reactor.core.publisher.Sinks.EmitFailureHandler.FAIL_FAST) Subscription(org.reactivestreams.Subscription) AssertSubscriber(reactor.test.subscriber.AssertSubscriber) Collections(java.util.Collections) Timeout(org.junit.jupiter.api.Timeout) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) FluxOperatorTest(reactor.test.publisher.FluxOperatorTest) Test(org.junit.jupiter.api.Test)

Aggregations

Disposable (reactor.core.Disposable)120 Test (org.junit.jupiter.api.Test)101 CountDownLatch (java.util.concurrent.CountDownLatch)33 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)32 StepVerifier (reactor.test.StepVerifier)29 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)25 AtomicReference (java.util.concurrent.atomic.AtomicReference)18 Duration (java.time.Duration)15 List (java.util.List)15 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)15 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)15 Subscription (org.reactivestreams.Subscription)15 TimeUnit (java.util.concurrent.TimeUnit)14 Timeout (org.junit.jupiter.api.Timeout)13 CoreSubscriber (reactor.core.CoreSubscriber)12 ArrayList (java.util.ArrayList)11 Arrays (java.util.Arrays)11 Disabled (org.junit.jupiter.api.Disabled)11 Scannable (reactor.core.Scannable)11 Fuseable (reactor.core.Fuseable)10