Releases: reactor/reactor-core
v3.1.8.RELEASE
This is the 9th release of Reactor 3.1, part of BISMUTH-SR10
Release Train.
This is a recommended update for all Reactor 3 users. Note that all fixes in this release
are backports of fixes in the upcoming 3.2.0.RELEASE.
⚠️ Update considerations
Flux.last()
used to skip throwing aNoSuchElementException
on some category of empty sources (Flux
orMono
that areCallable
). This is a bug and it correctly does throw now. (#1226)
✨ New features and improvements
🪲 Bug fixes
Flux.last()
throwsNoSuchElementException
(see update considerations section, #1226)Operators.lift
properly maintainGroupedFlux
/ConnectableFlux
interface (#1204)- Request is not tracked in
FluxOnBackpressureBufferTimeout
(#1194) - Let
Flux.interval
support 0 delay/period (#1178) delayUntil
now requestsLong.MAX_VALUE
instead ofInteger.MAX_VALUE
(#1214)
📖 Documentation, Tests and Build
- Fix compiler warnings during compileTestJava phase (#1139)
- Revert bad replace of word "set" with "push" in comments (#1192)
👍 Thanks to the following contributors that also participated to this release
v3.1.7.RELEASE
This is the 8th release of Reactor 3.1, part of BISMUTH-SR9
Release Train.
This maintenance update is mainly backporting QoL enhancements and fixes from the ongoing 3.2.0 development effort.
✨ New features and improvements
MonoProcessor
internals have been improved and now support Context resolution (6ab5186)- Pub-Sub operators and processors now support Context resolution (first context found) (#1114)
- Partial resolution for recursive virtual time use (#783)
Flux.take(0)
now eagerly cancel and onComplete (#1158)
🪲 Bug fixes
Mono.cache(Duration)
should not onSubscribe after adding a new subscriber (#1190)WorkQueueProcessor.forceShutdown
should interrupt hanging threads (#1142)Flux.publish
should properly dispose its state on cancel (#1173)
Many thanks for you reports folks !!! 💃
@Vulcannis @rwinch @elrodro83 @stavalfi
Special thanks to @OlegDokuka for his continuous support on our Gitter channel 🥇
v3.1.6.RELEASE
This is the 7th release of Reactor 3.1, part of BISMUTH-SR8
Release Train.
This maintenance update is mainly backporting QoL enhancements and fixes from the ongoing 3.2.0 development effort.
⚠️ Update considerations and deprecations
Operators.onErrorDropped
still bubbles the exception up, but it also logs the error (#1118, 97d110f)- see the associated
Mono.fromFuture
change below
- see the associated
- Most operators that go back to the blocking paradigm now throw an exception when used from
parallel()
andsingle()
Schedulers
(#1102 , 5291239)Mono#block
,Flux#blockFirst
,Flux#blockLast
,toIterator
,toStream
✨ New features and improvements
StepVerifier.withVirtualTime
is now mutually exclusive to better protect from its side effects onSchedulers
when running multiple tests in parallel (#648, 65e7d62)
🪲 Bug fixes
Mono.fromFuture
would sometimes swallow errors.- Although fatal errors like
StackOverflowError
are bubbled up and are not expected to be part of the sequence anymore, here such error would totally disappear. NowMonoCompletionStage
drops such errors, which results in the SOE being logged thanks to the associated change toOperators.onErrorDropped
(97d110f, #1118)
- Although fatal errors like
- Avoid interrupting
WorkerTask
Future
in case of cancel race (#1107, e8f7867)
v3.1.5.RELEASE
This is the 5th release of Reactor 3.1, part of BISMUTH-SR7
Release Train.
This is a recommended update for all Reactor 3 users. Note that all fixes in this release
are backports of fixes in the upcoming 3.2.0.RELEASE.
✨ New features and improvements
create
usesonOperatorError
hook instead ofonErrorDropped
, avoiding thrown exceptions (#1078)
🪲 Bug fixes
RejectedExecutionException
now only terminate theExecutorScheduler
if the underlyingExecutor
is shut down (#1080)- Fixed
DisconnectException
on cancellation race inParallelFlux#refCount
(#1088)
📖 Documentation, Tests and Build
- Warn on
doOnSubscribe
javadoc: not for acting on theSubscription
(#1090) - Fix return clause of
blockLast
javadoc mentioning "first" element instead of "last" (#1095) - Small internal cleanup of
groupBy
code (#1094)
👍 Thanks to the following contributors that also participated to this release
v3.1.4.RELEASE
This is the 4th release of Reactor 3.1, part of BISMUTH-SR6
Release Train.
This is a recommended update for all Reactor 3 users.
⚠️ Update considerations and deprecations
- The MPSC
Queue
implementation from3.1.3.RELEASE
shouldn't have been public (#1010, #1035)- it is now exposed as a plain
Queue
throughQueues.unboundedMultiproducer()
- it is now exposed as a plain
- 3 operator implementations have mistakenly been released as public classes (#1036)
- These classes shouldn't have normally been noticed by users. However they have now been made private.
FluxDelaySequence
,FluxIndex
andFluxIndexFuseable
- Emitting a
Context
as part ofFlux.repeatWhen
andFlux.retryWhen
companion flux triggers a specific behavior (#1048)- The emitted
Context
, which acts as a trigger for resubscription to the source, replaces the originalContext
of the
xxxWhen operator and becomes visible to the upstream from that point. - Care should be taken to craft that
Context
from the originalContext
, otherwise you risk blindly deleting keys from the original that 3rd party libraries rely on. (this is described in the javadoc)
- The emitted
- Like
Flux.zip
,Mono.zip
short-circuits on the first source that terminates empty, cancelling other pending sources (#1071)- this means that the Mono will complete as soon as any
Mono<Void>
source or any emptyMono<T>
completes. this could lead to earlier than expected completions. - note this changes nothing for sources that are all valued
- You should look for
Mono.zip(...).then()
pattern in your code and replace that withMono.when(...)
instead, aswhen
does wait for all completions and results in aMono<Void>
. - If you want to keep the behavior of letting all valid sources run to completion, use
Mono.zipDelayError
, which
won't cancel other sources (aggregating to a compositeonError
in case of 1+ errors, or an empty mono in case
of 0 error and 1+ empty sources)
- this means that the Mono will complete as soon as any
✨ New features and improvements
log
now has a variant that directly takes aLogger
instance, which can improve performance if the bottleneck
is the resolution of Loggers (#956)- a new variant of merge, the
mergeOrdered
, has been added toFlux
andParallelFlux
(#963) Flux.concatWithValues(T...)
andMono.thenReturn(T)
have been added to conveniently concat/continue with
scalar values (#1029)- Operators that used to synchronize around a queue now use the new MPSC queue implementation instead (#914)
distinct
now allows for arbitrary backing store, not necessarily aCollection
, if you also provide a
"distinct check"BiPredicate
(#1054)- In Kotlin extensions, nullable types are mapped to non-nullable Monos (#1062)
- Emitting a
Context
as part ofFlux.repeatWhen
andFlux.retryWhen
companion flux triggers a specific behavior (see update considerations above, #1048) - Core implementations of
Scheduler
andWorker
are nowScannable
(#1050)- The interfaces themselves are not, so you'll need to attempt scanning by first calling
Scannable.from(schedulerInstance)
ExecutorService
-backed schedulers can offer a degree of insight into their executor if it is aThreadPoolExecutor
, via
scanning ofCAPACITY
andBUFFERED
- Most core executors that used to be backed by a
Executors.newSingleThreadExecutor
(which isn't introspectable by the above
method) are now backed by aThreadPoolExecutor
with acorePoolSize
==maxPoolSize
of1
.
- The interfaces themselves are not, so you'll need to attempt scanning by first calling
- Most operators that take a
Scheduler
as parameter can return thatScheduler
or theWorker
they use via ascan()
of the newAttr.RUN_ON
attribute. AScannable.UNAVAILABLE_SCAN
is returned if that information is not available (dcc36e5)
🪲 Bug fixes
doOnEach
could be ignored in case of aFuseable
source, due to a mistake in the way it would call its
downstreamonSubscribe
method with its source rather than itself (#1056, #1067)- The
elastic
Scheduler
would retain a reference to all its expired workers, which has now been fixed (#1070) - The
TopicProcessor
andWorkQueueProcessor
forceShutdown()
method would fail to shut down the "request task"
backingExecutorService
(#1074) - Like
Flux.zip
,Mono.zip
short-circuits on the first source that terminates empty, cancelling other pending sources
(see update considerations above, #1071)
📖 Documentation, Tests and Build
- Documentation improvements and typo corrections
- Various test improvements making some tests less brittle on our CI
japicmp
now has the previous 3.1.3.RELEASE as baseline (1c0fa6d)- Some tests were missing a final
verify()
call, and as such not testing anything (#1046)
👍 Thanks to the following contributors that also participated to this release
v3.1.3.RELEASE
This is the 3rd release of Reactor 3.1, part of BISMUTH-SR5
Release Train.
This is a recommended update for all Reactor 3 users.
⚠️ Update considerations and deprecations
- The implementations of
bufferWhen
andwindowWhen
(which are also backing their timeout based variants) have changed, fixing leaks in the process. distinct()
/distinctUntilChanged()
now use the full object (with aHashSet
) instead of just the extractedhashcode()
for their distinct criteria (#1025)EventLoopProcessor#shutdownAndAwait(long, TimeUnit)
has been deprecated (#986)- MpscLinkedQueue, FluxDelaySequence, FluxIndex, FluxIndexFuseable have been scoped public API and
should NOT be used.
A patch release will fix their scope back to package scope.
✨ New features and improvements
- If Level is FINE/FINEST,
log()
now logs errors usingdebug()
/trace()
(#967) - ParallelFlux#composeGroup maintains
parallelism()
(#968) EventLoop
basedProcessors
now have aDuration
basedshutdownAndAwait
(#986)- Test features:
- Add
delaySequence
operator to Flux, that just shifts the sequence forward in time (#989) - Prevent handle sink usage after error/complete (#965)
- Make
Context
accessible throughSignal
frommaterialize
anddoOnEach
(#947, #1004) - Avoid using only hashcode as default
distinct()
/distinctUntilChanged()
criteria (#1025)
🪲 Bug fixes
- Detect same-thread request in Mono subscribeOn (#943, #949)
- Execute
doFinally
even ifsubscribe()
throws (#951) - Don't retain reference to UnicastProcessor subscriber on cancel (#980)
- Prevent NPE when debug mode is activated via command line (#985)
- Fix eventual premature termination issue with WorkQueueProcessor (4b2fd19)
- [test] VirtualTimeScheduler: Use single worker, wait for expectations before advancing time (#1001, #992, #959)
windowWhile
now replenishes on premature cancel (#1017)- Fixed leak: retaining of windows in
windowWhen
(#975) - Fixed leak: buffers being retained until completion of a
bufferWhen
Flux (#969, 170f39b) - Notify lack of request on bufferTimeout (#994)
- Process fatal exceptions in Schedulers.handleError, don't throw / silently fail (#916)
📖 Documentation, Tests and Build
- Improve documentation of Flux.merge, advanced features reference guide, various typos (#1020, #970)
- Bump Kotlin, AssertJ and ReactiveStreams versions (#915, 69fbde6, 6c0bde7)
- Improve CI testing, avoid longer tests on Travis only, decrease verbosity of some tests (14d607b, #325, #1007, )
👍 Thanks to the following contributors that also participated to this release
v3.2.0.M1
3.2.0 MILESTONE 1
This version of 3.2.0 is an advance MILESTONE (despite the fact that development continues in parallel on 3.1.3.RELEASE). Its main goal is to make the "error mode" feature accessible for testing (see #629 and
ce62135).
Note that all latest developments on the master branch for 3.1.x versions are not necessarily present in this milestone, as it was branched from master on Jan. 10 2018 (commit 5a4d38f "Notify lack of request on bufferTimeout" in the history)
v3.1.2.RELEASE
This is the 3rd release of Reactor 3.1, part of BISMUTH-SR4
Release Train.
This is a recommended update for all Reactor 3 users. It notably contains a new Flux
operator called index
to index as a Tuple<Long, T>
or any arbitrary container each element from a sequence.
✨ New features and improvements
- Add
Flux#index
operator (#934) - Add
Mono#single
to enforce the presence of an element in aMono<T>
(#940) - Add
Mono#blockOptional
to block and return anOptional
(#918) - Add
Flux#fromStream(Supplier<Stream>)
(#922) - Use an explicit timeout message for
timeout
operator (#925) - Add a Kotlin extension to create a
Mono
from aSupplier
(#929)
🪲 Bug fixes
- Fix
concatDelayError
andconcatMapDelayError
withMono.error
(#936)
📖 Documentation, Tests and Build
- Add
Context
simple example in reference guide (#921) - Fix javadoc marble for
Mono.repeatWhenEmpty
(#919) - Fix CLA in Contributing.md (#98b32f5)
- Fix links to JDK Reference (#a0d8126)
- Add
cache(Duration)
javadoc (#930) - Fix
Context
content in test (#950) - Improvve
Scheduler
javadoc (#935)
👍 Thanks to the following contributors that also participated to this release
v3.1.1.RELEASE
This is the 2nd release of Reactor 3.1, part of BISMUTH-SR2
Release Train.
This is a recommended update for all Reactor 3 users. It notably contains an important fix for a Flux#windowTimeout
bug introduced in v3.1.0.
✨ New features and improvements
- Overflow exception for
interval
has been clarified, making it clearer thatinterval
doesn't really support backpressure (#911) - Improved means of customizing the request amount mid-chain: new
limitRequest
operator will strictly cap the total request (without prefecthing, unlikelimitRate
) andlimitRate
now has a variant that takes alowTide
parameter that allow to customize the replenishing amount (#879, #894) - Kotlin extension now extends
Publisher
withtoFlux
andtoMono
operations (#908)
🪲 Bug fixes
Flux#windowTimeout
with <10ms timeouts could trigger race conditions and lose some windows/drop data to already closed windows. The operator has consequently been reworked (#912)- Periodic tasks of Schedulers and Workers are now correctly cancelled by calling
dispose()
(#880) - Ensure that
Scannable
scanning of PARENT and ACTUAL always returns aScannable
, even if the original unsafe scan didn't. In the later case, the UNAVAILABLE_SCAN instance is returned (#895) ParallelFlux
(.parallel()
) is now considered aTHREAD_BARRIER
for fusion purposes, allowing sensitive operators to skip fusion (#905)
📖 Documentation, Tests and Build
- Several typos fixed and rephrasing have been made (#885, #868, #902)
- Reference guide now has a small section on
reactor-extra
(#899) - Build has been upgraded to Gradle 4.2, binary compatibility is now checked with a baseline (3.1.0.RELEASE) using
japicmp
(#884) - Java 9: fixed deep reflection issue and additional build with JDK9 in Travis CI (minus a few elements due to build dependencies not being ready, #881, #883, #891)
- The Kotlin plugin has been upgraded to 1.1.51, with a workaround for a source jar class duplication issue (#889, #887)
- OSGI compatibility has been improved with the removal of extraneous packages and marking kotlin and JSR305 as optional (#903)
👍 Thanks to the following contributors that also participated to this release
v3.1.0.RELEASE
This is the first release of Reactor 3.1, part of Bismuth-RELEASE
Release Train.
This version is a recommended update for all Reactor 3 users, and will be the one backing Spring Framework 5.0. A lot of API polishing has occurred between the last 3.0.x release and this one, so please read the release notes below carefully if you didn't progressively upgrade through the various MILESTONEs and RCs. (if you only care about what changed since RC1, please have a look at the RC2 release note)
The release notes below are written from the perspective of a migration from 3.0.x latest version and cover
changes across all the 3.1.0 pre-releases.
Note that since pre-release v3.1.0.M2
, the source code for the reactor-test
artifact is part of the reactor-core
github repository.
⚠️ Update considerations and deprecations
-
Reactor has been updated to pass the TCK of the new Reactive Streams specification
1.0.1.RC2
. A newStrictSubscriber
enforces RS rules more strictly when going out of the Reactor world and bridging to an externalPublisher
(#711) -
The
reactor-test
artifact is now part of theio.projectreactor
groupId (and reactor-core github repository) -
Kotlin extensions for core and test are now part of the
reactor-core
repo and artifacts -
behavioral changes
-
Flux/Mono method changes
ParallelFlux#subscribe(lambdas)
lambda-based variants now return aDisposable
(composite of all rails subscribers, #800)Flux#toIterable
now takes anint
for itsbatchSize
argument (f3e13bf)Mono.doOnTerminate
anddoAfterTerminate
now take a simpleRunnable
(aligning the API withFlux
). The olddoOnTerminate(BiConsumer<Throwable, T>)
can be achieved with the addeddoOnSuccessOrError
and olddoAfterTerminate(BiConsumer<Throwable, T>)
withdoAfterSuccessOrError(BiConsumer<Throwable, T>)
. (#836 + 80a3210)Flux.firstEmitting
is now calledfirst
andFlux.firstEmittingWith
is now calledor
, aligning APIs with those ofMono
(#849)- static
Mono.empty(Publisher<?>)
has been removed, prefer using the newMono.when(p)
(2e7fdf3) - buffer operators that take a
(Publisher, Function)
as arguments (open boundary and closing selector) have been renamed tobufferWhen
. This improves the situation where having multiple lambda-based signature can create ambiguity (even more so in languages like Kotlin) (#542) delay
inFlux
is removed in favor ofFlux.delayElements
(see #263)Mono#untilOther
removed (usedelayUntil(it -> other.take(1))
instead, see #558)
-
then:
- variants of
then
that took aSupplier
have been removed. Usedefer
if you really need to provide the continuationMono
lazily (#547) Flux.then(Publisher<Void>)
has been removed in favor ofthenEmpty
Mono.then(Function)
is nowMono.flatMap
- variants of
-
Mono zip vs when
zip
is the operator dedicated to producing Tuples (or equivalent combinations) of the elements from multiple sources.
As a consequence,when
andand
variants that produced aTuple
have now been renamedzip
andzipWith
(#789 + 52f7f04)when
andand
still exist, as operators in the same family asthen
: they only care about completion signals,
discarding elements and returning aMono<Void>
.Mono#zip
with an iterable: for consistency, swap the arguments (old "function, iterable" version is deprecated, see #619)zip(Iterable)
andzip(Function, Iterable)
inFlux
has been removed (#338, #619)
-
⚠️ Mono.then(Function)
andMono.flatMap()
: how to migrate (#516):- first replace all usage of
Mono.flatMap
withflatMapMany
- then replace all usage of
Mono.then(Function)
(which has been removed) withflatMap
. - the gist of this change is that the old
flatMap
was actually changing the return type toFlux
and was thus missing the "Many" suffix we usually use. At the same time,then(Function)
was transforming the source value (unlike any other form ofthen
which usually just ignore the emissions and act on the onComplete). Thus it was actually more of aflatMap
.
- first replace all usage of
-
error handling operators have been made more consistent between
Mono
andFlux
(#533, #535, #531)Flux
: onErrorResumeWith ->onErrorResume
, mapError ->onErrorMap
, switchOnError -> replace withonErrorResume
with a lambda that ignores the left hand side.Mono
: otherwise ->onErrorResume
, otherwiseReturn ->onErrorReturn
, otherwiseIfEmpty ->switchIfEmpty
, mapError ->onErrorMap
-
window:
- various window operators have been aligned in behavior with respect to cancellation (#384)
window
operators that take a(Publisher, Function)
as arguments (open boundary and closing selector) have been renamed towindowWhen
. This improves the situation where having multiple lambda-based signature can create ambiguity (even more so in languages like Kotlin) (#542)Flux.window()
has been removed in favor ofwindow(Publisher)
,windowUntil
andwindowWhile
(see #260)Flux.windowTimeOrSize
: the timeout now starts right from subscription, resulting in potentially empty windows being emitted. It also restarts if the
timeout expires, so there could be several empty windows emitted eg. 3 for a timeout of 100ms if the Flux doesn't emit for 300ms.
The equivalent buffer version remains unchanged. (#484)windowUntil
/windowWhile
haveFlux
windows instead ofGroupedFlux
(#759)
-
Cross operator changes based on prefix / parameter pattern:
- xxxMillis: Timed operators with the
Millis
suffix have been removed, use theirDuration
based counterparts xxx(boolean delayError)
: All operators that were taking adelayError
boolean parameter instead of having aDelayError
suffixed variant now use the suffix variant pattern (see #480)xxx(Function<Throwable, ?>)
: Operators dealing with aPredicate
orFunction
ofThrowable
have been aligned to take a more generic<? super Throwable>
- All
subscribe
methods inFlux
that had a prefetch parameter have been removed (you can uselimitRate
to achieve the same effect)
- xxxMillis: Timed operators with the
-
class changes
Signal
is now an interface andMutableNextSignal
has been removed (#779)- Old introspection interfaces, which were mostly only used internally, have been removed in favor of the single
Scannable
interface (Loopback, MultiProducer, MultiReceiver, Producer, Receiver, Trackable, see #249, 20bd64d) Cancellation
has been removed and replaced withDisposable
(see #322, 844769d)TimedScheduler
has been removed, as well as theScheduler#shutdown
method (most schedulers are now fully time capable and you can usedispose()
. The fewScheduler
that are not time-capable will throw aRejectedExecutionException
indicating so whenever one attempts to useschedulePeriodically
on them. Note that most timed operators now use theparallel()
Scheduler by default. (see #451, #322)- Review interrupted flag on dispose (#507)
- Removed fromExecutorService(exec, boolean) variant
- Removed factory hook for simple ExecutorService (now all Scheduled)
OpenHashSet
has been removed, as it was only used for Disposables: useDisposables.composite()
(40fbd60)QueueSupplier
has been renamed toQueues
and is now purely about queue-related utils and static suppliers. It doesn't implementSupplier<Queue>
itself anymore. (#733)
-
Hooks
Hooks
are now cumulative. Setting a hook will add it on top of the existing one(s). You can also name
some hooks, which allows to update a sub-hook or only partially reset a hook. (#687, #784)- new hooks
onEachOperator
+onLastOperator
, nowFunction<Publisher, Publisher>
, new operatorlift
(#775) - hooks must now be called with the
Context
(#830)
-
nullability
-
Processors have been reworked:
- You cannot connect explicitly anymore but should rather use the
sink()
method. For details and rationale, see #525. - Processors that are costly to instantiate (
TopicProcessor
,WorkQueueProcessor
) now have aBuilder
instead of
factory methods. However, they keep a couple of significant factory methods (see #471, #616 and #628) Mono#subscribe()
returns aDisposable
. Use.toProcessor()
to get the exact legacy behavior (see #566, #605 and #638)UnicastProcessor
won't ignore theoverflowStrategy
if we can detect that a bounded queue is used. By default, an unbounded queue is used and the strategy is silently ignored. (#612)DirectProcessor
andUnicastProcessor
now callonErrorDropped
andonNextDropped
if calling after terminate.Exceptions.argumentIsNullException()
has been removed (most of the time replaced byObjects.requireNonNull()
). (7f6ff86)- MonoProcessor cancel/dispose now signals
CancellationException
(#792)
- You cannot connect explicitly anymore but should rather use the
-
Some changes have been made to the way writing custom operators works
Operators.SubscriberAdapter
is not part of the public API anymore.Operators.addAndGet(AtomicLong, ...)
has been removed in favor of theAtomicLongFieldUpdater
alternative, itself renamed toaddCap
(#371)- Removed unused and confusing Operators.addAndGet (#371)
MonoSource
andFluxSource
are now package privat...