-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hardening automatic context propagation (#3549)
This change addresses Flux, Mono, and Publisher implementations that are implemented outside of reactor-core for the purposes of automatic restoration of ThreadLocal state from the Context. Arbitrary Flux, Mono, or raw Publisher implementations can deliver signals from any Thread they desire, with no need to use Scheduler-controlled Threads. The implementations in reactor-core, whenever they switch Threads or when they receive signals out-of-band (e.g. request(n)) restore the ThreadLocal state. Recently, factories for Flux and Mono creation from external sources, such as a raw Publisher, or Future implementations, have added guards via a dedicated ThreadLocal-restoring Subscriber to deal with signals from the sources that are not performing the restoration. However, custom Flux, Mono, and Publisher sources not wrapped via from() method can deliver signals without the ThreadLocal state restored. This is the case with reactor-netty's Flux implementation delivering signals from Netty's event loop. Also, while wrapping the sources obtained via Flux.from and Mono.from factories works fine, plenty of operators, such as flatMap, accept a raw Publisher and don't provide any guard against changing Thread, which means these operators need to be addressed. This change applies wrapping of either the Producer or Subscriber. It is driven by a Scannable flag on the Publisher. We do it in these scenarios: 1. Wrap the Publisher when we assemble an operator at runtime of another operator (flatMap for example). 2. Wrap the Subscriber at operators that allow the user to directly emit signals from a different Thread (Sinks for example). 3. Wrap the Subscriber when subscribe(Subscriber) from RS Publisher is called and the source is not protected. The following changes have been introduced: * Added an internal Scannable attribute: INTERNAL_PRODUCER, which allows determining if a Flux or Mono is a reactor-core implementation. * Reviewed Scannable implementations to report INTERNAL_PRODUCER properly for internal implementations. * Introduced new methods in Operators class, which allow wrapping the Subscriber with a context restoration guard whenever the Publisher is not an INTERNAL_PRODUCER and allow wrapping the Publisher directly by applying an operator that restores ThreadLocals when signals travel downstream. * In Flux, Mono, InternalFluxPublisher, InternalMonoPublisher, FluxFromMonoOperator, MonoFromFluxOperator, MonoFromPublisher, the subscribe(Subscriber) method from Publisher uses Subscriber wrapping as a last-resort chance to restore ThreadLocals. In case subscribe(CoreSubscriber) is used, we have no way to intercept it, as it is abstract, so we need other means of wrapping too. * Flux.from, Mono.from, Mono.fromDirect and their respective wrap() methods also apply the wrapping. * In operators which receive a Publisher from the user during runtime (for instance flatMap receives it as a return value of a lambda provided by the user), either Operators.toFluxOrMono is used or direct type wrapping when it is known what is expected. * Added plenty of tests that depict the issue for the identified cases that are able to accept a Publisher that can switch a Thread when delivering signals. Resolves #3478.
- Loading branch information
Showing
134 changed files
with
2,316 additions
and
751 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.