Skip to content

Conversation

@runspired
Copy link
Contributor

When implementing SchemaObject and SchemaArray, we punted on some aspects of the design around cleanup by stashing them inside WeakRefs and WeakMaps. Unfortunately, in addition to being unwieldy and malperformant, this ultimately didn't work as strong-refs were generated for notification subscriptions (among other retainers).

I've been thinking on different strategies by which to address this and ensure both

  • full object graph cleanup when a resource is destroyed
  • full branch cleanup when a schema-object or schema-array is no longer needed

While there are a few strategies that would allow us to retain the lazy materialization semantics schema-array shares with record arrays, a realization of this exploration was that in this case lazy is wrong.

The underlying issue is one of addressing. In a record-array, should a record be handed out to the UI and then later removed from the array, this is alright - as the record has an identity of its own and thus knows how to directly reference its data in the cache.

In schema-array however, schema-objects do not have this capability. While it is true that a schema-object may have a concept of identity, that identity is both local (to its position in the graph) and compound.

E.g. for a schema-object to find itself in the cache it must know:

  • the identity of the base resource to which it is attached
  • the full path to its data in the cache from that resource's entry

This is of course presuming that both the identity and the schema-object-type of the data at that position still match the object ... they may not.

So when a schema-object is either moved (and its path updated) or removed from an array (and thus has no path) it should be immediately divorced from the cache entry it had access to before, unlike records in record arrays. Thus fundamentally, schema-arrays cannot be lazy because if they were lazy an object retained in the ui would either reflect incorrect state, broken-state, or unsafe access to state.

Whenever we work on #9612 we will want to take into account that usage of a schema-object, managed-object, schema-array or managed-array counts as retention of the resource as well. We can likely achieve this by placing a back-ref to the record instance on the context so that if any part of the object-graph is retained the record is retained.

This PR is going to focus on sync-cleanup of schema-object-fields and sync-materialization and sync-cleanup of schema-array fields. There is some (much less pressing as less memory-leak prone) need to clean up managed-objects and managed-arrays, and further refinements we will want for full tracing-GC support down the road.

@runspired runspired added 🎯 canary PR is targeting canary (default) 🏷️ bug This PR primarily fixes a reported issue labels Jul 11, 2025
@github-project-automation github-project-automation bot moved this to needs triage in EmberData Jul 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎯 canary PR is targeting canary (default) 🏷️ bug This PR primarily fixes a reported issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants