Non-Blocking Reactive Foundation for the JVM

Overview

Reactor Core

Join the chat at https://gitter.im/reactor/reactor Reactor Core Latest

CI on GHA Codecov Code Quality: Java Total Alerts

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactive Extensions inspired API and efficient event streaming support.

Since 3.3.x, this repository also contains reactor-tools, a java agent aimed at helping with debugging of Reactor code.

Getting it

Reactor 3 requires Java 8 or + to run.

With Gradle from repo.spring.io or Maven Central repositories (stable releases only):

repositories {
    mavenCentral()

    // Uncomment to get access to Milestones
    // maven { url "https://repo.spring.io/milestone" }

    // Uncomment to get access to Snapshots
    // maven { url "https://repo.spring.io/snapshot" }
}

dependencies {
    compile "io.projectreactor:reactor-core:3.5.0-M5"
    testCompile "io.projectreactor:reactor-test:3.5.0-M5"

    // Alternatively, use the following for latest snapshot artifacts in this line
    // compile "io.projectreactor:reactor-core:3.5.0-SNAPSHOT"
    // testCompile "io.projectreactor:reactor-test:3.5.0-SNAPSHOT"

    // Optionally, use `reactor-tools` to help debugging reactor code
    // implementation "io.projectreactor:reactor-tools:3.5.0-M5"
}

See the reference documentation for more information on getting it (eg. using Maven, or on how to get milestones and snapshots).

Note about Android support: Reactor 3 doesn't officially support nor target Android. However it should work fine with Android SDK 21 (Android 5.0) and above. See the complete note in the reference guide.

Trouble importing the project in IDE?

Since the introduction of Java 9 stubs in order to optimize the performance of debug tracebacks, one can sometimes encounter cryptic messages from the build system when importing or re-importing the project in their IDE.

For example:

  • package StackWalker does not exist: probably building under JDK8 but java9stubs was not added to sources
  • cannot find symbol @CallerSensitive: probably building with JDK11+ and importing using JDK8

When encountering these issues, one need to ensure that:

  • Gradle JVM matches the JDK used by the IDE for the modules (in IntelliJ, Modules Settings JDK). Preferably, 1.8.
  • The IDE is configured to delegate build to Gradle (in IntelliJ: Build Tools > Gradle > Runner and project setting uses that default)

Then rebuild the project and the errors should disappear.

Getting Started

New to Reactive Programming or bored of reading already ? Try the Introduction to Reactor Core hands-on !

If you are familiar with RxJava or if you want to check more detailed introduction, be sure to check https://www.infoq.com/articles/reactor-by-example !

Flux

A Reactive Streams Publisher with basic flow operators.

  • Static factories on Flux allow for source generation from arbitrary callbacks types.
  • Instance methods allows operational building, materialized on each subscription (Flux#subscribe(), ...) or multicasting operations (such as Flux#publish and Flux#publishNext).

Flux in action :

Flux.fromIterable(getSomeLongList())
    .mergeWith(Flux.interval(100))
    .doOnNext(serviceA::someObserver)
    .map(d -> d * 2)
    .take(3)
    .onErrorResume(errorHandler::fallback)
    .doAfterTerminate(serviceM::incrementTerminate)
    .subscribe(System.out::println);

Mono

A Reactive Streams Publisher constrained to ZERO or ONE element with appropriate operators.

  • Static factories on Mono allow for deterministic zero or one sequence generation from arbitrary callbacks types.
  • Instance methods allows operational building, materialized on each Mono#subscribe() or Mono#get() eventually called.

Mono in action :

Mono.fromCallable(System::currentTimeMillis)
    .flatMap(time -> Mono.first(serviceA.findRecent(time), serviceB.findRecent(time)))
    .timeout(Duration.ofSeconds(3), errorHandler::fallback)
    .doOnSuccess(r -> serviceM.incrementSuccess())
    .subscribe(System.out::println);

Blocking Mono result :

Tuple2<Long, Long> nowAndLater = 
        Mono.zip(
                Mono.just(System.currentTimeMillis()),
                Flux.just(1).delay(1).map(i -> System.currentTimeMillis()))
            .block();

Schedulers

Reactor uses a Scheduler as a contract for arbitrary task execution. It provides some guarantees required by Reactive Streams flows like FIFO execution.

You can use or create efficient schedulers to jump thread on the producing flows (subscribeOn) or receiving flows (publishOn):

Mono.fromCallable( () -> System.currentTimeMillis() )
	.repeat()
    .publishOn(Schedulers.single())
    .log("foo.bar")
    .flatMap(time ->
        Mono.fromCallable(() -> { Thread.sleep(1000); return time; })
            .subscribeOn(Schedulers.parallel())
    , 8) //maxConcurrency 8
    .subscribe();

ParallelFlux

ParallelFlux can starve your CPU's from any sequence whose work can be subdivided in concurrent tasks. Turn back into a Flux with ParallelFlux#sequential(), an unordered join or use arbitrary merge strategies via 'groups()'.

Mono.fromCallable( () -> System.currentTimeMillis() )
	.repeat()
    .parallel(8) //parallelism
    .runOn(Schedulers.parallel())
    .doOnNext( d -> System.out.println("I'm on thread "+Thread.currentThread()) )
    .subscribe()

Custom sources : Flux.create and FluxSink, Mono.create and MonoSink

To bridge a Subscriber or Processor into an outside context that is taking care of producing non concurrently, use Flux#create, Mono#create.

Flux.create(sink -> {
         ActionListener al = e -> {
            sink.next(textField.getText());
         };

         // without cancellation support:
         button.addActionListener(al);

         // with cancellation support:
         sink.onCancel(() -> {
         	button.removeListener(al);
         });
    },
    // Overflow (backpressure) handling, default is BUFFER
    FluxSink.OverflowStrategy.LATEST)
    .timeout(3)
    .doOnComplete(() -> System.out.println("completed!"))
    .subscribe(System.out::println)

The Backpressure Thing

Most of this cool stuff uses bounded ring buffer implementation under the hood to mitigate signal processing difference between producers and consumers. Now, the operators and processors or any standard reactive stream component working on the sequence will be instructed to flow in when these buffers have free room AND only then. This means that we make sure we both have a deterministic capacity model (bounded buffer) and we never block (request more data on write capacity). Yup, it's not rocket science after all, the boring part is already being worked by us in collaboration with Reactive Streams Commons on going research effort.

What's more in it ?

"Operator Fusion" (flow optimizers), health state observers, helpers to build custom reactive components, bounded queue generator, converters from/to Java 9 Flow, Publisher and Java 8 CompletableFuture. The repository contains a reactor-test project with test features like the StepVerifier.


Reference Guide

https://projectreactor.io/docs/core/release/reference/docs/index.html

Javadoc

https://projectreactor.io/docs/core/release/api/

Getting started with Flux and Mono

https://github.com/reactor/lite-rx-api-hands-on

Reactor By Example

https://www.infoq.com/articles/reactor-by-example

Head-First Spring & Reactor

https://github.com/reactor/head-first-reactive-with-spring-and-reactor/

Beyond Reactor Core

  • Everything to jump outside the JVM with the non-blocking drivers from Reactor Netty.
  • Reactor Addons provide for adapters and extra operators for Reactor 3.

Powered by Reactive Streams Commons

Licensed under Apache Software License 2.0

Sponsored by VMware

Comments
  • Take doesn't limit requests

    Take doesn't limit requests

    It seems like take isn't implemented as a limit on the request, rather an instruction to cancel. This isn't great when the publisher involves a network call and the request n tells the server to publish as much as it wants.

            var f = Flux.range(0, 10).map {
                if (it > 4) {
                    throw RuntimeException("$it")
                } else {
                    it
                }
            }.log().take(5);
            println(f.blockLast());
    

    Output:

    INFO: | onSubscribe([Fuseable] FluxMapFuseable.MapFuseableSubscriber)
    Sep 23, 2017 9:19:37 AM reactor.util.Loggers$Slf4JLogger info
    INFO: | request(unbounded)
    Sep 23, 2017 9:19:37 AM reactor.util.Loggers$Slf4JLogger info
    INFO: | onNext(0)
    Sep 23, 2017 9:19:37 AM reactor.util.Loggers$Slf4JLogger info
    INFO: | onNext(1)
    Sep 23, 2017 9:19:37 AM reactor.util.Loggers$Slf4JLogger info
    INFO: | onNext(2)
    Sep 23, 2017 9:19:37 AM reactor.util.Loggers$Slf4JLogger info
    INFO: | onNext(3)
    Sep 23, 2017 9:19:37 AM reactor.util.Loggers$Slf4JLogger info
    INFO: | onNext(4)
    Sep 23, 2017 9:19:37 AM reactor.util.Loggers$Slf4JLogger info
    INFO: | cancel()
    4
    

    Expected:

    INFO: | request(5)
    
    opened by yschimke 48
  • Convert Marbles to SVG and rework diagrams

    Convert Marbles to SVG and rework diagrams

    Source for choice of fonts: http://www.ars-informatica.ca/article.php?article=59

    Changes:

    [doc] Rework marble diagrams into SVG This commit is a large rework of the marble diagrams:

    • started from the omnigraffle original exported to SVG
    • large rework of diagrams with clearer and more consistent semantics
    • large naming rework to be more consistent with operator names
    • creation of missing marble diagrams
    • javadoc modifications to point to new diagram names
    • main javadocs no longer point to URLs but expect an embedded doc-files set up
    • SVG use Tahoma/Nimbus and Lucida Console/Courier New font families

    [doc] Add "Contributing to SVG" README and task to copy SVG to doc-files

    Said task is run as part of processResources, which gives a chance that new users checking out the repo will see the quick documentation with diagrams after first building the project.

    type/documentation wide-change for/merge-with-rebase 
    opened by simonbasle 37
  • Fix OverflowException in MultiSubscriptionSubscriber

    Fix OverflowException in MultiSubscriptionSubscriber

    Fixes:

    public class FFTest {
        private static final Logger log = LoggerFactory.getLogger(FFTest.class);
    
        @Test
        public void test() {
            int round = 0;
            try {
                while (true) {
                    Flux.range(0, 10)
                        .concatWithValues(10, 11, 12, 13)
                        .concatWith(Flux.range(14, 100 - 14))
                        .limitRate(16, 2)
                        .publishOn(Schedulers.boundedElastic(), 16)
                        .subscribeOn(Schedulers.boundedElastic())
                        .blockLast();
                    log.info("Round : " + (round++));
                }
            } catch(Exception e) {
                log.error("", e);
            }
        }
    }
    
    13:06:20.429 [main] INFO com.ca.apm.tas.FFTest - Round : 0
    ......
    13:06:20.442 [main] INFO com.ca.apm.tas.FFTest - Round : 38
    13:06:20.442 [main] INFO com.ca.apm.tas.FFTest - Round : 39
    13:06:20.450 [main] ERROR com.ca.apm.tas.FFTest - 
    reactor.core.Exceptions$OverflowException: Queue is full: Reactive Streams source doesn't respect backpressure
    	at reactor.core.Exceptions.failWithOverflow(Exceptions.java:234)
    	at reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.onNext(FluxPublishOn.java:232)
    	at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:183)
    	at reactor.core.publisher.FluxRange$RangeSubscription.slowPath(FluxRange.java:154)
    	at reactor.core.publisher.FluxRange$RangeSubscription.request(FluxRange.java:109)
    

    Problem is that reactor.core.publisher.Operators.MultiSubscriptionSubscriber.drainLoop() is double counting missedRequested in case that missedSubscription happens during evaluation (two cycles). Example values:

    First iteration in drainLoop: missedRequested = 12, missedProduced = 0, requested = 2, missedSubscription = null, requestTarget = log requestAmount = 12

    Second iteration in drainLoop: missedRequested = 0, missedProduced = 0, requested = 14, missedSubscription = range
    requestTarget = range requestAmount = 26

    See that missedRequested (12) was counted twice so requestAmount is 26 instead of 14.

    opened by koldat 31
  • WindowTimeout backpressure

    WindowTimeout backpressure

    Expected behavior

    windowTimeout respects the backpressure

    Actual behavior

    Not verified if expected or not: The receiver is overrun by more signals than expected (bounded queue...)

    Steps to reproduce

    Flux
            .generate(sink -> {
                System.out.println("generate");
                sink.next(UUID.randomUUID().toString());
            })
            .log("source", Level.INFO, SignalType.REQUEST)
            .limitRate(5)
            .windowTimeout(10, Duration.ofSeconds(2))
            .concatMap(batch -> batch.delayElements(Duration.ofMillis(200)))
            .blockLast()
    

    Reactor Core version

    3.1.4.RELEASE

    JVM version (e.g. java -version)

    Any

    status/need-investigation 
    opened by bsideup 31
  • Android support

    Android support

    It would be nice to check what is needed to make reactor-core running on Android since Google recently announced Java 8 support on. It seems to me that this is supported as of Android Gingerbread (to be checked).

    The fist goal of this issue is to identify what are the blocking point to run Reactor 2.5 on Android (class not available, etc.)

    If somebody has the time to experiment with that that would be awesome.

    good first issue 
    opened by sdeleuze 30
  • `firstValue()` variant for `Mono` and `Flux`

    `firstValue()` variant for `Mono` and `Flux`

    Mono and Flux provide a first() method used for forming a publisher that replays all the signals of whichever publisher responds with any signal the fastest (as the docs say, effectively behaving like the fastest of the competing sources.) There are also or() methods which have the same behaviour, but are instance rather than static methods.

    However, no such method exists for replaying whichever publisher that emits the first value, rather than just the first signal.

    Motivation

    This is useful when wanting to use the fastest of several sources, but ignoring any sources that are empty or return an error.

    For instance, one may wish to use a value / stream of values returned by the fastest of a number of distributed sources / services; but would not want to consider any empty or erroneous sources.

    Desired solution

    Mono.firstValue() and Flux.firstValue() methods that use the publisher which returns the first value, not the first of any signal.

    Considered alternatives

    Mono.firstValue() could essentially be replaced by using Flux.merge(mono0, mono1).next();. Flux.firstValue(). Not immediately clear if there's an obvious way of emulating the same behaviour with a Flux.

    type/enhancement 
    opened by berry120 25
  • No emissions from other Flux in mergeWith().groupBy()

    No emissions from other Flux in mergeWith().groupBy()

    Flux<Type> first = Flux.generate(Consumer);
    Flux<Type> second = Flux.create(Consumer);
    
    Flux<GroupedFlux<Key, Type>> groupedFluxFlux = first.mergeWith(second).groupBy(type -> {
        //emissions from "second" never arrive
    });
    
    groupedFluxFlux.subscribe(groupedFlux -> {
        //do something with group
        Mono<Type> mono = groupedFlux.take(2).reduce( ... );
        mono.block();
    });
    

    I understand that "second" is a "cold" publisher which needs a subscription to start emitting. Why doesn't downstream subscription cause an upstream subscription to both of the merged "first" and "second?"

    Emissions from "second" occur if I subscribe() to it directly but of course that drains the Flux, which I don't want. I've tried turning "second" into a "hot" ConnectableFlux by calling publish(), subscribe(), and then connect(). Nothing works. What's wrong?

    for/stackoverflow 
    opened by westonlast 22
  • Subscriber error is causing share operator to fail the source flux and cancels all the clients

    Subscriber error is causing share operator to fail the source flux and cancels all the clients

    According to the share operator JavaDocs: "When all subscribers have cancelled it will cancel the source". My understanding of such statement is that problems of each and every subscriber are handled in isolation, and should not impact shared-flux itself. In fact, if I decide to create an empty subscription with no-args subscribe call, the shared flux should live until complete or error signal is propagated by the source.

    Flux<String>shared = Flux
                    .create(producer::set)
                    .log()
                    .share();
    shared.subscribe(); // Stay alive until producer issues complete or error
    

    Unfortunately, this is not true when one of the subscribers is going to fail without proper error handler provided. In such case, the shared flux and all the remaining subscribers will be canceled as well. This renders share as unusable and enforces custom implementation of the same behavior.

    Expected Behavior

    Subscriber error should cancel subscriber's flux and not shared flux.

    Actual Behavior

    Subscriber error is cancelling shared flux and thus all other subscribers are cancelled.

    Steps to Reproduce

     package test;
    
    import java.util.concurrent.atomic.AtomicReference;
    
    import org.junit.jupiter.api.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import reactor.core.publisher.BaseSubscriber;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.FluxSink;
    import reactor.test.StepVerifier;
    
    class SharedProblem {
        private static final Logger LOGGER = LoggerFactory.getLogger(SharedProblem.class.getName());
        private static final String TEST_MESSAGE = "Test";
    
        @Test
        void shouldNotCancelSharedWhenNoSubscriberError() {
            final AtomicReference<FluxSink<String>> producer = new AtomicReference<>();
            final Flux<String> flux = createSharedFlux(producer);
            flux.subscribe(); // This is keep alive subscription
    
            flux.subscribe(o -> LOGGER.debug("First client : {}", o));
            flux.subscribe(o -> LOGGER.debug("Second client : {}", o));
    
            StepVerifier
                    .create(flux)
                    .then(() -> sendMessage(producer))
                    .then(() -> sendComplete(producer))
                    .expectNext(TEST_MESSAGE)
                    .expectComplete()
                    .log()
                    .verify();
        }
    
        @Test
        void shouldNotCancelSharedWhenSubscriberThrowsExceptionAndErrorHandlerIsAbsent() {
            final AtomicReference<FluxSink<String>> producer = new AtomicReference<>();
            final Flux<String> flux = createSharedFlux(producer);
            flux.subscribe(); // This is keep alive subscription
    
            flux
                    .log()
                    .subscribe(new BaseSubscriber<String>() {
                        @Override
                        protected void hookOnNext(String value) {
                            throw new IllegalStateException("I'm failing");
                        }
    
                        @Override
                        public void dispose() {
                            super.dispose();
                        }
                    });
            flux
                    .log()
                    .subscribe(o -> LOGGER.debug("Second client : {}", o));
    
            StepVerifier
                    .create(flux)
                    .then(() -> sendMessage(producer))
                    .then(() -> sendComplete(producer))
                    .expectNext(TEST_MESSAGE)
                    .expectComplete()
                    .log()
                    .verify();
        }
    
        @Test
        void shouldNotCancelSharedWhenSubscriberThrowsExceptionAndErrorHandlerIsPresent() {
            final AtomicReference<FluxSink<String>> producer = new AtomicReference<>();
            final Flux<String> flux = createSharedFlux(producer);
            flux.subscribe(); // This is keep alive subscription
    
            flux
                    .log()
                    .subscribe(new BaseSubscriber<String>() {
                        @Override
                        protected void hookOnNext(String value) {
                            throw new IllegalStateException("I'm failing");
                        }
    
                        @Override
                        protected void hookOnError(Throwable throwable) {
                            LOGGER.error("Error {}", throwable);
                        }
    
                        @Override
                        public void dispose() {
                            super.dispose();
                        }
                    });
            flux
                    .log()
                    .subscribe(o -> LOGGER.debug("Second client : {}", o));
    
            StepVerifier
                    .create(flux)
                    .then(() -> sendMessage(producer))
                    .then(() -> sendComplete(producer))
                    .expectNext(TEST_MESSAGE)
                    .expectComplete()
                    .log()
                    .verify();
        }
    
        @Test
        void shouldNotCancelSharedWhenConsumerThrowsExceptionAndErrorHandlerIsAbsent() {
            final AtomicReference<FluxSink<String>> producer = new AtomicReference<>();
            final Flux<String> flux = createSharedFlux(producer);
            flux.subscribe(); // This is keep alive subscription
    
            flux
                    .log()
                    .subscribe(e -> {
                        throw new IllegalStateException("I'm failing");
                    });
            flux
                    .log()
                    .subscribe(o -> LOGGER.debug("Second client : {}", o));
    
            StepVerifier
                    .create(flux)
                    .then(() -> sendMessage(producer))
                    .then(() -> sendComplete(producer))
                    .expectNext(TEST_MESSAGE)
                    .expectComplete()
                    .log()
                    .verify();
        }
    
        @Test
        void shouldNotCancelSharedWhenConsumerThrowsExceptionAndErrorHandlerIsPresent() {
            final AtomicReference<FluxSink<String>> producer = new AtomicReference<>();
            final Flux<String> flux = createSharedFlux(producer);
            flux.subscribe(); // This is keep alive subscription
    
            flux
                    .log()
                    .subscribe(e -> {
                        throw new IllegalStateException("I'm failing");
                    }, e -> LOGGER.debug("Error handler", e));
            flux
                    .log()
                    .subscribe(o -> LOGGER.debug("Second client : {}", o));
    
            StepVerifier
                    .create(flux)
                    .then(() -> sendMessage(producer))
                    .then(() -> sendComplete(producer))
                    .expectNext(TEST_MESSAGE)
                    .expectComplete()
                    .log()
                    .verify();
        }
    
        @Test
        void shouldNotCancelSharedWorkAround() {
            final AtomicReference<FluxSink<String>> producer = new AtomicReference<>();
            final Flux<String> flux = createSharedFlux(producer);
            flux.subscribe();// This is keep alive subscription
    
            flux
                    .doOnNext(o -> {
                        throw new IllegalStateException("I'm failing");
                    })
                    .onErrorContinue((e, o) -> LOGGER.debug("I've failed, but I can survive {}", o, e))
                    .subscribe();
            flux
                    .log()
                    .subscribe(o -> LOGGER.debug("Second client : {}", o));
    
            StepVerifier
                    .create(flux)
                    .then(() -> sendMessage(producer))
                    .then(() -> sendComplete(producer))
                    .expectNext(TEST_MESSAGE)
                    .expectComplete()
                    .log()
                    .verify();
        }
    
        private Flux<String> createSharedFlux(AtomicReference<FluxSink<String>> producer) {
            return Flux
                    .create(producer::set)
                    .log()
                    .share();
        }
    
        private FluxSink<String> sendMessage(AtomicReference<FluxSink<String>> producer) {
            return producer
                    .get()
                    .next(TEST_MESSAGE);
        }
    
        private void sendComplete(AtomicReference<FluxSink<String>> producer) {
            producer
                    .get()
                    .complete();
        }
    
    }
    

    Possible Solution

    The best possible solution is to have the same response on errors like in groupBy operator. In groupBy when one of the generated streams is failing, it is recreated and may continue its work. The most important here is that source flux is not impacted. Similar behavior is expected from the share operator. The source Flux should survive and continue its work, and just the failing client shall be canceled. One of the provided test cases is showing how one can make sure that the failing Flux is not going to break anything else. However, there is no real WA when third party subscriber is involved e.g. WebFlux. In fact, the problem was detected in code that takes advantage of Spring WebFlux. Most likely, the root cause is that client has detached and was canceled, there was no new element propagated for long time period, and WebFlux (or servlet container) has triggered some timeout which changed the subscriber's state further. As a result, and incoming element has triggered an exception in WebFlux subscriber and propagated the failure to the shared flux.

    Your Environment

    • Reactor version(s) used: Reactor version(s) used: 3.3.1.RELEASE
    • JVM version (javar -version): 1.8.0_202-release-1483-b58 amd64
    • OS and version (eg uname -a): Windows Version 6.1 (Build 7601: SP1)
    status/declined 
    opened by create1st 21
  • Refactor of retryWhen to switch to a Spec/Builder model

    Refactor of retryWhen to switch to a Spec/Builder model

    This big commit is a large refactor of the retryWhen operator in order to add several features.

    Fixes #1978 Fixes #1905 Fixes #2063 Fixes #2052 Fixes #2064

    • Expose more state to retryWhen companion (#1978)

    This introduces a retryWhen variant based on a Retry functional interface. This "function" deals not with a Flux of Throwable but of RetrySignal. This allows retry function to check if there was some success (onNext) since last retry attempt, in which case the current attempt can be interpreted as if this was the first ever error.

    This is especially useful for cases where exponential backoff delays should be reset, for long lived sequences that only see intermittent bursts of errors (transient errors).

    We take that opportunity to offer a builder for such a function that could take transient errors into account.

    • the Retry builders

    Inspired by the Retry builder in addons, we introduce two classes: RetrySpec and RetryBackoffSpec. We name them Spec and not Builder because they don't require to call a build() method. Rather, each configuration step produces A) a new instance (copy on write) that B) is by itself already a Retry.

    The Retry + xxxSpec approach allows us to offer 2 standard strategies that both support transient error handling, while letting users write their own strategy (either as a standalone Retry concrete implementation, or as a builder/spec that builds one).

    Both specs allow to handle transientErrors(boolean), which when true relies on the extra state exposed by the RetrySignal. For the simple case, this means that the remaining number of retries is reset in case of onNext. For the exponential case, this means retry delay is reset to minimum after an onNext (#1978).

    Additionally, the introduction of the specs allows us to add more features and support some features on more combinations, see below.

    • filter exceptions (#1905)

    Previously we could only filter exceptions to be retried on the simple long-based retry methods. With the specs we can filter in both immediate and exponential backoff retry strategies.

    • Add pre/post attempt hooks (#2063)

    The specs let the user configure two types of pre/post hooks. Note that if the retry attempt is denied (eg. we've reached the maximum number of attempts), these hooks are NOT executed.

    Synchronous hooks (doBeforeRetry and doAfterRetry) are side effects that should not block for too long and are executed right before and right after the retry trigger is sent by the companion publisher.

    Asynchronous hooks (doBeforeRetryAsync and doAfterRetryAsync) are composed into the companion publisher which generates the triggers, and they both delay the emission of said trigger in non-blocking and asynchronous fashion. Having pre and post hooks allows a user to better manage the order in which these asynchronous side effect should be performed.

    • Retry exhausted meaningful exception (#2052)

    The Retry function implemented by both spec throw a RuntimeException with a meaningful message when the configured maximum amount of attempts is reached. That exception can be pinpointed by calling the utility Exceptions.isRetryExhausted method.

    For further customization, users can replace that default with their own custom exception via onRetryExhaustedThrow. The BiFunction lets user access the Spec, which has public final fields that can be used to produce a meaningful message.

    • Ensure retry hooks completion is taken into account (#2064)

    The old retryBackoff would internally use a flatMap, which can cause issues. The Spec functions use concatMap.

    /!\ CAVEAT

    This commit deprecates all of the retryBackoff methods as well as the original retryWhen (based on Throwable companion publisher) in order to introduce the new RetrySignal based signature.

    The use of Retry explicit type lifts any ambiguity when using the Spec but using a lambda instead will raise some ambiguity at call sites of retryWhen.

    We deem that acceptable given that the migration is quite easy (turn e -> whatever(e) to (Retry) rs -> whatever(rs.failure())). Furthermore, retryWhen is an advanced operator, and we expect most uses to be combined with the retry builder in reactor-extra, which lifts the ambiguity itself.

    opened by simonbasle 20
  • Reactor Kore - A Cross-Platform Non-Blocking Reactive Foundation

    Reactor Kore - A Cross-Platform Non-Blocking Reactive Foundation

    Preface

    This past year, Kotlin's growth has been remarkable and Jetbrains strong position to make Kotlin available in the Mobile, Browser, Server and Desktop platforms is exciting to say the least.

    At the same time, the asynchronous programming space has been increasingly active as well. JVM reactive libraries (RxJava2, Reactor) have had major releases and the ecosystems surrounding them have increased the adoption and/or facilitated asynchronous programming (Android Architecture Components, Spring 5, etc). Moreover, the intersection between the management of data mutation and asynchronicity continues to lead an explosion of interest in patterns/frameworks (CycleJS, Flux, CQRS, Event-Sourcing, Redux) to address this concerns. This can be seen as well from the increase of literature in this space.

    This two trends together present a great opportunity for rich collaboration between software communities spanning multiple platforms.

    Reactor Kore

    The purpose of this issue is to bring forth conversation regarding the possibility/feasibility of building a kotlin-based cross-platform reactor-core. For starters, this core could target both the JVM and the Android environments.

    Members of the Android/ReactiveX community have expressed interest in a Kotlin implementation of RxJava2 and there are some interesting experiments to leverage kotlin coroutines to simplify job scheduler code. A kotlin-based reactor could be an interesting path as well.

    It'd be great to hear your thoughts.

    @thomasnield @JakeWharton @stepango @smaldini @simonbasle @elizarov @sdeleuze

    status/declined status/need-design 
    opened by PedroAlvarado 20
  • DirectProcessor using ParallelFlux crashes with error

    DirectProcessor using ParallelFlux crashes with error "Queue is full?!"

    Expected behavior

    DirectProcessor using ParallelFlux should help us support high throughput and reliability. (We cannot require restart on fail).

    Actual behavior

    I'm getting the following exception after a while and i'm not sure what to do:

    reactor.core.Exceptions$OverflowException: Queue is full?! at reactor.core.Exceptions.failWithOverflow(Exceptions.java:152) ~[reactor-core-3.0.7.RELEASE.jar:3.0.7.RELEASE] at reactor.core.publisher.ParallelSource$ParallelSourceMain.onNext(ParallelSource.java:231) ~[reactor-core-3.0.7.RELEASE.jar:3.0.7.RELEASE] at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:96) ~[reactor-core-3.0.7.RELEASE.jar:3.0.7.RELEASE] at reactor.core.publisher.DirectProcessor$DirectInner.onNext(DirectProcessor.java:304) ~[reactor-core-3.0.7.RELEASE.jar:3.0

    do i need to 'release' the queue at some point? what might be the cause for it to be full?

    Steps to reproduce

    Just tried to create several events (onNext) and i have 16 subscribers with filter. For example:

    public void subscribe(eventRoute, Request flow) {
    ParallelFlux<Request> parallelFlux = directProcessor.filter(flow -> flow.getPayload().getEventRoute().equals(eventRoute))
    					.parallel()
    					.log()
    					.runOn(Schedulers.fromExecutor(excuterService));
    parallelFlux.subcribe(() -> {do something with try and catch}
    }
    

    //In events call directProcessor.onNext(req);

    This is super important for us, this happened in production environment right now..

    Reactor Core version

    3.0.7.RELEASE

    JVM version (e.g. java -version)

    1.8.0_121

    OS version (e.g. uname -a)

    MINGW64_NT-10.0 ADAMB-DELL 2.6.1(0.306/5/3) 2017-01-20 15:23 x86_64 Msys

    for/stackoverflow 
    opened by BerlinAdam87 20
  • concatMapIterable does not work for SYNC fusion and empty iterable

    concatMapIterable does not work for SYNC fusion and empty iterable

    For specific pipelines where SYNC is used for concatMapIterable operator it fails with empty iterable.

    Expected Behavior

    concatMapIterable should work for empty iterators ending up as empty Flux for example.

    Actual Behavior

    NoSuchElementException thrown when inner iterator is empty:

    java.lang.AssertionError: expectation "expectComplete" failed (expected: onComplete(); actual: onError(java.util.NoSuchElementException))
    	at reactor.test.MessageFormatter.assertionError(MessageFormatter.java:115)
    	at reactor.test.MessageFormatter.failPrefix(MessageFormatter.java:104)
    	at reactor.test.MessageFormatter.fail(MessageFormatter.java:73)
    	at reactor.test.MessageFormatter.failOptional(MessageFormatter.java:88)
    	at reactor.test.DefaultStepVerifierBuilder.lambda$expectComplete$4(DefaultStepVerifierBuilder.java:344)
    	at reactor.test.DefaultStepVerifierBuilder$SignalEvent.test(DefaultStepVerifierBuilder.java:2289)
    	at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onSignal(DefaultStepVerifierBuilder.java:1529)
    	at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onExpectation(DefaultStepVerifierBuilder.java:1477)
    	at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onError(DefaultStepVerifierBuilder.java:1129)
    	at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drainSync(FluxFlattenIterable.java:636)
    	at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drain(FluxFlattenIterable.java:721)
    	at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.request(FluxFlattenIterable.java:303)
    	at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onSubscribe(DefaultStepVerifierBuilder.java:1161)
    	at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.onSubscribe(FluxFlattenIterable.java:222)
    	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178)
    	at reactor.core.publisher.FluxJust.subscribe(FluxJust.java:68)
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8660)
    	at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.toVerifierAndSubscribe(DefaultStepVerifierBuilder.java:891)
    	at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:831)
    	at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:823)
    	at com.ca.apm.common.ReactorTest.concatMapIterableTest(ReactorTest.java:70)
    

    Steps to Reproduce

    This unit test fails for latest version (it was working for older releases 3.4.x):

        @Test
        public void concatMapIterableTest() throws IOException {
            StepVerifier.create(
                Flux.just(1)
                    .log() // Without .log it works as it uses another branch in source code
                    .concatMapIterable(i -> {
                        Iterator<Integer> it = Collections.emptyIterator();
                        return () -> it;
                    }))
            .expectComplete()
            .verify();
        }
    

    Possible Solution

    This line should most likelly be same as in async drain: https://github.com/reactor/reactor-core/blob/main/reactor-core/src/main/java/reactor/core/publisher/FluxFlattenIterable.java#L591

    isEmpty = itFinite && sp.estimateSize() == 0;
    

    Async drain is hasNext check that cporrectly identify my case is empty: https://github.com/reactor/reactor-core/blob/main/reactor-core/src/main/java/reactor/core/publisher/FluxFlattenIterable.java#L385

    isEmpty = itFinite ? sp.estimateSize() == 0 : !hasNext(sp);
    

    Your Environment

    • Reactor version(s) used: 3.5.1
    • JVM version (java -version): openjdk version "17.0.4.1"
    • OS and version (eg uname -a): Linux, Windows
    :question:need-triage 
    opened by koldat 0
  • Add tests for AOT reflection hints

    Add tests for AOT reflection hints

    In #3325 @violetagg added reflection hints for AOT builds and tested against spring smoke tests. We should be able to provide a smoke test within reactor-core repository. The below can be used as inspiration:

    • https://github.com/spring-projects/spring-aot-smoke-tests
    • https://github.com/oracle/graalvm-reachability-metadata
    type/enhancement 
    opened by chemicL 0
  • Sinks.many replay limit not respected

    Sinks.many replay limit not respected

    Max-age limit is one of the available features offered by MulticastReplaySpec. Events are supposed to be expired after a ttl/maxAge, and therefore not fed downstream when new subscribers join.

    From my observation, this contract is only respected if events are continuously added to the Sink, otherwise, expired values are kept forever ( or until the next event is added to the sink ), and - therefore - new subscribers are presented with expired events.

    Expected Behavior

    Expired events should not be presented to subscribers, even if sink is in "idle", meaning, no new events have been added to it.

    Actual Behavior

    Expired events are not removed, and new subscribers can see them.

    Steps to Reproduce

    package pt.goncalo.gitissues.reactor
    
    import org.junit.jupiter.api.Test
    import reactor.core.publisher.Sinks
    import reactor.test.StepVerifier
    import java.time.Duration
    import java.util.stream.IntStream
    
    class ReactorReplayTest {
    
    
        /**
         * This test is failing, because MulticastReplaySpec seems to only clear expired items after an operation
         * (like next) is called
         *
         */
        @Test
        fun `it should receive no event if sent before maxAge gap - even without add`() {
            val maxAge = Duration.ofSeconds(1)
            val instance = Sinks.many().replay().limit<String>(maxAge)
    
            IntStream
                .range(0, 100)
                .mapToObj { "$it" }
                .forEach {
                    instance.tryEmitNext(it)
                }
            // Sleep for maxAge / TTL
            Thread.sleep(maxAge.toMillis())
            instance.tryEmitComplete()
            StepVerifier
                .create(instance.asFlux())
                .expectComplete()
                .verify(Duration.ofSeconds(1))
    
    
        }
    
        /**
         * This test passes ( as expected ) but only because next was called before the completion of the publisher.
         */
        @Test
        fun `it should receive no event if sent before maxAge gap`() {
            val maxAge = Duration.ofSeconds(1)
            val instance = Sinks.many().replay().limit<String>(maxAge)
            IntStream
                .range(0, 100)
                .mapToObj { "$it" }
                .forEach {
                    instance.tryEmitNext(it)
                }
            Thread.sleep(maxAge.toMillis())
    
            // This shouldn't be required.. but if i emit this value, previous values (expired ) are correctly removed
            instance.tryEmitNext("lastOne")
            instance.tryEmitComplete()
            StepVerifier
                .create(instance.asFlux())
                .expectNext("lastOne")
                .expectComplete()
                .verify(Duration.ofSeconds(1))
        }
    }
    
    

    A complete and running test case can be found at this repository The test class is HERE

    Your Environment

    The project built using start.string.io, using Gradle - Kotlin, spring boot 3.0.1. The problem also happening using Java - Maven, spring boot 2.7.3

    • Reactor version(s) used: reactor-core 3.5.1 or reactor-core 3.4.22

    • JVM version (java -version): 17

    • OS and version (eg uname -a): Darwin 21.6.0 Darwin Kernel Version 21.6.0

    Thanks.

    type/bug 
    opened by GoncaloPT 0
  • Mono#retryWhen and Flux#retryWhen cancel the source on error

    Mono#retryWhen and Flux#retryWhen cancel the source on error

    Mono#retryWhen and Flux#retryWhen cancel the upstream when an error is propagated from the upstream. Consider the following example:

    Mono.error(RuntimeException::new)
        .doOnCancel(() -> {
            throw new IllegalStateException("Why cancelling?");
        })
        .retryWhen(Retry.fixedDelay(0L, Duration.ZERO)) // the parameters to Retry#fixedDelay are irrelevant
        .block();
    

    If executed you'll find the IllegalStateException in the logs (being dropped). This behavior is unexpected and not observed in simpler alternatives like Mono#retry.

    This has a bigger impact in the following use case using jOOQ which behaves similarly except that it hangs rather than propagating the error downstream (making it much worse):

    Mono.from(dslContext.transactionPublisher(config -> Mono.error(RuntimeException::new)))
        .retryWhen(Retry.fixedDelay(0L, Duration.ZERO)) // the parameters to Retry#fixedDelay are irrelevant
        .block();
    

    In this case, since jOOQ doesn't have an idempotent close of the connection and tries to close it on error or cancel (and it is not expected that both occur) there's an error which is again dropped, but the whole execution hangs (none of the errors is propagated at all).

    Expected Behavior

    The source should not be cancelled.

    Actual Behavior

    The source is cancelled.

    Steps to Reproduce

    Here are a few tests depending only on JUnit5 to quickly check the problem (both when cancellation should and should not occur). There's also a TODO to fill in and test a possible workaround. Currenty for retryWhen:

    • the cancellation occurs incorrectly in the first test
    • the cancellation occurs correctly in the second test
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.MethodSource;
    import reactor.core.Exceptions;
    import reactor.core.publisher.Mono;
    import reactor.test.StepVerifier;
    import reactor.util.retry.Retry;
    
    import java.time.Duration;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicBoolean;
    import java.util.function.Function;
    
    import static org.junit.jupiter.api.Assertions.*;
    
    class RetryWhenSourceCancellationTest {
    
        @ParameterizedTest
        @MethodSource("retryWhenImplementations")
        void assertRetryWhenDoesNotCancelTheSourceOnUpstreamError(Function<Mono<?>, Mono<?>> transformer) {
            AtomicBoolean sourceCancelled = new AtomicBoolean(false);
    
            StepVerifier.create(Mono.error(() -> new RuntimeException("failed on purpose"))
                            .doOnCancel(() -> sourceCancelled.set(true))
                            .as(transformer))
                    .expectErrorSatisfies(e -> {
                        assertTrue(Exceptions.isRetryExhausted(e));
                        assertEquals("failed on purpose", e.getCause().getMessage());
                    })
                    .verify();
    
            assertFalse(sourceCancelled.get());
        }
    
        @ParameterizedTest
        @MethodSource("retryWhenImplementations")
        void assertRetryWhenDoesCancelTheSourceOnDownstreamCancellation(Function<Mono<?>, Mono<?>> transformer) {
            AtomicBoolean sourceCancelled = new AtomicBoolean(false);
    
            StepVerifier.create(Mono.delay(Duration.ofSeconds(10))
                            .doOnCancel(() -> sourceCancelled.set(true))
                            .as(transformer))
                    .thenAwait()
                    .thenCancel()
                    .verify();
    
            assertTrue(sourceCancelled.get());
        }
    
        // the parameters to Retry#fixedDelay are irrelevant
        private static List<Function<Mono<?>, Mono<?>>> retryWhenImplementations() {
            return List.of(
    
                    mono -> mono.retryWhen(Retry.fixedDelay(0L, Duration.ZERO)),
                    // the workaround
                    mono -> {
                        AtomicBoolean cancelledFromDownstream = new AtomicBoolean(false);
    
                        // TODO:
                        //  How to allow being cancelled conditionally (only if cancelledFromDownstream)
                        //  A general solution is necessary that is appropriate for Flux as well.
                        return Mono.defer(mono::cache) // Mono#cache to prevent cancellation, Mono#defer to prevent caching
                                .retryWhen(Retry.fixedDelay(0L, Duration.ZERO))
                                .doOnCancel(() -> cancelledFromDownstream.set(true));
                    });
        }
    }
    

    Possible Solution

    None. I would appreciate it very much if someone could provide insights on how to implement the incomplete workaround in the provided tests above.

    Your Environment

    • Reactor version(s) used: latest BOM versions 2020.0.26 and 2022.0.1 using respectively 3.4.26 and 3.5.1.
    • JVM version:
      openjdk version "18.0.2.1" 2022-08-18
      OpenJDK Runtime Environment (build 18.0.2.1+1-1)
      OpenJDK 64-Bit Server VM (build 18.0.2.1+1-1, mixed mode, sharing)
      
    type/bug 
    opened by GeorgiPetkov 0
  • Review Scannable RUN_STYLE returned values

    Review Scannable RUN_STYLE returned values

    Some operators report incorrect RUN_STYLE from the Scannable::scanUnsafe(Attr key) implementations.

    These incorrect responses can (and most probably do) cause errors in usages that scan the reactive pipeline to infer asynchronous behaviour.

    The list can be completed during the actual review and fixed:

    • [ ] reactor.core.publisher.FluxOnBackpressureBuffer.BackpressureBufferSubscriber has an async boundary - a queue which can be drained from different thread than the publishing, therefore it should report ASYNC instead of SYNC.
    • [ ] reactor.core.publisher.FluxBufferBoundary and it's Main - the signals from "other" are an async boundary, so this operator should report ASYNC instead of SYNC.
    • [ ] ...
    type/bug 
    opened by chemicL 4
Releases(v3.5.1)
  • v3.5.1(Dec 13, 2022)

    Reactor-Core 3.5.1 is part of 2022.0.1 Release Train.

    What's Changed

    :warning: Update considerations and deprecations

    • Fix regression: Sinks.one()#tryEmitValue(null) by @simonbasle in #3287
    • Ensure context restored in RetrySpec by @OlegDokuka in #3316

    :sparkles: New features and improvements

    • Ensure given iterable is interacted once per subscriber by @OlegDokuka in #3297

    :lady_beetle: Bug fixes

    • Fix #3307 case by @OlegDokuka in #3312

    :book: Documentation, Tests and Build

    • Revert Add jcenter() to the repositories list by @violetagg in #3279
    • Perf baseline 3.5.0, adapt Shakespeare bench to 2022.0.0 release by @simonbasle in #3278
    • Fix typo in in documentation by @SpikeBlues in #3300
    • Remove NotNull annotation from jetbrains by @OlegDokuka in #3303

    New Contributors

    • @SpikeBlues made their first contribution in #3300

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.5.0...v3.5.1

    Source code(tar.gz)
    Source code(zip)
  • v3.4.26(Dec 13, 2022)

    Reactor-Core 3.4.26 is part of 2020.0.26 Release Train (Europium SR26).

    What's Changed

    :warning: Update considerations and deprecations

    • Fix regression: Sinks.one()#tryEmitValue(null) by @simonbasle in #3287
    • Ensure context restored in RetrySpec by @OlegDokuka in #3316

    :sparkles: New features and improvements

    • Ensure given iterable is interacted once per subscriber by @OlegDokuka in #3297

    :lady_beetle: Bug fixes

    • Fix #3307 case by @OlegDokuka in #3312

    :book: Documentation, Tests and Build

    • Fix typo in in documentation by @SpikeBlues in #3300
    • Remove NotNull annotation from jetbrains by @OlegDokuka in #3303

    New Contributors

    • @SpikeBlues made their first contribution in #3300

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.25...v3.4.26

    Source code(tar.gz)
    Source code(zip)
  • v3.4.25(Nov 15, 2022)

    Reactor-Core 3.4.25 is part of 2020.0.25 Release Train (Europium SR25).

    What's Changed

    :warning: Update considerations and deprecations

    :warning: :hourglass: Deprecations

    • Deprecate scheduler start by @chemicL in #3236
      • Scheduler#init() method should be used instead. Restart capability is discouraged and the new method is allowed to throw in case of initializing a disposed instance. Please create a new Scheduler instance when necessary.
      • Implementors of Scheduler should also implement the init() method, which currently delegates to start() in the default implementation.

    :warning: :recycle: Behavior Changes

    • Disable fusion in MonoSubscriber by @UgiR in #3245
      • A number of Mono operators derived from the Operators.MonoSubscriber have stopped negotiating fusion (even though their Publisher still implements Fuseable)
      • The highest impact is likely to be on tests that validate the fusion negotiation (eg. StepVerifier's expectFusion(...))

    :sparkles: New features and improvements

    • Add on discard support for FluxZip/MonoZip by @OlegDokuka in #3209
    • Optimize Scheduler initialization by @chemicL in #3248
    • Disable fusion in MonoSubscriber by @UgiR in #3245
    • Fix breaking change for fromFuture source cancellation by @OlegDokuka in #3252
    • Add Flux.mergePriority, does not wait for all sources to emit by @osi in #3267
    • Only initialize logging once per test session by @marcphilipp in #3263
    • Limit the number of Scheduler#disposeGracefully threads by @simonbasle in #3259

    :lady_beetle: Bug fixes

    • Fix incorrect value/error set during tryEmitXXX call by @OlegDokuka in #3260
    • Fix subscription loss in FluxTakeUntilOther by @simonbasle in #3270 (fixing a 3.4.24 regression)

    :book: Documentation, Tests and Build

    • Fix flaky FluxPublishOnTest by @simonbasle in #3241
    • SingleScheduler.isDisposed() only true on disposed instance by @chemicL in #3242
    • Use new GHA API for setting output, latest core actions by @simonbasle in #3237
    • Clean up references to fusion in MonoSubscriber comments by @UgiR in #3261
    • Improve Mono#fromFuture/fromCompletionStage javadocs by @simonbasle in #3272

    :up: Dependency Upgrades

    • Upgrade several plugins and test dependencies by @simonbasle in #3254

    New Contributors

    • @marcphilipp made their first contribution in #3263

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.24...v3.4.25

    Source code(tar.gz)
    Source code(zip)
  • v3.5.0(Nov 10, 2022)

    Reactor-Core 3.5.0 is part of 2022.0.0 Release Train.

    This is the first GA release of 2022.0.0 🎉

    This note focuses on 3.5.0 proper, curating changes from across all milestones and also includes changes already released as part of 3.4.x line up to 3.4.25.

    While there are plenty of improvements and bug fixes, it's worth to highlight the bigger themes first:

    • The Mono stack is now more lazy and complies to the Reactive Streams specification by only evaluating the source Publisher after receiving appropriate demand. Previously this usually happened during subscription time.
    • We reworked the metrics utilities. Please consult the reference documentation for more details.
    • A new context-propagation library has become an important part of the Reactor and Micrometer backbone to allow bridging between reactive and ThreadLocal contextual metadata. Reactor supports this bridging as soon as context-propagation library is present at runtime. Read more in the reference documentation.

    Please pay special attention to the following update considerations. More detailed listing of features, bug fixes, and improvements follow.

    :warning: Update considerations and deprecations

    :warning: :wastebasket: Removals

    • Remove Kotlin extensions by @simonbasle in #2949
    • Remove deprecated Mono.doOn/AfterSuccessOrError by @simonbasle in #2954
      • The doOn* recommended alternatives include doOnNext(Consumer), doOnError(Consumer), doOnTerminate(Runnable), and doOnSuccess(Consumer),
      • The doAfter* recommended alternatives are doAfterTerminate(Runnable) and doFinally(Consumer).
    • Remove deprecated context-related operators by @simonbasle in #2953
      • deferWithContext(Function) -> use deferContextual(Function) instead,
      • subscriberContext(Context) and subscriberContext(Function) -> use contextWrite(ContextView) and contextWrite(Function) instead,
      • Signal::getContext() -> use Signal::getContextView() instead,
      • Context::putAll(Context) -> use Context::putAll(ContextView) instead.
    • Remove deprecated ElasticScheduler by @simonbasle in #2955
      • Use BoundedElasticScheduler (Schedulers.boundedElastic()) instead.

    :warning: :hourglass: Deprecations

    • Introduce new module reactor-core-micrometer by @simonbasle in #3015
      • We introduced a new module, reactor-core-micrometer, and added operators and features supporting the new Observation API of Micrometer 1.10.0, read more about it the release notes.
      • The class reactor.util.Metrics, Flux::metrics() and Mono::metrics() operators have been deprecated.
    • Deprecate [Flux|Mono|Synchronous]Sink currentContext by @simonbasle in #2974, #3021
      • contextView() should be used instead.
    • Deprecate scheduler start by @chemicL in #3236
      • Scheduler#init() method should be used instead. Restart capability is discouraged and the new method is allowed to throw in case of initializing a disposed instance. Please create a new Scheduler instance when necessary.
      • Implementors of Scheduler should also implement the init() method, which currently delegates to start() in the default implementation.

    :warning: :recycle: Behavior Changes

    • Make some Mono sources and aggregators lazier by @OlegDokuka in #3081
    • Change behavior of switchOnNext/switchMap default 0 prefetch by @simonbasle in #2956
    • Have concatMap default to 0 prefetch behavior by @simonbasle in #2967
    • take(n) now behaves as take(n,true)/limitRequest by @simonbasle in #2969
    • SourceException wrapper for main stream errors delivered to windows by @chemicL in #3167
    • Scheduler.isDisposed() only true for disposed instances by @chemicL in #3243
    • adds cancellation of the source future support by @OlegDokuka in #3146
    • Scannable.tags() rework, add tagsDeduplicated() by @simonbasle in #3037
    • Disable fusion in MonoSubscriber by @UgiR in #3245
      • A number of Mono operators derived from the Operators.MonoSubscriber have stopped negotiating fusion (even though their Publisher still implements Fuseable)
      • The highest impact is likely to be on tests that validate the fusion negotiation (eg. StepVerifier's expectFusion(...))

    :sparkles: New features and improvements

    Context propagation and bridging to ThreadLocals

    • Add context-propagation-api dependency + ReactorContextAccessor by @simonbasle in #3098, #3107, #3256
    • Add ContextPropagation runtime util + captureContext operator by @simonbasle in #3145
    • handle/tap implicit ThreadLocal restoration if ContextCapture by @simonbasle in #3180
    • Add forEach method to ContextView and subclasses by @chemicL in #3092
    • Introducing default impl for Context::forEach by @chemicL in #3101
    • Introducing Context::putAllMap by @chemicL in #3102

    Observability and logging

    • Introduce new module reactor-core-micrometer by @simonbasle in #3015
    • Add StateLogger for structured logging of state machines by @OlegDokuka in #3077
    • Polish Observation names and tag keys by @simonbasle in #3110
    • Micrometer#observation(): avoids scopes, set parentObservation by @simonbasle in #3119
    • Add logging in Exceptions.throwIf[Jvm]Fatal, add isFatal methods by @simonbasle in #3122
    • Only initialize logging once per test session by @marcphilipp in #3263
    • Add TimedScheduler to reactor-core-micrometer module by @simonbasle in #3109

    Operators and relevant machinery

    • Add 'tap', a generic side-effect/observability operator by @simonbasle in #3013
    • Add Flux.mergePriority, does not wait for all sources to emit by @osi in #3267
    • Introduce an alternative to Processor-with-upstream case by @simonbasle in #3042, #3065
    • Implement variant of windowTimeout with fairBackpressure by @OlegDokuka in #3054
    • Add windowTimeout sendNext early guard against maxSize overflow by @OlegDokuka in #3073
    • Replay terminal signals to late subscribers in Flux.replay(int) and Flux.cache(int) by @chemicL in #3200
    • Add disposeGracefully method to Scheduler by @chemicL in #3089
    • Optimize Scheduler initialization by @chemicL in #3248
    • Limit the number of Scheduler#disposeGracefully threads by @simonbasle in #3259
    • Add key hook parts to Schedulers.onHandleError by @simonbasle in #3039
    • Use byte padding to avoid fields re-ordering on JDK 15 and above by @lantalex in #3168
    • Make use of CompletionStage#handle instead of whenComplete by @He-Pin in #3221
    • adds on discard support for FluxZip/MonoZip by @OlegDokuka in #3209
    • Include classname of null-returning map function in NPE msg by @ismailalammar in #2984

    reactor-test module

    • [reactor-test] Add StepVerifier option to use ConditionalSubscriber by @simonbasle in #3035
    • Implement disposing of tasks scheduled on VirtualTimeScheduler by @mdindoffer in #3097
    • Ensure StepVerifier evaluates signal that exits thenConsumeWhile by @simonbasle in #3203
    • Improve LoggerUtils support and add TestLoggerExtension by @simonbasle in #3123

    :lady_beetle: Bug fixes

    • [agent] Avoid instrumenting methods with unwrappable returnType by @simonbasle in #2973
    • Avoid FluxReplay buffer retaining/leaking with tiny TTL by @simonbasle in #2998
    • Fix subscribers being retained by SinkOneMulticast by @simonbasle in #3002
    • Fix a Many sink / EmitterProcessor subscriber disposal leak by @simonbasle in #3029
    • Fix doOnEach ASYNC fusion triggering onNext signal twice by @simonbasle in #3045
    • Fix cancel too synchronized in MonoCollect[List] by @simonbasle in #3053
    • Async fusion bug: extra fixes and changes by @simonbasle in #3046
    • ensures onLastAssembly does not break fusion chain by @OlegDokuka in #3156
    • Improve Loggers.useConsoleLoggers() thread safety by @alexismanin in #3174
    • Dispose picked worker when BoundedElasticScheduler rejects task by @Fearsin in #3183
    • Allow blocking calls in WorkerTask#dispose by @nathankooij in #3213
    • fixes incorrect value/error set during tryEmitXXX call by @OlegDokuka in #3260
    • cleans context for concat map for retry companion publisher by @OlegDokuka in #3262
    • Fix meters documentation generation following renames by @simonbasle in #3217
    • Fix subscription loss in FluxTakeUntilOther by @simonbasle in #3270
    • Fix cancel behavior of FluxTakeUntilOther by @haraldpusch in #3219
    • fixes breaking change for fromFuture source cancellation by @OlegDokuka in #3252

    :book: Documentation, Tests and Build

    • Fix windowTimeout stress test to use sinks by @OlegDokuka in #3074
    • [test] Fix flaky BoundedElasticTest with better controlled tasks by @simonbasle in #2968
    • [doc] Polish Schedulers javadoc for common/cached instances by @dedeibel in #2995
    • Increase landscape width of refguide content for readability by @tmyksj in #3009
    • [test] Improve flaky BoundedElasticScheduler toString test by @simonbasle in #3010
    • Polish README by @simonbasle in #3007
    • Refguide on mobile to use screen space optimally by @tmyksj in #3019
    • Correct typo in metrics.adoc by @jarredhiggs in #3047
    • Introducing JCStress tests for concurrent queues by @chemicL in #3069
    • Fix doc typo: missing word in reactiveProgramming.adoc by @eduardNeagoe in #3075
    • Make context-propagation-api dependency optional + documentation by @simonbasle in #3100
    • Clarify ContextN.putAll(Map) intended internal use in javadoc by @chemicL in #3103
    • Rework guide on Retry with Transient Errors by @simonbasle in #3093
    • Adapt to the changes in the context propagation API by @violetagg in #3113
    • Clarify how to use processExistingClasses in debugging.adoc by @kicmeri in #3130
    • Refguide: Remove mention of discouraged subscribe variant by @simonbasle in #3141
    • Removing outdated references to Exceptions#bubble(Throwable) by @chemicL in #3160
    • Document reactor-Core-Micrometer obs/meters/tags via enums by @simonbasle in #3175
    • Improve JapiCmp: avoid misses, improve reporting and exclusions by @simonbasle in #3198
    • Adapt to Micrometer SNAPSHOTs before RC1 by @simonbasle in #3215
    • Micrometer Observation test: ensure assert fails the test by @simonbasle in #3220
    • Polish Micrometer Docs generation by @simonbasle in #3225
    • Document not to reuse/cache EmitFailureHandle#busyLooping by @He-Pin in #3224
    • Rework the refguide section on metrics to focus on new module by @simonbasle in #3205
    • Fix flaky FluxPublishOnTest by @simonbasle in #3241
    • Use new gha API for setting output, latest core actions by @simonbasle in #3237
    • Minor polish on documentation by @glefloch in #3247
    • various minor cleanups by @dfa1 in #3234
    • Clean up references to fusion in MonoSubscriber comments by @UgiR in #3261
    • Document usage of the EmitFailureHandler.busyLooping in refguide by @ivyazmitinov in #3271
    • Improve Mono fromFuture/fromCompletionStage javadocs by @simonbasle in #3272
    • Fix a couple reactor-core-micrometer module compilation errors by @simonbasle in #3132
    • Disable flaky BoundedElasticScheduler test by @simonbasle in #3142

    :up: Dependency Upgrades

    • April round of upgrades superseding Renovate PRs by @simonbasle in #2992
    • Update gradle/gradle-build-action to v2.1.5 by @simonbasle in #2996
    • Update ByteBuddy to v1.12.9 by @simonbasle in #3008
    • Switch Micrometer snapshots to 1.10.0-SNAPSHOT by @simonbasle in #3016
    • Upgrade to Micrometer 1.10.0-M1 for 3.5.0-M2 by @simonbasle in #3025
    • Upgrade Checkout action, Mockito, Spotless, Artifactory by @simonbasle in #3030
    • Upgrade download, gradle enterprise, spotless, byteBuddy by @simonbasle in #3034
    • June dependency upgrades by @simonbasle in #3066
    • Update Reactive-Streams to v1.0.4 by @renovate-bot in #3055
    • Update plugin bnd to v6.3.1 by @simonbasle in #3070
    • July dependency upgrades by @simonbasle in #3115
    • Update Micrometer dependency to version 1.10.0-M3 by @violetagg in #3116
    • Upgrade Gradle to 7.5, workaround nohttp, update gradle action by @simonbasle in #3127
    • Update Micrometer dependency to latest milestone releases by @violetagg in #3143
    • Upgrade Gradle 7.5.1, Artifactory plugin 4.29.0 by @violetagg in #3144
    • Update dependencies junit, mockito, spotless, download... by @simonbasle in #3169
    • Update byte-buddy to v1.12.14 by @renovate-bot in #3134
    • switches to all the Micrometer SNAPSHOTs by @simonbasle in #3179
    • updates Micrometer dependency to latest milestone releases by @violetagg in #3190
    • Update Micrometer dependency to 1.10.0-M6 by @chemicL in #3194
    • Update dependencies junit, mockito, bytebuddy, jcstress, spotless... by @chemicL in #3218
    • Update Micrometer dependency to RC1 by @violetagg in #3228
    • Upgrade several plugins and test dependencies by @simonbasle in #3254
    • Upgrade Micrometer/Context-Propagation dependencies to 1.10.0 GA by @simonbasle in #3274

    New Contributors

    • @dedeibel made their first contribution in #2995
    • @tmyksj made their first contribution in #3009
    • @ismailalammar made their first contribution in #2984
    • @jarredhiggs made their first contribution in #3047
    • @chemicL made their first contribution in #3069
    • @eduardNeagoe made their first contribution in #3075
    • @mdindoffer made their first contribution in #3097
    • @kicmeri made their first contribution in #3130
    • @lantalex made their first contribution in #3168
    • @alexismanin made their first contribution in #3174
    • @Fearsin made their first contribution in #3183
    • @nathankooij made their first contribution in #3213
    • @He-Pin made their first contribution in #3224
    • @haraldpusch made their first contribution in #3219
    • @glefloch made their first contribution in #3247
    • @dfa1 made their first contribution in #3234
    • @marcphilipp made their first contribution in #3263

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.16...v3.5.0

    Source code(tar.gz)
    Source code(zip)
  • v3.5.0-RC1(Oct 11, 2022)

    What's Changed

    :warning: Update considerations and deprecations

    • Fix meters documentation generation following renames by @simonbasle in #3217

    :sparkles: New features and improvements

    • Replay terminal signals to late subscribers in Flux.replay(int) and Flux.cache(int) by @chemicL in #3200
    • Ensure StepVerifier evaluates signal that exits thenConsumeWhile by @simonbasle in #3203
    • Add ContextPropagation runtime util + captureContext operator by @simonbasle in #3145
    • Fix cancel behavior of FluxTakeUntilOther by @haraldpusch in #3219
    • Make use of CompletionStage#handle instead of whenComplete by @He-Pin in #3221

    :lady_beetle: Bug fixes

    • Dispose picked worker when BoundedElasticScheduler rejects task by @Fearsin in #3183
    • Allow blocking calls in WorkerTask#dispose by @nathankooij in #3213

    :book: Documentation, Tests and Build

    • Document reactor-Core-Micrometer obs/meters/tags via enums by @simonbasle in #3175
    • Improve JapiCmp: avoid misses, improve reporting and exclusions by @simonbasle in #3198
    • Adapt to Micrometer SNAPSHOTs before RC1 by @simonbasle in #3215
    • Micrometer Observation test: ensure assert fails the test by @simonbasle in #3220
    • Polish Micrometer Docs generation by @simonbasle in #3225
    • Document not to reuse/cache EmitFailureHandle#busyLooping by @He-Pin in #3224
    • Rework the refguide section on metrics to focus on new module by @simonbasle in #3205

    :up: Dependency Upgrades

    • Update dependencies junit, mockito, bytebuddy, jcstress, spotless... by @chemicL in #3218
    • Update Micrometer dependency to RC1 by @violetagg in #3228

    New Contributors

    • @Fearsin made their first contribution in #3183
    • @nathankooij made their first contribution in #3213
    • @He-Pin made their first contribution in #3224
    • @haraldpusch made their first contribution in #3219

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.5.0-M6...v3.5.0-RC1

    Source code(tar.gz)
    Source code(zip)
  • v3.4.24(Oct 11, 2022)

    What's Changed

    :sparkles: New features and improvements

    • Replay terminal signals to late subscribers in Flux.replay(int) and Flux.cache(int) by @chemicL in #3200
    • Ensure StepVerifier evaluates signal that exits thenConsumeWhile by @simonbasle in #3203
    • Fix cancel behavior of FluxTakeUntilOther by @haraldpusch in #3219
    • Make use of CompletionStage#handle instead of whenComplete by @He-Pin in #3221

    :lady_beetle: Bug fixes

    • Dispose picked worker when BoundedElasticScheduler rejects task by @Fearsin in #3183
    • Allow blocking calls in WorkerTask#dispose by @nathankooij in #3213

    :book: Documentation, Tests and Build

    • Improve JapiCmp: avoid misses, improve reporting and exclusions by @simonbasle in #3198
    • Document not to reuse/cache EmitFailureHandle#busyLooping by @He-Pin in #3224

    :up: Dependency Upgrades

    • Update dependencies junit, mockito, bytebuddy, jcstress, spotless... by @chemicL in #3218

    New Contributors

    • @Fearsin made their first contribution in #3183
    • @nathankooij made their first contribution in #3213
    • @He-Pin made their first contribution in #3224
    • @haraldpusch made their first contribution in #3219

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.23...v3.4.24

    Source code(tar.gz)
    Source code(zip)
  • v3.5.0-M6(Sep 13, 2022)

    What's Changed

    :warning: Update considerations and deprecations

    • SourceException wrapper for main stream errors delivered to windows by @chemicL in https://github.com/reactor/reactor-core/pull/3167

    :sparkles: New features and improvements

    • adds cancellation of the source future support by @OlegDokuka in https://github.com/reactor/reactor-core/pull/3146
    • Add disposeGracefully method to Scheduler by @chemicL in https://github.com/reactor/reactor-core/pull/3089
    • Add onErrorComplete operator and rework onErrorReturn by @simonbasle in https://github.com/reactor/reactor-core/pull/3159
    • Use byte padding to avoid fields re-ordering on JDK 15 and above by @lantalex in https://github.com/reactor/reactor-core/pull/3168

    :lady_beetle: Bug fixes

    • ensures onLastAssembly does not break fusion chain by @OlegDokuka in https://github.com/reactor/reactor-core/pull/3156
    • Improve Loggers.useConsoleLoggers() thread safety by @alexismanin in https://github.com/reactor/reactor-core/pull/3174

    :book: Documentation, Tests and Build

    • Removing outdated references to Exceptions#bubble(Throwable) by @chemicL in https://github.com/reactor/reactor-core/pull/3160

    :up: Dependency Upgrades

    • Update dependencies junit, mockito, spotless, download... by @simonbasle in https://github.com/reactor/reactor-core/pull/3169
    • Update byte-buddy to v1.12.14 by @renovate-bot in https://github.com/reactor/reactor-core/pull/3134
    • switches to all the Micrometer SNAPSHOTs by @simonbasle in https://github.com/reactor/reactor-core/pull/3179
    • updates Micrometer dependency to latest milestone releases by @violetagg in https://github.com/reactor/reactor-core/pull/3190

    New Contributors

    • @lantalex made their first contribution in https://github.com/reactor/reactor-core/pull/3168
    • @alexismanin made their first contribution in https://github.com/reactor/reactor-core/pull/3174

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.5.0-M5...v3.5.0-M6

    Source code(tar.gz)
    Source code(zip)
  • v3.4.23(Sep 13, 2022)

    What's Changed

    :sparkles: New features and improvements

    • adds cancellation of the source future support by @OlegDokuka in https://github.com/reactor/reactor-core/pull/3146
    • Add disposeGracefully method to Scheduler by @chemicL in https://github.com/reactor/reactor-core/pull/3089
    • Add onErrorComplete operator and rework onErrorReturn by @simonbasle in https://github.com/reactor/reactor-core/pull/3159
    • Use byte padding to avoid fields re-ordering on JDK 15 and above by @lantalex in https://github.com/reactor/reactor-core/pull/3168

    :lady_beetle: Bug fixes

    • ensures onLastAssembly does not break fusion chain by @OlegDokuka in https://github.com/reactor/reactor-core/pull/3156
    • Improve Loggers.useConsoleLoggers() thread safety by @alexismanin in https://github.com/reactor/reactor-core/pull/3174

    :up: Dependency Upgrades

    • Update dependencies junit, mockito, spotless, download... by @simonbasle in https://github.com/reactor/reactor-core/pull/3169
    • Update byte-buddy to v1.12.1 in https://github.com/reactor/reactor-core/pull/3134

    New Contributors

    • @lantalex made their first contribution in https://github.com/reactor/reactor-core/pull/3168
    • @alexismanin made their first contribution in https://github.com/reactor/reactor-core/pull/3174

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.22...v3.4.23

    Source code(tar.gz)
    Source code(zip)
  • v3.5.0-M5(Aug 9, 2022)

    Reactor-Core 3.5.0-M5 is part of 2022.0.0-M5 Release Train (F Milestone 5).

    This version brings in a few changes, bugfixes and enhancements from the 3.4.x line, most notably from 3.4.22.

    These are also listed below.

    What's Changed

    :warning: Update considerations and deprecations

    • Make some Mono sources and aggregators lazier by @OlegDokuka in #3081
    • Add TimedScheduler to reactor-core-micrometer module by @simonbasle in #3109
    • Remove Micrometer#useRegistry, remove notion of Clock by @simonbasle in #3128

    :sparkles: New features and improvements

    • Micrometer#observation(): avoids scopes, set parentObservation by @simonbasle in #3119
    • Adapt to ContextAccessor change: new readValue method by @simonbasle in #3124
    • Fix a couple reactor-core-micrometer module compilation errors by @simonbasle in #3132
    • Update Micrometer dependency to latest milestone releases by @violetagg in #3143
    • from 3.4.x:
      • Add logging in Exceptions.throwIf[Jvm]Fatal, add isFatal methods by @simonbasle in #3122
      • Improve LoggerUtils support and add TestLoggerExtension by @simonbasle in #3123

    :book: Documentation, Tests and Build

    • from 3.4.x:
      • Clarify how to use processExistingClasses in debugging.adoc by @kicmeri in #3130
      • Refguide: Remove mention of discouraged subscribe variant by @simonbasle in #3141
      • Disable flaky BoundedElasticScheduler test by @simonbasle in #3142

    :up: Dependency Upgrades

    • from 3.4.x:
      • Upgrade Gradle to 7.5, workaround nohttp, update gradle action by @simonbasle in #3127
      • Upgrade Gradle 7.5.1, Artifactory plugin 4.29.0 by @violetagg in #3144

    New Contributors

    • @kicmeri made their first contribution in https://github.com/reactor/reactor-core/pull/3130

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.5.0-M4...v3.5.0-M5

    Source code(tar.gz)
    Source code(zip)
  • v3.4.22(Aug 9, 2022)

    Reactor-Core 3.4.22 is part of 2020.0.22 Release Train (Europium SR22).

    What's Changed

    :sparkles: New features and improvements

    • Add logging in Exceptions.throwIf[Jvm]Fatal, add isFatal methods by @simonbasle in #3122
    • Improve LoggerUtils support and add TestLoggerExtension by @simonbasle in #3123

    :book: Documentation, Tests and Build

    • Clarify how to use processExistingClasses in debugging.adoc by @kicmeri in #3130
    • Refguide: Remove mention of discouraged subscribe variant by @simonbasle in #3141
    • Disable flaky BoundedElasticScheduler test by @simonbasle in #3142

    :up: Dependency Upgrades

    • Upgrade Gradle to 7.5, workaround nohttp, update gradle action by @simonbasle in #3127
    • Upgrade Gradle 7.5.1, Artifactory plugin 4.29.0 by @violetagg in #3144

    New Contributors

    • @kicmeri made their first contribution in #3130

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.21...v3.4.22

    Source code(tar.gz)
    Source code(zip)
  • v3.5.0-M4(Jul 12, 2022)

    Reactor-Core 3.5.0-M4 is part of 2022.0.0-M4 Release Train (F Milestone 4).

    This version brings in a few changes, bugfixes and enhancements from the 3.4.x line, most notably from 3.4.21.

    These are also listed below.

    What's Changed

    :warning: Update considerations and deprecations

    • Micrometer module: add observation(), deprecate global registry by @simonbasle in #3104
    • Reintroduction of Processors as deprecated by @simonbasle in #3112

    :sparkles: New features and improvements

    • Add context-propagation-api dependency + ReactorContextAccessor by @simonbasle in #3098
    • Improve ReactorContextAccessor, add tests by @simonbasle in #3107
    • Polish Observation names and tag keys by @simonbasle in #3110
    • From 3.4.x:
      • Implement disposing of tasks scheduled on VirtualTimeScheduler by @mdindoffer in #3097
      • Add forEach method to ContextView and subclasses by @chemicL in #3092
      • Introducing default impl for Context::forEach by @chemicL in #3101
      • Introducing Context::putAllMap by @chemicL in #3102

    :book: Documentation, Tests and Build

    • Make context-propagation-api dependency optional + documentation by @simonbasle in #3100
    • Adapt to the changes in the context propagation API by @violetagg in #3113
    • From 3.4.x:
      • Clarify ContextN.putAll(Map) intended internal use in javadoc by @chemicL in #3103
      • Rework guide on Retry with Transient Errors by @simonbasle in #3093

    :up: Dependency Upgrades

    • July dependency upgrades by @simonbasle in #3115
    • Update Micrometer dependency to version 1.10.0-M3 by @violetagg in #3116

    New Contributors

    • @mdindoffer made their first contribution in #3097

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.5.0-M3...v3.5.0-M4

    Source code(tar.gz)
    Source code(zip)
  • v3.4.21(Jul 12, 2022)

    Reactor-Core 3.4.21 is part of 2020.0.21 Release Train (Europium SR21).

    What's Changed

    :sparkles: New features and improvements

    • Add windowTimeout sendNext early guard against maxSize overflow by @OlegDokuka in #3073
    • Add StateLogger for structured logging of state machines by @OlegDokuka in #3077
    • Implement disposing of tasks scheduled on VirtualTimeScheduler by @mdindoffer in #3097
    • Add forEach method to ContextView and subclasses by @chemicL in #3092
    • Introducing default impl for Context::forEach by @chemicL in #3101
    • Introducing Context::putAllMap by @chemicL in #3102

    :book: Documentation, Tests and Build

    • Clarify ContextN.putAll(Map) intended internal use in javadoc by @chemicL in #3103
    • Rework guide on Retry with Transient Errors by @simonbasle in #3093

    :up: Dependency Upgrades

    • July dependency upgrades by @simonbasle in #3115

    New Contributors

    • @mdindoffer made their first contribution in #3097

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.19...v3.4.21

    Source code(tar.gz)
    Source code(zip)
  • v3.4.20(Jul 12, 2022)

  • v3.5.0-M3(Jun 21, 2022)

    Reactor-Core 3.5.0-M3 is part of 2022.0.0-M3 Release Train (F Milestone 3).

    This version brings in a few changes, bugfixes and enhancements from the 3.4.x line, most notably from 3.4.18 and 3.4.19. These are also listed below.

    What's Changed

    :warning: Update considerations and deprecations

    • Scannable.tags() rework: change in how the tags are enumerated and added a tagsDeduplicated() method which allows to enumerate without duplicates (#3037)
    • Finalizing deprecation removals from public API with FluxProcessor and MonoProcessor and their implementations (#3051)
      • with the recent addition of a Sinks equivalent to EmitterProcessor, the most common remaining use case where Processor was needed is now covered (since #3042)

    :sparkles: New features and improvements

    • Fix windowTimeout stress test to use sinks by @OlegDokuka in #3074
    • from 3.4.x:
      • Add key hook parts to Schedulers.onHandleError by @simonbasle in #3039
      • [reactor-test] Add StepVerifier option to use ConditionalSubscriber by @simonbasle in #3035
      • Introduce an alternative to Processor-with-upstream case by @simonbasle in #3042
      • Rework Processor-with-upstream case to be backward compatible by @simonbasle in #3065
      • Implement variant of windowTimeout with fairBackpressure by @OlegDokuka in #3054
      • Add windowTimeout sendNext early guard against maxSize overflow by @OlegDokuka in #3073
      • Add StateLogger for structured logging of state machines by @OlegDokuka in #3077
      • Include classname of null-returning map function in NPE msg by @ismailalammar in #2984

    :lady_beetle: Bug fixes

    • from 3.4.x:
      • Fix DoOnEach ASYNC fusion triggering onNext signal twice by @simonbasle in #3045
      • Fix cancel too synchronized in MonoCollect[List] by @simonbasle in #3053
      • Async fusion bug: extra fixes and changes by @simonbasle in #3046

    :book: Documentation, Tests and Build

    • Correct typo in metrics.adoc by @jarredhiggs in #3047
    • Fix doc typo: missing word in reactiveProgramming.adoc by @eduardNeagoe in #3075
    • from 3.4.x:
      • Refguide on mobile to use screen space optimally by @tmyksj in #3019
      • Introducing JCStress tests for concurrent queues by @chemicL in #3069

    :up: Dependency Upgrades

    • from 3.4.x:
      • Upgrade Checkout action, Mockito, Spotless, Artifactory by @simonbasle in #3030
      • Upgrade download, gradle enterprise, spotless, byteBuddy by @simonbasle in #3034
      • June dependency upgrades by @simonbasle in #3066
      • Update Reactive-Streams to v1.0.4 by @renovate-bot in #3055
      • Update plugin bnd to v6.3.1 by @simonbasle in #3070

    New Contributors

    • @jarredhiggs made their first contribution in #3047
    • @eduardNeagoe made their first contribution in #3075
    Source code(tar.gz)
    Source code(zip)
  • v3.4.19(Jun 14, 2022)

    Reactor-Core 3.4.19 is part of 2020.0.20 Release Train (Europium SR20).

    What's Changed

    :sparkles: New features and improvements

    • Add key hook parts to Schedulers.onHandleError by @simonbasle in #3039
    • [reactor-test] Add StepVerifier option to use ConditionalSubscriber by @simonbasle in #3035
    • Introduce an alternative to Processor-with-upstream case by @simonbasle in #3042
    • Rework Processor-with-upstream case to be backward compatible by @simonbasle in #3065
    • Implement variant of windowTimeout with fairBackpressure by @OlegDokuka in #3054
      • This is activated by the fairBackpressure boolean parameter.

    :lady_beetle: Bug fixes

    • Fix DoOnEach ASYNC fusion triggering onNext signal twice by @simonbasle in #3045
    • Fix cancel too synchronized in MonoCollect[List] by @simonbasle in #3053
    • Async fusion bug: extra fixes and changes by @simonbasle in #3046

    :book: Documentation, Tests and Build

    • Introducing JCStress tests for concurrent queues by @chemicL in #3069

    :up: Dependency Upgrades

    • June dependency upgrades by @simonbasle in #3066
    • Update Reactive-Streams to v1.0.4 by @renovate-bot in #3055
    • Update plugin bnd to v6.3.1 by @simonbasle in #3070

    New Contributors

    • @chemicL made their first contribution in #3069
    Source code(tar.gz)
    Source code(zip)
  • v3.4.18(May 10, 2022)

    Reactor-Core 3.4.18 is part of 2020.0.19 Release Train (Europium SR19).

    What's Changed

    :sparkles: New features and improvements

    • Backport: contextView() implem of [Flux|Mono|Synchronous]Sink by @simonbasle in #3026
    • Include classname of null-returning map function in NPE msg by @ismailalammar in #2984

    :lady_beetle: Bug fixes

    • Fix a Many sink / EmitterProcessor subscriber disposal leak by @simonbasle in #3029

    :up: Dependency Upgrades

    • Upgrade Checkout action, Mockito, Spotless, Artifactory by @simonbasle in #3030
    • Upgrade download, gradle enterprise, spotless, byteBuddy by @simonbasle in #3034

    New Contributors

    • @ismailalammar made their first contribution in #2984
    Source code(tar.gz)
    Source code(zip)
  • v3.5.0-M2(Apr 21, 2022)

    Feedback Needed

    As always, milestones are an important step where your feedback is needed.

    • We are particularly interested in feedback for the tap operator (#3013) combined to the new metrics module (#3015).

    • One feature that didn't make it to this release but on which we'd like your input as well is a contextual variant of the task-decoration scheduler hook. See design in #2980 and candidate implementation in #2983.

    What's Changed

    :warning: Update considerations and deprecations

    • Changes in metrics dependencies and approach
      • Reactor-Core now expects and assumes Micrometer 1.10 as the metrics baseline (#3006, #3025)
      • The inlined metrics() operator and other metrics features have been deprecated (#3015)
      • A new more generic tap operator is introduced, among other things it can replace metrics() (#3013)
      • One provider for the tap is the newly introduced reactor-core-micrometer module version 1.0.0-M2 (#3015)

    :sparkles: New features and improvements

    • Add 'tap', a generic side-effect/observability operator by @simonbasle in #3013
    • Add default contextView() implem to [Flux|Mono|Synchronous]Sink by @simonbasle in #3021

    :lady_beetle: Bug fixes

    • Avoid FluxReplay buffer retaining/leaking with tiny TTL by @simonbasle in #2998
    • Fix subscribers being retained by SinkOneMulticast by @simonbasle in #3002
    • Fix a Many sink / EmitterProcessor subscriber disposal leak by @simonbasle in #3029

    :book: Documentation, Tests and Build

    • [doc] Polish Schedulers javadoc for common/cached instances by @dedeibel in #2995
    • Increase landscape width of refguide content for readability by @tmyksj in #3009

    :up: Dependency Upgrades

    • April round of upgrades (#2992, #2996, #3008
    • Upgrade to Micrometer 1.10.0-M1 for 3.5.0-M2 by @simonbasle in #3025

    New Contributors

    • @dedeibel made their first contribution in #2995
    • @tmyksj made their first contribution in #3009
    Source code(tar.gz)
    Source code(zip)
  • v3.4.17(Apr 12, 2022)

    Reactor-Core 3.4.17 is part of 2020.0.18 Release Train (Europium SR18).

    :warning: Update considerations and deprecations

    • Deprecate [Flux|Mono|Synchronous]Sink currentContext by @simonbasle in #2974

    :lady_beetle: Bug fixes

    • [agent] Avoid instrumenting methods with unwrappable returnType by @simonbasle in #2973
    • Avoid FluxReplay buffer retaining/leaking with tiny TTL by @simonbasle in #2998
    • Fix subscribers being retained by SinkOneMulticast by @simonbasle in #3002

    :book: Documentation, Tests and Build

    • [test] Fix flaky BoundedElasticTest with better controlled tasks by @simonbasle in #2968
    • [doc] Polish Schedulers javadoc for common/cached instances by @dedeibel in #2995
    • [test] Improve flaky BoundedElasticScheduler toString test by @simonbasle in #3010

    :up: Dependency Upgrades

    • April round of upgrades: Gradle 7.4.2, plugins (download, jmh, spotless, artifactory, gradle enterprise) by @simonbasle in #2992
    • Update gradle/gradle-build-action to v2.1.5 by @simonbasle in #2996
    • Update ByteBuddy to v1.12.9 by @simonbasle in #3008

    New Contributors

    • @dedeibel made their first contribution in #2995
    Source code(tar.gz)
    Source code(zip)
  • v3.5.0-M1(Mar 23, 2022)

    What's Changed

    :warning: Update considerations and deprecations

    • Remove Kotlin extensions by @simonbasle in #2949
    • Remove deprecated Mono.doOn/AfterSuccessOrError by @simonbasle in #2954
    • Remove deprecated context-related operators by @simonbasle in #2953
    • Change behavior of switchOnNext/switchMap default 0 prefetch by @simonbasle in #2956
    • Remove deprecated ElasticScheduler by @simonbasle in #2955
    • Have concatMap default to 0 prefetch behavior by @simonbasle in #2967
    • Take(n) now behaves as take(n,true)/limitRequest by @simonbasle in #2969
    • Deprecate [Flux|Mono|Synchronous]Sink currentContext by @simonbasle in #2974

    :lady_beetle: Bug fixes

    • [agent] Avoid instrumenting methods with unwrappable returnType by @simonbasle in #2973

    :book: Documentation, Tests and Build

    • [test] Fix flaky BoundedElasticTest with better controlled tasks by @simonbasle in #2968

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.16...v3.5.0-M1

    Source code(tar.gz)
    Source code(zip)
  • v3.4.16(Mar 15, 2022)

    Reactor-Core 3.4.16 is part of 2020.0.17 Release Train (Europium SR17).

    This service release contains a few bugfixes and improvements.

    What's Changed

    :sparkles: New features and improvements

    • Improve BoundedElasticScheduler to be less blocking by @simonbasle in #2909
    • Add EmitFailureHandler.busyLoop flavor by @Animesh27 in #2943

    :lady_beetle: Bug fixes

    • Fix Mono.then not cancelling between Callable sources by @simonbasle in #2934

    :book: Documentation, Tests and Build

    • Update Gradle to v7.4 in #2922
    • [doc] Correct flux subscribe example in faq by @liukun2634 in #2924
    • Show how-to-fix hints in CI when preliminary steps fail (check of license headers, api compatibility) by @simonbasle in #2932
    • [guide] Remove ref to Swing/SwtScheduler in addons appendix by @simonbasle in #2959
    • [build] Have jcstress part of slowerChecks by @simonbasle in #2958

    :up: Dependency Upgrades

    • Update plugin spotless to v6.3.0 in #2925
    • Update plugin bnd to v6.2.0 in #2941
    • Update dependency org.awaitility:awaitility to v4.2.0 in #2945
    • Update dependency ch.qos.logback:logback-classic to v1.2.11 in #2946
    • Update dependency com.tngtech.archunit:archunit to v0.23.1 in #2940
    • Update plugin japicmp to v0.4.0 in #2948
    • Update dependency org.mockito:mockito-core to v4.4.0 in #2951
    • Update plugin download to v5.0.2 in #2950

    New Contributors

    • @Animesh27 made their first contribution in #2943 👍

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.15...v3.4.16

    Source code(tar.gz)
    Source code(zip)
  • v3.4.15(Feb 15, 2022)

    Reactor-Core 3.4.15 is part of 2020.0.16 Release Train (Europium SR16).

    This service release contains a few bugfixes.

    What's Changed

    :lady_beetle: Bug fixes

    • Fix Flux.generate request accounting leading to hanging by @davidyangss in #2884
    • Prevent FluxBufferTimeout requests < 0 when enough outstanding by @simonbasle in #2892

    :book: Documentation, Tests and Build

    • Replace drafter workflow with github's simple generator config by @simonbasle in #2887
    • Renovate group patched libs only, separate all plugin updates by @simonbasle in #2888
    • [build] Hardening of GitHub actions by @simonbasle in #2894
    • [doc] Consistently use replaySink var name for sink example by @kaka2634 in #2896
    • Rewrite a MonoSubscribeOn test to be less flaky by @simonbasle in #2893
    • Run preliminary spotless/japicmp job in ci, fix japicmp of core by @simonbasle in #2895
    • [build] Action updates: fix pinning by @simonbasle in #2901

    :up: Dependency Upgrades

    • Update plugin com.gradle.enterprise to v3.8.1 by @renovate-bot in #2890
    • Update mockito-core to v4.3.1 by @renovate-bot in #2904
    • Pin all github actions to commits corresponding to vXXX tags by @renovate-bot in #2905
    • Update plugin download to v5 by @renovate-bot in #2906
    • Update gradle/gradle-build-action to v2.1.3 by @renovate-bot in #2914
    • Update plugin spotless to v6.2.2 by @renovate-bot in #2910
    • Update dependency org.slf4j:slf4j-api to v1.7.36 by @renovate-bot in #2918
    • Update ByteBuddy to v1.12.8 by @renovate-bot in #2921
    • Update plugin artifactory to v4.27.1 by @renovate-bot in #2923

    New Contributors

    • @davidyangss made their first contribution in #2884
    • @kaka2634 made their first contribution in #2896

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.4.14...v3.4.15

    Source code(tar.gz)
    Source code(zip)
  • v3.4.14(Jan 11, 2022)

    Reactor-Core 3.4.14 is part of 2020.0.15 Release Train (Europium SR15).

    This release contains a cancellation bug fix on usingWhen, as well as build and docs improvements.

    :lady_beetle: Bug fixes

    • UsingWhen leak / fails to cancel when early cancel race (#2859)

    :book: Documentation, Tests and Build

    • [docs] Fix log output descriptions in faq docs (#2871, thanks @yujinchoi-94)
    • [doc] Fix several small typos in Flux javadocs (#2869, thanks @Leuteris)
    • Use Gradle's VersionCatalog for dependencies in a single place (#2853)
    • Automatically draft release notes on maintenance branches push (#2872, #2876)
    • Update JmhExecTask to use latest Gradle task APIs (#2877)

    :up: Dependency Upgrades

    • Enable Renovate bot with custom configuration (#2856)
    • Update all test dependencies to latest versions (#2860, #2862, #2867)
    • Update testng to 7.5 and reactor-extra (for jmh) to 3.4.6 (#2875)
    • Update all build plugins and gha actions to latest versions (#2864, #2866, #2861, #2863, #2878, #2880)
    • Update Gradle from 7.2 to 7.3.3 (#2865)
    • Update Kotlin to v1.5.32 (#2874)
    Source code(tar.gz)
    Source code(zip)
  • v3.4.13(Dec 14, 2021)

    Reactor-Core 3.4.13 is part of 2020.0.14 Release Train (Europium SR14).

    This service release contains a couple enhancements and documentation updates.

    :sparkles: New features and improvements

    • Discard concatMap queued elements on innerError (#2844)
    • Introduce TestSubscriber public API to reactor-test (#2708)

    :book: Documentation, Tests and Build

    • Fix marbles for mergeComparing having wrong timings (#2849)
    • Refguide debugging.adoc uses traceback terminology consistently (#2818)
    • Improve the refguide Retry.Backoff FAQ entry (#2852)

    :+1: Thanks to all contributors who participated to this release

    @kaladhar-mummadi

    Source code(tar.gz)
    Source code(zip)
  • v3.4.12(Nov 11, 2021)

    Reactor-Core 3.4.12 is part of 2020.0.13 Release Train (Europium SR13).

    This service release contains improvement to tracebacks rendering, introduces a couple utility methods to Logger and bring bugfixes.

    All changes from 3.3.22.RELEASE are also included and these are listed below with an additional level of indentation.

    :sparkles: New features and improvements

    • Tune OnAssemblyException.toString for better traceback rendering (#2814)
    • Improve traceback rendering of checkpoints (#2820)
    • Add logging convenience methods, polish a few messages (#2823)

    :lady_beetle: Bug fixes

    • Fix FluxSwitchMapNoPrefetch inner's scan(CANCELLED) (#2809)
    • Fix initialization order of Loggers factory (#2824)
    • Make OnAssemblyException serializable again (#2833)

    :book: Documentation, Tests and Build

    • Fix Signal#isOnComplete javadoc (#2817)
    • Fix flatMapMany description typo (#2834)
    • from 3.3.x:
      • Use @NonNull annotation, not JetBrain's NotNull (#2808)
      • [agent] Bump OpCode to ASM9 for compatibility with newer JDKs (#2825)
      • Use gradle-build-action for invoking Gradle on CI (#2828 )

    :+1: Thanks to all contributors who participated to this release

    @dominikbrandon, @lhauspie, @boroborome, @bigdaz, @trettstadtnlb, @EMellau

    Source code(tar.gz)
    Source code(zip)
  • v3.3.22.RELEASE(Nov 11, 2021)

    This is the last release of 3.3.x, as the Dysprosium line is now EoL

    What's Changed

    • Use @NonNull annotation, not JetBrain's NotNull by @simonbasle in #2808
    • [agent] Bump OpCode to ASM9 for compatibility with newer JDKs by @simonbasle in #2825
    • Use gradle-build-action for invoking Gradle on CI by @bigdaz in #2828

    New Contributors

    • @bigdaz made their first contribution in #2828

    Full Changelog: https://github.com/reactor/reactor-core/compare/v3.3.21.RELEASE...v3.3.22.RELEASE

    Source code(tar.gz)
    Source code(zip)
  • v3.4.11(Oct 12, 2021)

    Reactor-Core 3.4.11 is part of 2020.0.12 Release Train (Europium SR12).

    This service release contains bugfixes and one enhancement.

    All changes from 3.3.21.RELEASE are also included and these are listed below with an additional level of indentation.

    :warning: Update considerations and deprecations

    • Backtrace format has changed for cases where exception traverses multiple chains (#2780)

    :sparkles: New features and improvements

    • Prevent unnecessary duplicated lines in backtraces (#2780)

    :lady_beetle: Bug fixes

    • SwitchOnFirst better tracks in/out premature close(#2794)
    • ConcatArray: avoid next subscription if cancelled (#2791)
    • from 3.3.x:
      • Mono.create sink now discards if emitting after cancel (#2771)

    :book: Documentation, Tests and Build

    • Tune test performanceOfContinuouslyCancellingGroup by @simonbasle in https://github.com/reactor/reactor-core/pull/2777
    • Polish parameterized tests for better display names (#2773)
    • Document possible alternative to replay ManySink limit(0) (#2787)
    • Polish Mono cache operators documentation (#2790)
    • Fix Mono.flatMapIterable javadoc: no prefetch parameter (#2799)
    • Use Named.of to describe parameterized tests input (#2801)
    • from 3.3.x:
      • Bump to Gradle 7.2, polish build and upgrade plugins/libraries (#2775)
      • Fix Module was compiled with an incompatible version of Kotlin (#2795)
      • Bump ByteBuddy to 1.11.16, use TestKit in agent integration test (#2776)
      • Bump ByteBuddy from 1.11.16 to 1.11.19 (#2803)

    :+1: Thanks to all contributors who participated to this release

    @rs017991

    Source code(tar.gz)
    Source code(zip)
  • v3.3.21.RELEASE(Oct 12, 2021)

    Reactor-Core 3.3.21 is part of Dysprosium-SR24 Release Train.

    This service release contains one bugfixe and dependency bumps (including Gradle 7.2).

    :lady_beetle: Bug fixes

    • Mono.create sink now discards if emitting after cancel (#2771)

    :book: Documentation, Tests and Build

    • Bump to Gradle 7.2, polish build and upgrade plugins/libraries (#2775)
    • Fix Module was compiled with an incompatible version of Kotlin (#2795)
    • Bump ByteBuddy to 1.11.16, use TestKit in agent integration test (#2776)
    • Bump ByteBuddy from 1.11.16 to 1.11.19 (#2803)
    Source code(tar.gz)
    Source code(zip)
  • v3.4.10(Sep 14, 2021)

    Reactor-Core 3.4.10 is part of 2020.0.11 Release Train (Europium SR11).

    This service release contains bugfixes and polishing changes.

    All changes from 3.3.20.RELEASE are also included and these are listed below with an additional level of indentation.

    :warning: Update considerations and deprecations

    • Flux.replay underlying implementation doesn't support 0-size anymore (which was illogical in the first place)
      • For now, the operator transparently translates such calls to Flux.publish() instead (#2741)
    • Align Mono#share() behavior with Flux#share, split sink impl out (#2756)
      • Previously the Disposable obtained by calling mono.share().subscribe() (and that variant only) would terminate/cancel the whole mono.share() for all its subscribers. now this is an individual subscription, much like .subscribe(v -> {}) for instance.
      • the old behavior can still be obtained by calling toProcessor() and explicitly turning the source Mono into a MonoProcessor instead of sharing it, although the whole approach is deprecated.

    :sparkles: New features and improvements

    • from 3.3.x:
      • Have FluxOnBackpressureBufferStrategy reject sizes <= 0 (#2757)

    :lady_beetle: Bug fixes

    • Rework FluxReplay to avoid hanging, but reject 0 size (#2741)
    • Align Mono#share() behavior with Flux#share, split sink impl out (#2756)
    • Fix bad switchOnFirst state transition leading to dropped error (#2768)
    • from 3.3.x:
      • [reactor-test] Fix consumeWhile+expectRecorded* skipping signal (#2764)
      • In FluxIterable, defer hasNext exceptions from isEmpty to poll to protect against iterators that throw in hasNext (#2766)

    :book: Documentation, Tests and Build

    • Fix onDiscard/onErrorContinue javadoc position in Flux/Mono (#2762)
    • [doc] remove stray mid-sentence newlines (#2763)
    • from 3.3.x:
      • Document that windows (and groupBy groups) are unicast (#2767, #2568)

    :+1: Thanks to all contributors who participated to this release

    @hisener, @KATKrazy, @keturn

    Source code(tar.gz)
    Source code(zip)
  • v3.3.20.RELEASE(Sep 14, 2021)

    Reactor-Core 3.3.20.RELEASE is part of Dysprosium-SR23 Release Train.

    This service release contains bugfixes and polishing.

    :sparkles: New features and improvements

    • Have FluxOnBackpressureBufferStrategy reject sizes <= 0 (#2757)

    :beetle: Bug fixes

    • [reactor-test] Fix consumeWhile+expectRecorded* skipping signal (#2764)
    • In FluxIterable, defer hasNext exceptions from isEmpty to poll (#2766)
      • this one is a bit on the defensive side, protecting against iterators that throw in hasNext

    :book: Documentation, Tests and Build

    • Document that windows (and groupBy groups) are unicast (#2767, #2568)

    :+1: Thanks to all contributors who participated to this release

    @hisener

    Source code(tar.gz)
    Source code(zip)
  • v3.4.9(Aug 10, 2021)

    Reactor-Core 3.4.9 is part of 2020.0.10 Release Train (Europium SR10).

    This service release contains bugfixes and new features.

    Some changes from 3.3.19.RELEASE are also included and these are listed below with an additional level of indentation.

    :beetle: Bug fixes

    • reworks FluxConcatArray to eliminate unexpected thread switch (#2742)
    • from 3.3.x
      • Fix hanging of windoUntil(cutBefore=false) by replenishing (#2749)

    :book: Documentation, Tests and Build

    • Clarify behavior of collect* operators on empty sequences (#2746)
    • from 3.3.x:
      • Polish logging: test scenario name, verbose MonoCollect logs (#2750) 84256772c

    :+1: Thanks to the following contributors that also participated to this release

    @ivyazmitinov

    Source code(tar.gz)
    Source code(zip)
Owner
Reactor
Reactive Streams based projects for backpressure-ready asynchronous message passing.
Reactor
My task for " The Sparks Foundation

MyBank This is a Sparks Foundation GRIP (Graduate Rotational Internship Program) Technology Task. Task 2: Basic Banking App ◇ Create a simple mobile a

Sanjeev 1 Oct 19, 2021
Reactive Streams Specification for the JVM

Reactive Streams The purpose of Reactive Streams is to provide a standard for asynchronous stream processing with non-blocking backpressure. The lates

null 4.5k Dec 30, 2022
Protect your Spigot server against IP forwarding exploits, as well as blocking unknown BungeeCord and/or Velocity proxies.

Sentey Protect your Spigot server against IP forwarding exploits, as well as blocking unknown BungeeCord and/or Velocity proxies. But firewalls are a

ComuGamers Network 18 Dec 28, 2022
AndroidHiddenApiBypass - Bypass restrictions on non-SDK interfaces

AndroidHiddenApiBypass Bypass restrictions on non-SDK interfaces. Why AndroidHiddenApiBypass? Pure Java: no native code used. Reliable: does not rely

LSPosed 903 Jan 6, 2023
Non intrusive log4j2 RCE vulnerability patch.

Log4j Patch Resolve the RCE vulnerability caused by JNDI lookup in log4j 2.0~2.14.1. It is licensed under the WTFPL 2.0 license, you can do anything w

Glavo 67 Dec 2, 2022
source code of the live coding demo for "Building resilient and scalable API backends with Apache Pulsar and Spring Reactive" talk held at ApacheCon@Home 2021

reactive-iot-backend The is the source code of the live coding demo for "Building resilient and scalable API backends with Apache Pulsar and Spring Re

Lari Hotari 4 Jan 13, 2022
Decorating Spring Boot Reactive WebClient for tracing the request and response data for http calls.

SpringBoot Reactive WebClient ?? Tracing HTTP Request through a single pane of glass Decorating Spring Boot Reactive WebClient for tracing the request

Reactive Learning LLP 7 Jul 13, 2022
Spring 5 Reactive playground

Spring Reactive Sample This is a sandbox project for demonstrating Reactive Streams support in Spring framework and Spring ecosystem. I've also mainta

Hantsy Bai 1.1k Dec 29, 2022
A joint research effort for building highly optimized Reactive-Streams compliant operators.

reactive-streams-commons A joint research effort for building highly optimized Reactive-Streams compliant operators. Current implementors include RxJa

Reactor 350 Dec 23, 2022
Cloud Runtimes Specification for the JVM

cloud-runtimes-jvm Cloud Runtimes Specification for the JVM. Introduction Standard API for dapr / layotto / capa / .... Motivation [Discussion] Future

Reactive Group 6 Jul 28, 2022
Nrich is a Java library developed at CROZ whose purpose is to make development of applications on JVM a little easier.

nrich Nrich is a Java library developed at CROZ whose purpose is to make development of applications on JVM a little easier. It contains modules that

CROZ 44 Nov 12, 2022
A Sentry SDK for Java, Android and other JVM languages.

Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoy

Sentry 912 Dec 28, 2022
Java agent that enables class reloading in a running JVM

Welcome to Spring-Loaded What is Spring Loaded? Spring Loaded is a JVM agent for reloading class file changes whilst a JVM is running. It transforms c

Spring 2.7k Dec 26, 2022
Fault tolerance and resilience patterns for the JVM

Failsafe Failsafe is a lightweight, zero-dependency library for handling failures in Java 8+, with a concise API for handling everyday use cases and t

Failsafe 3.9k Dec 29, 2022
High level api to interact with maven form within the jvm

maven-utils High level api to interact with maven from within the jvm Use it by adding the dependency to your maven pom: <dependency> <groupId>se.

Alipsa 5 Sep 29, 2022
Spring-boot application to demo JVM HEAP and Native memory leak

Description This repo can be used as demo repo for finding memory leaks. Example spring-boot project to show how to find and fix JVM HEAP memory leak

Iranna Nk 4 Jul 22, 2022
Deploys an agent to fix CVE-2021-44228 (Log4j RCE vulnerability) in a running JVM process

-- This repository has been archived -- Further development of this tool will continue at corretto/hotpatch-for-apache-log4j2. Thanks for sharing, com

Volker Simonis 108 Dec 23, 2021
Low-overhead, non-blocking I/O, external Process implementation for Java

NuProcess NuProcess is proud to power Facebook's Buck build. A low-overhead, non-blocking I/O, external Process execution implementation for Java. It

Brett Wooldridge 644 Dec 29, 2022
High performance non-blocking webserver

Undertow Undertow is a Java web server based on non-blocking IO. It consists of a few different parts: A core HTTP server that supports both blocking

null 3.3k Jan 1, 2023