Skip to content

improvement: Add typed equality constructors to avoid reflect.DeepEqual in refreshable debouncing#431

Open
bmoylan wants to merge 2 commits into
masterfrom
bm/equality
Open

improvement: Add typed equality constructors to avoid reflect.DeepEqual in refreshable debouncing#431
bmoylan wants to merge 2 commits into
masterfrom
bm/equality

Conversation

@bmoylan

@bmoylan bmoylan commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

Add a family of constructors that accept or infer an equality function, allowing callers to bypass reflect.DeepEqual when updating refreshable values. This is both more efficient and more correct for types like time.Time where reflect.DeepEqual disagrees with semantic equality, or x509.Certificate which contains function pointer fields that never satisfy reflect.DeepEqual.

New constructors: NewComparable, NewComparableMap, NewComparableSlice, NewBytes, NewEqualMethod, NewEqualMethodMap, and NewEqualMethodSlice, and NewEqualFunc. Each targets a common category of types and wires the appropriate comparison (==, maps.Equal, slices.Equal, bytes.Equal, or a type's own Equal method).

Add CacheWith and CacheWithFunc to wrap an existing Refreshable with a typed equality cache, and migrate defaultRefreshable.current from atomic.Value to atomic.Pointer[T] to remove type assertions.


This change is Reviewable

…al in refreshable debouncing

Add a family of constructors that accept or infer an equality function,
allowing callers to bypass reflect.DeepEqual when updating refreshable
values. This is both more efficient and more correct for types like
time.Time where reflect.DeepEqual disagrees with semantic equality.

New constructors: NewComparable, NewComparableMap, NewComparableSlice,
NewBytes, NewEqualMethod, NewEqualFunc, NewEqualMethodMap, and
NewEqualMethodSlice. Each targets a common category of types and wires
the appropriate comparison (==, maps.Equal, slices.Equal, bytes.Equal,
or a type's own Equal method).

Add CacheWith and CacheWithFunc to wrap an existing Refreshable with a
typed equality cache, and migrate defaultRefreshable.current from
atomic.Value to atomic.Pointer[T] to remove type assertions.
@changelog-app

changelog-app Bot commented Mar 13, 2026

Copy link
Copy Markdown

Successfully generated changelog entry!

Entry generated via PR title

To modify this entry, edit PR title using proper format.


📋Changelog Preview

💡 Improvements

  • Add typed equality constructors to avoid reflect.DeepEqual in refreshable debouncing (#431)


func newZero[T any]() *defaultRefreshable[T] {
return newDefault(*new(T))
return newDefault(*new(T), nil)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, can we never pass in nil and remove all the logic in Update for checking nil? Can't we just pass in reflect.DeepEqual here?

func newValidRefreshable[M any]() *validRefreshable[M] {
valid := &validRefreshable[M]{
r: newDefault(validRefreshableContainer[M]{}),
// TODO: Wire equality

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And Below

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants