Suggested replacements for deprecated multicasting operators do not behave equivalently
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 31.7k
- Forks
- 3k
- PR merge metrics
- No merged PRs in 30d
Description
Bug Report
Current Behavior
The replacements suggested for the deprecated multicasting operators in the migration guide https://rxjs.dev/deprecations/multicasting and on the individual operator pages do not behave exactly like the deprecated operators. For the publishReplay case a detailed discussion is here: https://github.com/ReactiveX/rxjs/discussions/6438, but this issue is not limited to publishReplay.
Expected behavior
Using a suggested replacement behaves exactly like the replaced operators or it is documented explicitly when they don't (and maybe also why they shouldn't).
Reproduction
(leaving out imports for brevity)
const tick$ = timer(1_000).pipe(
publishReplay(1),
refCount()
);
does not behave equivalently to the suggested refactor:
const tick$ = timer(1_000).pipe(
share({
connector: () => new ReplaySubject(1),
resetOnError: false,
resetOnComplete: false,
resetOnRefCountZero: false,
})
);
demo: https://codesandbox.io/s/frosty-sun-2tv3h?file=/src/index.ts
a truly equivalent replacement would be:
const tick$ = timer(1_000).pipe(
(source$) => {
const subject = new ReplaySubject(1);
return source$.pipe(
share({
connector: () => subject,
resetOnError: false,
resetOnComplete: false,
resetOnRefCountZero: true,
}),
);
}
);
or if the suggested releaseConnectorOnRefCountZero config option is introduced:
const tick$ = timer(1_000).pipe(
share({
connector: () => new ReplaySubject(1),
resetOnError: false,
resetOnComplete: false,
resetOnRefCountZero: true,
releaseConnectorOnRefCountZero: false,
})
);
Environment
- Runtime: any
- RxJS version: 7
Possible Solution
- Change or extend the migration guide to include truly equivalent replacements or at least document the changed behaviors.
- Parameterize the test cases of deprecated operators to execute them with the suggested replacements
- Introduce a new option to
ShareConfig(and maybe alsoConnectableConfig&ConnectConfig):releaseConnectorOnRefCountZero: boolean | (() => ObservableInput<any>) = true. this will be used to control if and when to create a new connector, when no one is subscribed anymore. a memory-optimal time-based caching behavior on cold sources can then be achieved by:const tick$ = timer(1_000).pipe( share({ connector: () => new ReplaySubject(1), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: true, releaseConnectorOnRefCountZero: () => timer(5000), }), );
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the multicasting migration guide at rxjs.dev/deprecations/multicasting and the individual operator pages, then review discussion #6438 and the deprecated-operator test cases. Compare each suggested replacement with the deprecated operator's behavior, especially publishReplay and share configuration. Done means the replacements are equivalent or their differences and rationale are documented, with tests covering the comparisons.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, documentation
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100