-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf(client): share replay of computed observables (#1095)
Adds `shareReplay` to computed observables which when previously subscribed to by multiple components would be evaluated separately, i.e., each source data emission would evaluate defined pipeline for each subscription individually. "Futureproofs" `RxUtils.getCurrentValue` method through usage of `combineLatest` function which will always take the last emitted value even from "pure" observables unlike `take` operator which "resolves" with first emitted value. Fixes `noop` sorting (\w) test where "sort" mutates source data - when we move to TS5.2 we should replace that with `Array.toSorted`. ### Implementation notes I mentioned using `share` operator which uses `refCount` and `Subject` under the hood meaning that if amount of subscriptions on such observable reaches 0 (refCount === 0) - it resets the `Subject` and re-evaluates the pipeline and assignes new value on next subscription. Using it in our SDK proved to be difficult and was behaving unexpectedly (broke tests and certain observables would return "undefined" instead of initial values) though on paper it makes perfect sense. I opted to use `shareReplay` which by default (with only buffer size as argument) works like a `ReplaySubject` but continues running defined pipeline (never unsubscribes from the source observable) even after the `refCount` reached zero. With the overloaded variant `shareReplay({ bufferSize: 1, refCount: true })` it behaves just as expected and does not break our SDK - meaning the values (pipelines) are being computed only once per multiple subscriptions and only if it has at least one subscription. ### Sources: - [difference between `share` and `shareReplay` operators](https://www.bitovi.com/blog/always-know-when-to-use-share-vs.-sharereplay) - though I found a discrepancy in the post - they mention that the `shareReplay` with `refCount` does not re-evaluate source observable but through my testing I found that to be false (yet it does something differently under the hood) - [`shareReplay` operator](https://rxjs.dev/api/index/function/shareReplay) - [`share` operator](https://rxjs.dev/api/index/function/share) --------- Co-authored-by: Oliver Lazoroski <[email protected]>
- Loading branch information
1 parent
a253cbf
commit 759d9a2
Showing
6 changed files
with
22 additions
and
15 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