All Versions
33
Latest Version
Avg Release Cycle
37 days
Latest Release
84 days ago

Changelog History
Page 1

  • v3.4.1

    December 08, 2020

    ๐Ÿš€ Reactor-Core 3.4.1 is part of 2020.0.2 Release Train (Europium SR2).

    ๐Ÿ›  This service release contains bugfixes and new features.

    ๐Ÿš€ This note focuses on changes specific to this version, but all changes from 3.2.22.RELEASE and 3.3.12.RELEASE are also included.

    โšก๏ธ โš ๏ธ Update considerations and deprecations

    • ๐Ÿ›  fix #2459 Add a composite of all source as cause to firstWithValue error
      • this was overlooked when merging the new operator in 3.4.0, so we decided it was fresh enough that the slight behavior change would be acceptable

    ๐Ÿฑ โœจ New features and improvements

    • ๐Ÿ›  fix #2195 Add timed() operator
      • this new operator exposes various timing information on a Timed wrapper object, allowing richer output of Duration compared to elapsed() and timestamp() (which use Tuple2 and Long)
    • ๐Ÿ‘€ [reactor-test] fix #2269 Add test util to capture logs in early-established loggers (see also #2512)
      • LoggerUtils allows the early installation of a Logger factory that will forward to a classic factory AND let the user activate a logging indirection later on during tests
      • this allows a TestLogger to capture internal logs from operators that were classloaded earlier than the unit test
    • โœ… [reactor-test] fix #1518 Add cold variants of TestPublisher
      • cold variants better behave wrt backpressure and can replay to multiple subscribers at various stages
      • the old behavior (of ignoring requested amount) is still available through a createColdNonCompliant variant
    • โœ… [reactor-test] When asserting Context in StepVerifier, say from which operator the asserted Context was taken (#2518)

    ๐Ÿฑ ๐Ÿž Bug fixes

    • ๐Ÿ›  Make RetryWhenMainSubscriber#onError's calls serial (#2499, Fixes #2488)
    • ๐Ÿ›  fix #2513 ReplayProcessor now correctly pass nanos to buffer, not ms
    • ๐Ÿš€ from 3.3.12.RELEASE:
      • fix #2519 Cancel propagation on empty collectXxx
    • ๐Ÿš€ from 3.2..22.RELEASE:
      • fix #2498 Exception thrown in Flux.handle causes hanging in fused case

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • ๐Ÿ“š Various documentation improvements (#2463, #2457, #2469)
    • ๐Ÿ›  fix #2468 Review and polish deprecation suppressions
    • ๐Ÿ›  fix #2502 Generate OSGI Bundle-Version from Europium+ scheme

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @dowgiallom, @seants

  • v3.4.0

    October 27, 2020

    ๐Ÿš€ Reactor-Core 3.4.0 is part of 2020.0.0 Release Train (codename Europium).

    ๐Ÿš€ This is the first GA release of Europium ๐ŸŽ‰

    This note focuses on 3.4.0 proper, curating changes from across all milestones.
    ๐Ÿš€ Note that the 3.4.0 effort was started right after 3.3.5.RELEASE, so this version also contains changes from 3.3.6 to 3.3.11 (see the end of the notes for links).

    ๐Ÿฑ โš ๏ธ Known Issues

    • ๐Ÿ‘ป the firstWithValue new operator has an undocumented way of checking the cause of failure for individual sources, but it uses a suppressed exception rather than a cause. Please refrain from using that, as we'll switch to initCause in 3.4.1 (and properly document the behavior, setting it in stone) => #2459

    โšก๏ธ โš ๏ธ Update considerations

    ๐Ÿฑ โš ๏ธ ๐Ÿ—‘๏ธ Removals

    • โฑ Schedulers deprecated back in 3.3 have been removed (WorkQueueProcessor and TopicProcessor, #2208)
    • ๐Ÿ‘€ Previously deprecated methods and types have been removed (see #2277)

    ๐Ÿฑ โš ๏ธ โŒ› Deprecations

    • โฑ Schedulers.elastic() and variants are deprecated, to be removed in 3.5 (#1893)
    • ๐Ÿšš FluxProcessor (as well as all concrete implementations of it) are now deprecated and will be removed in 3.5 (#2188, #2431)
      • see the main focus section below for more details
    • ๐Ÿšš [api-change] MonoProcessor is made abstract and deprecated, to be removed in 3.5 (#2188, #1053 / f04bede, #2431)
      • see the main focus section below for more details
    • ๐Ÿšš Flux.subscribe(Consumer<Subscription>) variant is deprecated, to be removed in 3.5 (#1825)
    • ๐Ÿšฆ first is deprecated to be renamed to firstWithSignal (see firstWithValue in the new features below). The old deprecated method will be removed in 3.5 (#2173)
    • Context changes (#2282):
      • Operators exposing the Context at points where there is no use attempting to use write methods are deprecated and will be removed in 3.5 (#2293, 7d6c862)
      • these all receive a ContextView-based variant (see new features below)
      • deferWithContext => deferContextual with a ContextView
      • Signal.getContext() => Signal.getContextView()
      • Operators modifying the Context are renamed to be clearer. Old names are deprecated and will be removed in 3.5 (see new feature below, #2148, eed93d6)

    ๐Ÿฑ โš ๏ธ โ™ป๏ธ Behavior Changes

    • Most operators that take a Duration and convert it to milliseconds now use nanosecond precision (#1734)
    • ๐Ÿ”Š Operators.onErrorDropped no longer throws, but only logs the dropped exception (#1431)
    • ๐Ÿšฆ When an onError signal reaches the last (lambda based) subscriber in a chain which doesn't have an error handler, the exception is no longer thrown but only logged (#2176)
    • โฑ Vanilla implementations of Scheduler now initiate their backing infrastructure and apply Schedulers decorator in start() rather than the constructor (#1778)
      • start() is also now implicitly called when instantiating a Scheduler via the Schedulers.Factory
      • Allows to avoid this leaking from constructor
      • โš ๏ธ Custom implementations should similarly initialized and optionally decorate in start()
    • EmitterProcessor with a full backpressure queue no longer blocks until data is requested, but fails fast (#2049)
    • Metrics changes
      • Change in how metric meters/tags are named in accordance with the name operator (#1928, #2302)
      • flow tag has been removed entirely
      • using the name({String}) operator will replace reactor. prefix in meter names with the user-provided {String}.
      • โš ๏ธ using custom tags via the tags(String...) operator, but not name(String) still creates a sparse set of tags in the application which could be rejected by some metrics backend
      • Change name of some meters that used to include (redundant) unit names (#1807)
      • reactor_requested_requested_amount => {name}_requested
      • reactor_subscribed_subscribers => {name}_subscribed
      • notice these meters also take the user-provided {name} into account from the above change
      • Differentiate empty vs valued sequences in metrics via the status tag, introducing completedEmpty value (#1803)

    ๐Ÿฑ โš ๏ธ โœจ Main focus: Sinks

    ๐Ÿ—„ Sinks are a new API constructed to replace the FluxProcessor and MonoProcessor APIs, which have been deprecated (#2431, #1053).

    We distinguish Sinks.Many<T> (a Flux-like sink), Sinks.One<T> (a Mono-like sink) and Sinks.Empty (a Mono<Void>-like sink).

    These sinks are constructed through specs under the Sinks class. They expose a two-faced API:

    • methods starting with tryEmit are atomic, never throw (#2319, #2329, #2336, #2426) and immediately return an EmitResult enum (originally named Emission) indicating various variations of success or error (#2319, #2338)
    • 0๏ธโƒฃ methods starting with emit attempt to provide an easier facade over the above, take an EmitFailureHandler allowing to fine tune some aspects of the default behavior (#2377)

    0๏ธโƒฃ By default, the instances are "serialized", detecting parallel usage and failing fast in tryEmit (#2342, #2410, #2365, 19fc1ba, #2412).
    The vanilla reactor sink implementations of emit API terminate with the equivalent of an emitError when parallel usage is detected (#2365) but by using the EmitFailureHandler to drive the sink to retry, possibly with a small amount of sleeping, it should be possible to optimistically get rid of the contention.

    It is also possible to get a low-overhead, low-protection instance of vanilla sinks by using the Sinks.unsafe() spec (#2418).
    This doesn't detect parallel usage, so it must be used in a responsible way (in a context where the Reactive Streams contract is already externally enforced).

    Sinks also expose a asFlux() view (or asMono(), as relevant) for them to be passed to downstream and subscribed, and also expose a bit of state through currentSubscriberCount() getter (#2372) and by being Scannable (at a minimum for TERMINATED and CANCELLED attributes, #2394).

    Compared to existing processors, most flavors have a sink equivalent except DirectProcessor, with two close cousins under Sinks.many().multicast() (#2392, #2451):

    • directAllOrNothing will ignore tryEmitNext attempts when at least one subscriber doesn't have enough demand,
    • directBestEffort will instead push to the subset of subscribers with demand and drop from the perspective of slow subscribers.

    ๐Ÿ‘€ This differs from DirectProcessor in the sense that both these sinks are kept open in such a situation, so slow subscribers that increase their request will start seeing values pushed after that (instead of being immediately terminated in DirectProcessor).

    There is also a new flavor: an onBackpressureError() variant of the unicast Sink (#2347)

    ๐Ÿ›  ๐Ÿž Bugfixes

    ๐Ÿš€ See links to Dysprosium releases (3.3.6 to 3.3.11) at the end.

    ๐Ÿฑ โœจ New features

    • concatMap now has a variant with 0 prefetch (#2202)
    • ๐Ÿ’… All Scannable operators answer the new Attr.RUN_STYLE attribute with a RunStyle enum (#2058, #2123)
      • the enum allows to identify operators that run synchronously. Attribute is accessible both at Publisher and Subscriber level
      • RunStyle.SYNC guarantees the operator doesn't change threads
      • RunStyle.ASYNC indicates the operator MAY change threads
      • RunStyle.UNKNOWN (the default) indicates there's no available information (eg. due to the operator wrapping an arbitrary Publisher)
    • ๐Ÿ”ง A Reactor-wide Micrometer MetricsRegistry other than the global one can now be configured (#2253, 64fd556)
      • Use Metrics.MicrometerConfiguration#useRegistry for that purpose
      • The above will attempt to load Micrometer classes, so Micrometer MUST be on the classpath
    • ๐Ÿ†• New reactive context features (#2282):
      • Context now extends a simplified ContextView API which only expose the read methods (#2279, #2293)
      • the goal is to avoid exposing a seemingly writable (copy-on-write) Context when the only meaningful operations are read operations
      • exposed in Signal#getContextView(), deferContextual operator (variant to deferWithContext) and new transformDeferredContextual operator
      • Added transformDeferredContextual operator that takes a BiFunction, allowing to access the ContextView in the transformation (#2280 then renamed in #2293)
      • Mono.subscribe(valueConsumer, errorConsumer, ...) error Consumer now gets notified of exceptions thrown by the value Consumer (#1995)
      • Renamed Context operators with clearer names (#2148, eed93d6)
      • Mono.subscriberContext() is not aliased, we now advise to use Mono.deferContextual(Mono::just) to get the exact same behavior
      • subscriberContext(Context) is replaced by contextWrite(ContextView) (notice the use of ContextView)
      • subscriberContext(Function) is replaced by contextWrite(Function)
    • โž• Added method to snapshot factory+global schedulers (#2325, #2326, f9c7993)
      • use Schedulers.setFactoryWithSnapshot(Factory) to get a Snapshot object while replacing the Factory
      • reset the old factory by using resetFrom(Snapshot)
      • this is used by the reactor-test VirtualTimeScheduler to reset previously customized factories
    • The ParallelFlux.subscribe(array) method is now public to allow delegation in wrappers (#2328)
    • ๐Ÿšฆ The Retry object driving #retryWhen operator can now store user-provided state in the form of a ContextView, which is exposed through RetrySignal (#2312, bd8db8a)
    • The GroupedFlux#key() method is now marked as @NonNull (#2397)
    • โž• Added firstWithValue factory operator (#2173, 41c937f)
      • like first, it let multiple sources compete
      • except it prioritizes valued sources: empty sources are considered irrelevant
      • if no source completes with a value, a NoSuchElementException is thrown

    ๐Ÿ“ˆ Improvements

    • Have push(emitter) delegate to push(emitter, backpressure) (#2177)
    • ๐Ÿ‘ป Lazily instantiate exception in Mono#repeatWhenEmpty (#2221)
    • ๐ŸŒฒ log() will log context access at FINE(ST) level and now uses the more correct currentContext prefix (#2220)
    • Mono#materialize() now takes into account that the source IS a Mono, so it doesn't cancel() it when materializing its onNext (#2424, 765bfe8)
      • this could be considered a behavior change, but the previous behavior was unnecessary. cancelling the result of the materialization still propagates to the source.

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • [doc] fix #2170 Make parallel runOn methods doc consistent about work stealing
    • [doc] Document Android 21 desugaring options (#2232)
    • ๐Ÿ— [build] #2237 remove most compilation warnings
    • [doc] fix #2136 Turn discard/errorMode javadoc tags into plain paragraphs
    • ๐Ÿ— [build] fix #2400 use a different name for the jcstress jar
    • ๐Ÿ— [build] Remove compilation warnings related to jsr305 (85da74b)

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @AayushyaVajpayee, @camsteffen, @cnabro, @hamidshahid, @Inego, @jonenst, @josemalonsom, @OlegDokuka, @robotmrv, @seants, @smaldini, @steppedreckoner, @yschimke

    ๐Ÿš€ All changes from these releases have been forward-merged into 3.4.0:

  • v3.4.0-RC2

    October 12, 2020

    ๐Ÿš€ Reactor-Core 3.4.0-RC2 is part of 2020.0.0-RC2 Release Train (codename Europium).

    ๐Ÿš€ This second Release Candidate brings further changes to the Sinks API introduced in M2 and polished in RC1.

    ๐Ÿš€ This release note contains all the changes specific to RC2, as well as some forwarded changes that will be released in 3.3.11.RELEASE.

    โšก๏ธ โš ๏ธ Update considerations and deprecations

    • Rework Sinks specs to put unsafe() at root level (#2418)
    • ๐Ÿ“‡ Rename Emission to EmitResult (#2426)
    • โœ‚ Remove deprecated emit API (#2377)
    • ๐Ÿ—„ Deprecate [Flux|Mono]Processor contracts entirely (#2431)

    ๐Ÿฑ โœจ New features and improvements

    • โž• Add emitXxx(EmitFailureHandler) Sinks API (#2377)
    • โž• Add firstWithValue operator, alias/deprecate first (#2173)
    • VoidProcessor is now a pure empty sink (#2408)
    • โž• Add serialized wrappers for Sinks.Empty/Sinks.One (#2410)
    • โž• Add currentSubscriberCount() to Sinks.Many|One|Empty (#2372)
    • ๐Ÿ‘‰ Make sinks scannable for TERMINATED (and CANCELLED) (#2394)
    • โž• Add directAllOrNothing/directBestEffort multicast Sinks (#2392)
    • ๐Ÿ”„ Change GroupedFlux#key to @NonNull (#2397)

    ๐Ÿฑ ๐Ÿž Bug fixes

    • ๐Ÿ›  Fix concurrent terminal signal detection in SerializedManySink (#2412)
    • ๐Ÿ›  Fix potential integer overflow on BoundedElasticScheduler constructor (#2389)

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • correct marbles for transformDeferred (#2358)
    • ๐Ÿ›  fix windowWithBoundary marble diagram (#2346)
    • ๐Ÿ—„ Don't blanket hide deprecated members in javadoc (#2416)
    • โฌ†๏ธ Bump jcstress-gradle-plugin to natively fix jar classifier (#2429)
    • ๐Ÿ‘‰ use a different name for the jcstress jar (#2400)
    • ๐Ÿ’… [polish] Increase timeout duration to 1ms to avoid hiccups
    • ๐Ÿ’… [build] Polish granularity of stacks for Nested tests
    • ๐Ÿ’… [polish] StressSubscriber generified, track onSubscribe, initRequest
    • ๐Ÿ’… [doc] Polish Sinks doc accounting for RC1 and RC2 latest changes (#2414)
    • ๐Ÿ’… [test] Polish tests that use nano durations to avoid flakkyness (#2421)

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @camsteffen @yosfik

  • v3.4.0-RC1

    September 15, 2020

    ๐Ÿš€ Reactor-Core 3.4.0.-RC1 is part of 2020.0.0-RC1 Release Train (codename Europium).

    ๐Ÿš€ This first Release Candidate brings further changes to the Sinks API introduced in M2

    ๐Ÿš€ This release note focuses on RC1-specific changes, but RC1 also contains all the changes released in 3.2.20.RELEASE and 3.3.10.RELEASE.

    โšก๏ธ โš ๏ธ Update considerations and deprecations

    โšก๏ธ Processors and sinks update considerations

    ๐Ÿšฆ The most impactful change is the switch in focus from an API that emulates Subscriber (with void return types) to a lower level API that can consistently provide immediate feedback to a signalling attempt via the returned Emission. Now the later is prefixed with tryEmit. An emit API is offered as an initial problematic attempt at a higher level abstraction, but it had to be @Deprecated. See #2374 for potential ways to rewrite code that used to call onNext/next/emitNext-without-checking-returned-Emission in previous versions.

    @simonbasle is also preparing a retrospective write up of all the changes through which the sinks API went in #2382.

    emitXxx replaced with tryEmitXxx

    • ๐Ÿ‘€ See #2319 : Split emitXxx/tryEmitXxx, more consistent use of hooks.

    ๐Ÿ†• new Emission.FAIL_xxx error codes

    • Emission.FAIL_NON_SERIALIZED (see #2342 Failing fast on non-serialized access to Sink)
    • Emission.FAIL_ZERO_SUBSCRIBER (see #2338 Add new Emission FAIL_ZERO_SUBSCRIBER error code)

    "safe" onBackpressureError() not exposed anymore

    • ๐Ÿ‘€ See #2375 : Remove Sinks.many().multicast().onBackpressureError().

    ๐Ÿšš emitXxx part of the API to be removed / heavily reworked

    • ๐Ÿ‘€ See #2374 : Deprecate Sinks emit{Next,Error,Complete} methods.

    ๐Ÿฑ ๐Ÿž Bug fixes

    • These are incremental improvements over the tryEmitNext API (previously emitNext in M2):
      • Handle ASYNC fusion in EmitterProcessor#onNext rather than emitNext (#2316)
      • #2330 Ensure we never throw from tryEmitNext (#2336)
      • #2342 Failing fast on non-serialized access to Sink (#2365)

    ๐Ÿฑ โœจ New features and improvements

    • #2312 Add user provided state to Retry
    • โฑ #2325 Add method to snapshot factory+global schedulers, used by VTS (#2326)
    • #2328 Make ParallelFlux.subscribe(array) public to allow delegation
    • Sinks related improvements over M2:
      • #2329 Improve Emission API: polish status helpers, add orThrow()
      • #2338 Add new Emission FAIL_ZERO_SUBSCRIBER error code
      • Add onBackpressureError() variant of the unicast Sink (#2347, #2367)
    • ๐Ÿ’… [Polish] Add inners[] param to Operators dropMulticast private methods

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • [doc] As the custom javadoc tags are not displayed in all IDEs, turned discard/errorMode javadoc tags into plain paragraphs (#2136)
    • ๐Ÿ— [build] #2353 Use api for reactive streams api dependency import
    • โœ๏ธ several typos and inconsistencies fixed by various contributors
    • ๐Ÿ—„ [doc] #2317 Add examples to deprecation notes of processors
    • โœ… [test] Avoid potential infinite busy looping in tests
    • ๐Ÿ’… [doc] Polish javadoc of the multicast onBackpressureBuffer Sinks (#2373)
    • ๐Ÿ’… [doc] Polish variable names in snippet (#2351)

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @hamidshahid, @steppedreckoner

  • v3.4.0-M2

    August 11, 2020

    ๐Ÿš€ Reactor-Core 3.4.0.-M2 is part of 2020.0.0-M2 Release Train (codename Europium).

    This second milestone brings several important changes:

    • further evolution of the way processors and sinks are obtained and used (following up on the changes initiated in M1)
    • ๐Ÿ‘Œ improvements of the Context related APIs
    • ๐Ÿ‘Œ improvements on the Flux and Mono metrics

    ๐Ÿš€ This release note focuses on M2-specific changes, but M2 also contains all the changes released in 3.2.19.RELEASE, 3.3.8.RELEASE and 3.3.9.RELEASE.

    โšก๏ธ โš ๏ธ Update considerations and deprecations

    โšก๏ธ Metrics update considerations

    ๐Ÿท The name() operator is no longer used in metrics as a tag but as a prefix for the meter names (#1928):

    This allows to use custom tags via the tag() operator, while ensuring unique enough meter names that all bear the same set of tags

    The [name].flow.duration meter has a status tag that now differentiate between completed and completedEmpty (#2313)

    โšก๏ธ This allows to detect eg. empty Monos, but code relying on the completed status should be updated to also take completedEmpty into account.

    The [name].subscribed and [name].requested meters have had their unit dropped (#1807):

    ๐Ÿ›  The unit is part of the name in some backends like prometheus, but the unit was redundant. So the requested amount and subscribers unit suffixes have been dropped (separator may vary depending on the metrics backend).

    โšก๏ธ Processors and sinks update considerations

    The FluxIdentityProcessor and Processors classes that were introduced in M1 have been rolled back, and Sinks reworked (#2218)

    ๐Ÿšš The ultimate goal is to remove the need for processors (or greatly diminish it) and adding processor-related APIs was deemed counterproductive...

    The sinks from operators (FluxSinks and MonoSink in create) no longer have a common interface with the "standalone" sinks. The hierarchy has been simplified and we now have 4 uncorrelated interfaces: FluxSink and MonoSink (back to what they were in 3.3, oriented towards subscription-like usage) versus Sinks.One and Sinks.Many (both oriented towards publisher-like usage).

    ๐Ÿ— Sinks allow building the later two, with a tiered approach:

    1. chose many() vs one() vs empty()
    2. Then on many(), chose a flavor (unicast(), multicast(), replay())
    3. Finally, fine tune the flavor to obtain a sink (eg. Sinks.many().multicast().onBackpressureError())

    These can also be converted to processors efficiently, as their (private) implementation also implement FluxProcessor/MonoProcessor. NB: to convert from a Sinks.Many/Sinks.One to a processor where a processor is still relevant, use FluxProcessor.fromSink and MonoProcessor.fromSink.

    The MonoProcessor class used to be concrete but final. It is now abstract (#1053, #2296)

    ๐Ÿšฆ Most of its implementation has been moved to package-private NextProcessor. This will allow to introduce more flavors of MonoProcessor, focusing that class on signaling a Processor<A, B> that is also a Mono<B>.

    A new flavor VoidProcessor, has been also immediately added. It backs Sinks.empty() with less overhead than the old MonoProcessor.

    Sinks.Many and Sinks.One APIs

    Contrary to operator sinks, these two sinks are to be used more like publisher than like subscribers.

    That is to say, they are expected to be passed down asFlux() or asMono(), so generally should accommodate multiple subscribers (except for Sinks.many().unicast()).

    As a result they expose a different and more restrained API. Most relevant methods are the emitXxx methods, which are not fluent but return an Emission enum.
    ๐Ÿ‘€ They can be seen as a "best effort" API, indicating failure through the enum rather than an exception (comparable to Queue#offer vs Queue#add in the JDK).

    ๐Ÿฑ โš ๏ธ Consequently, the Emission enum should be checked to detect error cases.

    ๐Ÿ”ง For instance, the EmitterProcessor used to sleep when its configured buffer was full and users continued trying to emit, effectively busy-looping until the internal queue would accept the pushed valued. This is effectively blocking, and can be problematic (#2049).

    The equivalent sink, Sinks.many().multicast().onBackpressureBuffer(), doesn't sleep/block but immediately returns Emission.FAIL_OVERFLOW.

    Note that to get the old behavior, one can manually loop on the emitNext attempt until it returns Emission.OK, sleeping for a few nanoseconds when it returns FAIL_OVERFLOW. But caller could also decide to fail after a number of retries rather than an infinite loop for instance...

    Context APIs

    ContextView introduction (#2279)

    Knowing when a Context can be "written" vs when it cannot is complicated by the fact that operators that aim at exposing the contextual data only for reading still expose the full Context API, with write methods.

    In M2, we introduce ContextView, a superinterface to Context that only bears the read methods of the context.

    ๐Ÿšš Operators that expose the context for the purpose of reading from it (and where trying to put or remove data would effectively be a no-op) now have an alternative exposing the ContextView, deprecating the old way:

    • deferWithContext(Function<Context, P>) is superseded by deferContextual(Function<ContextView, P>)
    • we introduce transformDeferredContextual(BiFunction<P1, ContextView, P2>)
    • ๐Ÿšฆ Signal#getContext() is superseded by Signal#getContextView()
    • ๐Ÿ—„ Mono.subscriberContext() is deprecated. No replacement is planned as deferContextual(Mono::just) is a readily available replacement.

    A Context is already a ContextView. In case an API presents a ContextView but one really need a Context instead, use Context.of(ContextView).

    ๐Ÿ‘Œ Improve naming of context operators (#2148)

    ๐Ÿ—„ In 3.3, context operators are a bit confusing since they're only differentiated by their inputs. In 3.4 we deprecate these confusing names and provide alternatives:

    • ๐Ÿšš Mono.subscriberContext() is to be removed. Use Mono.deferContextual(Mono::just) instead, or even better try to rewrite the code to fully utilize the capacities of deferContextual and transformDeferredContextual operators (which could allow reading from the ContextView only once).
    • โž• subscriberContext(Context) is superseded by contextWrite(ContextView) (which better conveys that the entries in the input are added to the current Context)
    • subscriberContext(Function<Context, Context>) is superseded by contextWrite(Function<Context, Context>)

    โšก๏ธ Other update considerations

    • ๐Ÿšš Methods and classes deprecated in 3.3 have been removed (#2277)
      • to help with the retryWhen migration from legacy throwable-based function, a second adapter has been added (in both M2 and 3.3 latest release): Retry.withThrowable(Function<Flux<Throwable>, Publisher<?>>)
    • ๐Ÿ—„ subscribe(..., Consumer<Subscription>) variant has been deprecated (#1825):
      • too often, people misuse it to capture or log the Subscription but forget to request it, resulting in hangs
    • Mono.subscribe(valueHandler, errorHandler) now passed errors in the valueHandler to the errorHandler (#1995)
    • โฑ All instances of Scheduler are now expected to require start() call before usage (#1789)
      • the impact is limited as Schedulers.Factory-produced instances are started automatically by Schedulers factory methods (eg. Schedulers.parallel() or even Schedulers.newBoundedElastic())
    • ๐Ÿšฆ when encountering onError signal AFTER onComplete/onError, operators will now default to only logging the extraneous Throwable (#1431)
      • Same with a sequence that is subscribe without a error handler (#2176).
      • This can be tuned by setting a Hooks.onErrorDropped. The old behavior of throwing would cause issues and used to break the rules of Reactive Streams
    • All operators that take a Duration now do their best to deal with it in nanosecond precision (#1734)
      • However this means that the maximum interpretable Duration is now Duration.ofNanos(Long.MAX_VALUE) (down from ofMillis(Long.MAX_VALUE). This leaves us with 296 years as the maximum duration, which should be enough for all intents and purposes...
    • โฑ Schedulers.newElastic and Schedulers.elastic() are now deprecated, to be removed in 3.5

    ๐Ÿฑ โœจ New features and improvements

    • ๐Ÿ›  fix #2253 redesign how MetricsRegistry is configured: one can now centrally chose the registry to use instead of micrometer's globalRegistry
    • ๐Ÿ›  fix #2058 identify operators with scheduler through new scannable property (#2123)
    • ๐Ÿ‘ Allow "0" prefetch value in concatMap (#2202)
    • ๐Ÿ›  fix #2220 Log context access in FINE(ST) level and with correct prefix
    • ๐Ÿ‘ป Lazily instantiate exception in Mono#repeatWhenEmpty (#2221)

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • ๐Ÿ“š various cleanups in code, documentation, tests and build
    • [doc] Document Android 21 desugaring options (#2232)

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @cnabro, @OlegDokuka, @seants, @yschimke, @robotmrv

  • v3.4.0-M1

    July 01, 2020

    ๐Ÿš€ Reactor-Core 3.4.0-M1 is the first MILESTONE in the 2020.0.0-M1 Release Train (codename Europium).

    ๐Ÿš€ Note that in terms of content this milestone is also aligned with what was released in 3.3.7.RELEASE

    โšก๏ธ โš ๏ธ Update considerations and deprecations

    • ๐Ÿ—„ Introduce Sinks and deprecate concrete processors (#2188)
      • more detailed migration notes to come
    • โฑ Deprecate Schedulers.elastic for 3.5 removal (#1893)
      • This further enforces the use of the boundedElastic flavor
    • โœ‚ Remove schedulers deprecated in 3.3 (#2208)

    ๐Ÿฑ โœจ New features and improvements

    • ๐Ÿ– Handle nulls from collectors in Flux.collect() (#2181)
    • Have push(emitter) delegate to push(emitter, backpressure) (#2177)
    • Align implementations of MonoCollect to be comparable to MonoCollectList (#2186)
    • โฌ†๏ธ Bump the perf baseline to 3.3.6

    ๐Ÿฑ ๐Ÿž Bug fixes

    • ๐Ÿ›  Fix input package rule for OSGi metadata generator (#2185)

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • ๐Ÿ— [build] master is 3.4 Europium, introduce new versioning scheme (#2140)
    • ๐Ÿ— [build] Ensure tools fat jar is the one published (#2189)
    • [doc] Make ParallelFlux runOn methods doc consistent about work stealing (#2170)
    • [doc] Fix 'decided' typo in coreFeatures.adoc (#2174)

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @jonenst , @rstoyanchev , @Inego , @gurkerl83

  • v3.3.12.RELEASE

    December 08, 2020

    ๐Ÿš€ Reactor-Core 3.3.12.RELEASE is part of Dysprosium-SR15 Release Train.

    ๐Ÿ›  This service release contains a couple bugfixes and documentation polishing.

    ๐Ÿš€ This note focuses on changes specific to this version, but all changes from 3.2.22.RELEASE are also included.

    ๐Ÿฑ ๐Ÿž Bug fixes

    • ๐Ÿ›  fix #2519 Cancel propagation on empty collectXxx
    • ๐Ÿš€ from 3.2.22.RELEASE:
      • fix #2498 Exception thrown in Flux.handle causes hanging in fused case

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • ๐Ÿ›  The Mono contract was not sufficiently and explicitly stated in the docs, this has been fixed (#2481)
    • ๐Ÿšš Effort around test tooling: switch to JUnit5, remove JUnit4, switch to AssertJ (#2442, #2465, #2467, #2491)
    • ๐Ÿ‘Œ Improvements to the javadoc/marble diagrams (#2413, #2289, #2200, #2483, #2509, #2504
    • ๐Ÿ‘Œ Improvements to the reference guide:
      • Mention the current latest BOM in the "how to get Reactor" section (#2470)
      • Added a section on how to read marble diagrams (appendix B, #2314)
    • โฌ†๏ธ Bump to latest generation of plugins for asciidoctor (#2510) + allow forcing rendering of pdf reference guide (97f4e4e)

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @BilliAlpha

  • v3.3.11.RELEASE

    October 26, 2020

    ๐Ÿš€ Reactor-Core 3.3.11.RELEASE is part of Dysprosium-SR13 Release Train.

    โšก๏ธ This is a recommended update for all Reactor 3 users.

    ๐Ÿš€ This release also contains all changes available in 3.2.21.RELEASE

    ๐Ÿฑ ๐Ÿž Bug fixes

    • ๐Ÿ›  fix #2389 Potential integer overflow on BoundedElasticScheduler constructor

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • ๐Ÿ›  fix #2416 Don't blanket hide deprecated members in javadoc
    • ๐Ÿ›  fix #2358 correct marbles for transformDeferred
    • โฑ [test] Fix flakky boundedElasticScheduler test (#2425)
    • โœ… [test] #2437 migrate tests to junit5

    ๐Ÿš€ ๐Ÿ‘ Thanks to the following contributors that also participated to this release

    @yosfik

  • v3.3.10.RELEASE

    September 15, 2020

    ๐Ÿš€ Reactor-Core 3.3.10.RELEASE is part of Dysprosium-SR12 Release Train.

    ๐Ÿš€ This maintenance release contains one small enhancement to DirectProcessor/EmitterProcessor.

    ๐Ÿš€ This version also contains all changes from v3.2.20.RELEASE.

    ๐Ÿฑ ๐Ÿž Bug fixes

    • #2356 Have Direct/EmitterProcessor implement currentContext()

    ๐Ÿ“š ๐Ÿ“– Documentation, Tests and Build

    • ๐Ÿ— [build] #2308 align reactor-tools test output with others projects
  • v3.3.9.RELEASE

    August 10, 2020