WarmObservable 1.0.0-beta3

This is a prerelease version of WarmObservable.
dotnet add package WarmObservable --version 1.0.0-beta3                
NuGet\Install-Package WarmObservable -Version 1.0.0-beta3                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WarmObservable" Version="1.0.0-beta3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add WarmObservable --version 1.0.0-beta3                
#r "nuget: WarmObservable, 1.0.0-beta3"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install WarmObservable as a Cake Addin
#addin nuget:?package=WarmObservable&version=1.0.0-beta3&prerelease

// Install WarmObservable as a Cake Tool
#tool nuget:?package=WarmObservable&version=1.0.0-beta3&prerelease                

WarmObservable

A library for combining a cold observable and a hot observable of the same source.

Main use case

You have a database that you can:

  • query for Thing rows where Thing.Color is red
  • subscribe to database notifications for new Thing rows where Thing.Color is red

WarmObservable allows you to combine these two sources of data into a single observable. The cold observable is used to populate the initial state of the observable, and the hot observable is used to update the observable with new data.

Subtle but compelling feature:

WarmObservable instances account for the race condition between the cold and hot observables.

Let's say your cold observable emits existing Thing rows A, B, and C. Then your hot observable emits the new Thing row D. If you were to simply use cold.Merge(hot), any Thing rows inserted between the time the cold observable emits and the hot observable emits would be lost. Conversely, if you were to use hot.Merge(cold), any Thing rows inserted between the time the hot observable emits and the cold observable emits would be duplicated.

WarmObservables account for this by merging the hot and cold observables, but only emitting distinct Thing rows. You may be thinking that behaviour could easily be implemented with hot.Merge(cold).Distinct(). You would be right! However, Distinct() works by keeping a HashSet of all the items it has seen so far. Over time the HashSet will contain all the Thing rows ever emitted by the observable (minus duplicates of course). WarmObservable uses a HashSet internally, but it bypasses and releases reference to it once the cold observable has completed. You can also provide a latency delay to account for the time it takes for the hot observable to actually begin emitting events.

Usage

var cold = Observable.FromAsync(async () => await apiClient.GetThingsAsync()).SelectMany(x => x);

var hot = new Subject<Thing>();
await apiClient.SubscribeToNewThingsAsync(hot.OnNext);

var thingEqualityComparer = EqualityComparer<Thing>.Create(
    (a, b) => a!.Id == b!.Id,
    x => x.Id.GetHashCode()
);
var warm = WarmObservable.From(cold, hot, thingEqualityComparer);

NuGet Version

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-beta3 49 12/21/2024
1.0.0-beta2 47 12/21/2024
1.0.0-beta1 57 10/8/2024