github reactor/reactor-core v3.2.0.RELEASE

latest releases: v3.8.5, v3.7.18, v3.8.4...
7 years ago

This is the first release of Reactor 3.2, part of the Californium-RELEASE Release Train.

This major release contains a few significant new features, in addition to a heap of improvements and bug fixes.

⚠️ Update considerations and deprecations

  • Compared to 3.1.x, the Scannable#operatorName() method has been renamed to stepName() (#1156)
  • Disposables.composite() now has list semantics rather than undocumented set semantics, and thus should be more performant (#1237)
  • The constant Schedulers.DEFAULT_POOL_SIZE is now used internally (notably by Schedulers.[new]parallel()), but unlike before it doesn't enforce a minimum of 4 anymore. It can be tuned via system property reactor.schedulers.defaultPoolSize now though (#1243, #1246)
  • repeat(N) is now aligned with retry(N), as well as repeat(N, Predicate)/retry(N, Predicate): the number indicates the amount of repetitions of the original sequence, ie 0 mirrors the original sequence while 1 mirrors the original sequence + an additional repetition of it. Negative values are rejected at assembly time. (#1252)
    • look out for usage of repeat(long) in your code and decrement the passed parameter by one
    • repeat(0) should be replaced with Flux/Mono.empty()
  • windowUntil and windowWhile don't have a final empty window at the end of the sequence (#1033)
  • Default behavior for Operators.onErrorDropped is now to both bubble and throw the error
    • Mono.fromCompletionStage now drops fatal exceptions rather than hanging (#1118)
  • Blocking APIs (like blockLast(), block(), iterator()) called inside a parallel or single Scheduler trigger an exception (#1102)
    • This kind of blocking call are harmful as they impact limited resources, with a high risk of freezing the application
  • concatMapDelayError default behavior is now to delay the errors until the END (#1101)
    • This aligns with other *DelayError operators
  • StepVerifier.withVirtualTime now use a global lock, making virtual time verifications mutually exclusive (#648)
    • Virtual time impacts schedulers at the application level. Parallelisation of tests could lead to unforeseen side effects due to this (initializing operators with a VTS and have the StepVerifier see and manipulate the wrong VTS)
  • create uses Operators.onOperatorError hook instead of onErrorDropped (#1078)
  • (deprecation) Scannable#operatorName() is deprecated in favor of stepName() (#1115, #1140)
  • (internal) Switch to a simplified implementation for Mono.publish(Function) (#437)
  • (internal) Simplify MonoProcessor internals in preparation for #1114 and further 3.2 changes

⭐ Release focus features

  • Add metrics() to Flux (#1183, #1123, 34e0d4b, #1245, #1242, #1250)
    • This operator does nothing if Micrometer is not on the classpath
    • It exposes metrics from upstream signals visible at the operator's position in the chain
  • Add exponential backoff retry with jitter to core: retryWithBackoff (#1122)
    • This version of retry reflects what we think is the industry best practice in terms of retries.
    • It is a good middle ground between the too simple retry(n), the complex retryWhen(Function) and the more configurable RetryFunction from reactor-addons
  • New operators for transactional reactive use cases: usingWhen (#1220, b87ea6d, #1233, #1259)
    • Like using, but the resource is provided asynchronously through a Publisher
    • Can have separate async "cleanup" for complete, error and cancel terminations
    • Cleanups are asynchronous as well (Function<Resource, Publisher>) and only delay the propagation of the terminal signals, NOT the onNext signals.
    • Cancelled early before the resource is emitted, the Publisher<Resource> itself is cancelled.
  • New doOnDiscard(Class, Consumer) operator (#999, #1343, #1345, #1347)
  • Installs a local Context hook that will let upstream operators in the chain clean up elements that get either filtered out of the downstream sequence or prefetched then discarded
  • New onErrorContinue() mode that influences the upstream chain of operator (#629)
    • Supporting operators up in the chain will request more from their source in case of error, instead of terminating the sequence.
    • The Throwable is passed to a handler instead of downstream.

✨ New features and improvements

  • Include sequence name in timeout()'s message (#1349)
  • Replace String.replaceAll with a static Pattern and Matcher.replaceAll in Scannable (#1315)
  • Added a way to strictly limit the rate of requests with limitRate(n, 0) (#1317)
    • previously the lowTide and highTide parameter could still be changed by internal prefetching strategies
    • now with a lowTide of 0, the requests will strictly adhere to highTide
  • Blocking code detection and rejection has been improved for toStream() and toIterable(), and now only reject when the iteration is performed (#1313)
    • it would previously reject right where the Iterable was materialized, but what actually blocks is the act of iterating.
  • Improve concat error message on null Publisher (#1321)
  • Calling Mono.from(Flux.from(mono)) is now immediately returning the mono instance, as this is conceptually a no-op. (#1329)
    • the inverse operation (Flux.from(Mono.from(flux))) is NOT a no-op as it transforms the original Flux into a Mono, so it still returns a different instance.
  • Use more descriptive parameter names for buffer durations (#1331)
  • The default Scheduler pool size is now configurable via a system property (#1243)
  • In the case where a QueueSubscription is logged via log() during an onNext, its toString method is explicitly called (#1270)
    • typically this would happen when using window() immediately followed by log(), which is not really useful but was even less useful since it would trigger an exception
  • Tuple2..Tuple8 now have mapT1..mapT8 (as relevant) methods that allow to change a single part of the Tuple (e4a9aee, discussed in #1058)
  • cache(Duration) now have an overload that takes a Scheduler, added Mono.cache TTL-generator variant (#1189, #1125)
  • Operators.lift now has an alternative that exposes the raw Publisher: liftPublisher and supports Fuseable (#1205, #1206)
  • Added zip variants with 7 and 8 arguments (#1210
  • Support 0 delay/period in Flux.interval (#1178)
  • Add immutable empty() queue Supplier to Queues, support empty and one cases in Queues.capacity() (#1161, d9d76ab)
  • doOnEach now support Fuseable and ConditionalSubscriber (#1003)
  • Flux.take(0) now eagerly cancels on subscription (#1158)
  • Lazy Mono#fromFuture and Mono#fromCompletionStage added, with Supplier param (#1131)
  • Add an error(Supplier) variant to Flux and Mono (#1100)
  • Add Scannable#steps(), which produces a Stream<String> of all the stepNames both upstream and downstream (including the current Scannable) (#1115, #1140)
  • All operators now implement basic Scannable (this avoids problems for users that use instanceof checks in hooks, #1136)
  • [kotlin] Add Flux.split extension to convert Flux<List<T>> to Flux<T> (#1089)
  • [reactor-test] Add verifyThenAssertThat(Duration) to allow assertions and verification timeout (#1124)
  • [reactor-test] Allow naming of a whole StepVerifier scenario through options (#1077)
  • [reactor-test] Allow to change the LoggerFactory with a custom implementation, provide a TestLogger one that can be used to assert log contents (8f3a8fa)
  • [reactor-test] Add a cold version of the TestPublisher than can be set up before eg. subscribing in a StepVerifier (#1236)

🪲 Bug fixes

  • Fix ClassCastException in OneQueue/ZeroQueue + Java9 build (#1326)
  • When using doOnSuccess and subscribing without an error handler, errors would be swallowed (#1337)
    • This now generates a ErrorCallbackNotImplemented exception like in other cases, unless a doOnTerminate is also used
    • The best practice is still to always define an error handler when using subscribe(...)
  • Fixed an ArrayIndexOutOfBoundsException when using lift with a ParallelFlux operator that is fuseable (can be triggered by using Sleuth, #1293)
  • FluxPublish should trigger an extra poll on sync fusion (#1290, #1291)
  • Request fusion with THREAD_BARRIER in concatMap* and publish (#1302)
  • When using a non-compliant TestPublisher, calling .mono() would turn it into a compliant one. This has been fixed and the mono will now continue to be a bad boy (#1244)
  • A few bufferTimeout and bufferWhen issues have been corrected around cancellation and drain race conditions (#1247)
  • Flux.last() now correctly throws a NoSuchElementException on empty source even when said source is a Callable Mono(#1226)
  • delayUntil correctly request Long.MAX_VALUE and not Integer.MAX_VALUE on subscribe (#1214)
  • Operators.lift() properly maintain GroupedFlux/ConnectableFlux interfaces (#1204)
  • Request is now accounted for in `FluxOnBackpressureBufferTimeout (#1194)
  • onSubscribe should be done before add in MonoCacheTime.subscribe (#1190)
  • Multi-subscriber operators Context resolution resolves to 1st context (#1114)
  • Fix dangling thread when calling WorkQueueProcessor.forceShutdown (#1142)
  • Let VirtualTimeScheduler defer advanceTime if queue is empty (#783)
    • This avoids a situation where, due to a subscribeOn, the operators delaying values end up reading the clock AFTER the virtual time has been moved forward by thenAwait, hanging the test.
  • Tweak FluxPublish dispose to clear the existing connection (#1173)
  • Avoid interrupting WorkerTask Future if cancelled race (#1107)
  • FluxRefCount DisconnectException on cancellation race (#1088)
  • (internal cleanup) use passed queue in FluxGroupBy.checkTerminated (#1094)
  • Only terminate ExecutorScheduler if underlying is shut down (#1080)
  • Mono.fromCompletionStage now drops fatal exceptions rather than hanging (#1118)

📖 Documentation, Tests and Build

🎁 Contribution process change

A notable change in the way we work with the repository and contributions that make sense for maintenance releases: as of commit 0d8e16e, there will be no more port #xxx backport commits in maintenance branches, but rather issues will be fixed first in the maintenance branch THEN a forward-merge will happen to include the fix in the master branch. See #1225.

👍 Thanks to the following contributors that also participated to this release

@alex-diez, @baptistemesta, @charlesmuchene, @genie-youn, @igoperikov, @madgnome, @MarkusJais, @nurkiewicz, @OlegDokuka, @pdudkiewicz, @smiklos, @szpak, @utwyko, @xcorail, @yamkazy, @0xflotus

Don't miss a new reactor-core release

NewReleases is sending notifications on new releases.