MILESTONE 2 for Reactor 3.2.0, which will be the first release in the CALIFORNIUM Release Train.
This milestone contains a lot of fixes and improvements, as well as new features we'd really like your feedback on:
📢 Feedback Wanted! New features
- Add
metrics()toFlux(#1183, #1123, 34e0d4b)- This operator does nothing if
Micrometeris not on the classpath - It exposes metrics from upstream signals visible at the operator's position in the chain
- 📢 Feeback wanted on the type of metrics exposed
- This operator does nothing if
- 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 complexretryWhen(Function)and the more configurableRetryFunctionfromreactor-addons
- New operators for transactional reactive use cases:
usingWhen(#1220, b87ea6d)- Like
using, but the resource is provided asynchronously through aPublisher - 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 theonNextsignals.
- Like
⚠️ Update considerations and deprecations
windowUntilandwindowWhiledon't have a final empty window at the end of the sequence (#1033)- Default behavior for
Operators.onErrorDroppedis now to both bubble and throw the errorMono.fromCompletionStagenow drops fatal exceptions rather than hanging (#1118)
- Blocking APIs (like
blockLast(),block(),iterator()) called inside a parallel or singleSchedulertrigger an exception (#1102)- This kind of blocking call are harmful as they impact limited resources, with a high risk of freezing the application
concatMapDelayErrordefault behavior is now to delay the errors until theEND(#1101)- This aligns with other *DelayError operators
StepVerifier.withVirtualTimenow 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)
createusesOperators.onOperatorErrorhook instead ofonErrorDropped(#1078)- (deprecation)
Scannable#operatorName()is deprecated in favor ofstepName()(#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
✨ New features and improvements
cache(Duration)now have an overload that takes aScheduler, addedMono.cacheTTL-generator variant (#1189, #1125)Operators.liftnow has an alternative that exposes the rawPublisher:liftPublisher(#1205)Operators.liftnow supportsFuseable(#1206)- Added
zipvariants with 7 and 8 arguments (#1210 - Support 0 delay/period in
Flux.interval(#1178) - Add immutable
empty()`` queue Supplier toQueues, support empty and one cases inQueues.capacity()` (#1161, d9d76ab) doOnEachnow supportFuseableandConditionalSubscriber(#1003)Flux.take(0)now eagerly cancels on subscription (#1158)- Lazy
Mono#fromFutureandMono#fromCompletionStageadded, withSupplierparam (#1131) - Add an `error(Supplier)`` variant to Flux and Mono (#1100)
- Add
Scannable#steps(), which produces aStream<String>of all the stepNames both upstream and downstream (including the currentScannable) (#1115, #1140) - All operators now implement basic
Scannable(this avoids problems for users that use instanceof checks in hooks, #1136) - [kotlin] Add
Flux.splitextension to convertFlux<List<T>>toFlux<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
LoggerFactorywith a custom implementation, provide aTestLoggerone that can be used to assert log contents (8f3a8fa) - [reactor-test] Add a cold version of the
TestPublisherthan can be set up before eg. subscribing in aStepVerifier(#1236)
🪲 Bug fixes
Flux.last()now correctly throws aNoSuchElementExceptionon empty source even when said source is aCallable Mono(#1226)delayUntilcorrectly requestLong.MAX_VALUEand notInteger.MAX_VALUEon subscribe (#1214)Operators.lift()properly maintainGroupedFlux/ConnectableFluxinterfaces (#1204)- Request is now accounted for in `FluxOnBackpressureBufferTimeout (#1194)
- onSubscribe should be done before add in MonoCacheTime.subscribe (#1190)
- Multi-subscriber operators
Contextresolution resolves to 1st context (#1114) - Fix dangling thread when calling
WorkQueueProcessor.forceShutdown(#1142) - Let
VirtualTimeSchedulerdeferadvanceTimeif 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 bythenAwait, hanging the test.
- This avoids a situation where, due to a
- Tweak
FluxPublishdispose to clear the existing connection (#1173) - Avoid interrupting
WorkerTaskFutureif cancelled race (#1107) FluxRefCountDisconnectExceptionon cancellation race (#1088)- (internal cleanup) use passed queue in
FluxGroupBy.checkTerminated(#1094) - Only terminate ExecutorScheduler if underlying is shut down (#1080)
Mono.fromCompletionStagenow drops fatal exceptions rather than hanging (#1118)
📖 Documentation, Tests and Build
- Improve various marble diagrams (#1043, #1008, #1167)
- Document (im)mutability of Tuple2
toList()vsiterator()(#1135) - Point to reference doc operator matrix in Flux/Mono javadoc (f2bc74f)
- Warn on
doOnSubscribeusage (#1090) - various javadoc typos and minor rephrasing (#1222, 89a8e0e, #1149, #1199, 51dff9f, 4a1f691, 4e55122, #1095, 7a6a8a1, 35cb6fd,
- Various test fixes (2f74309, 0254f45, #1139, 1c27a15, 44dc73c, 8d942e1, 38f8edb)
- Add meaningful toString to FluxSink/MonoSink implementations (#1130)
👍 Thanks to the following contributors that also participated to this release
@alex-diez, @baptistemesta, @charlesmuchene, @igoperikov, @madgnome, @OlegDokuka, @smiklos, @utwyko, @yamkazy