cefn / watchable

Repo for @watchable/store and supporting packages.
MIT License
5 stars 1 forks source link

Fix or eliminate namedRace pattern #57

Closed cefn closed 2 months ago

cefn commented 7 months ago

A namedRace helps you write type-safe switch statements, but relies on creating a Promise<Name> from a thenable Promise<unknown> like promise.then(() => name).

This means there is a danger of a memory leak if a promise is routinely passed to named race as every call adds another then subscriber to the same promise, (which is never tidied as long as the promise exists).

In some way, this then subscriber has to be created once and reused between namedRace calls so they don't accumulate.

One implementation is to keep a Map of identity promises (promises which resolve to a WeakRef pointing to themselves). Only one such value needs to exist for any Promise. A FinalizationRegistry can tidy up entries which are GCed.

Combined with the use of safeRace (race-as-promised) this means a race can be made between only identity promises, and when the race completes, the namedRace implementation can unwrap the winning WeakRef, traverse all keypairs from the race and return the key from the pair which has the winning promise as the value.

The only circumstance this fails is if the promise from the namedRace itself is garbage-collected (and therefore no-one is watching anyway).

cefn commented 2 months ago

Completed in https://github.com/cefn/watchable/pull/79