Cleanup of Long-Lived State
Task
Make sure long-lived state and resources do not remain alive after the owning feature is gone.
Solution
Attach cleanup to destruction points and explicitly clear state that can stay reachable for too long.
Code
ts
import { compute, declareController, readonlyAtom } from '@nrgyjs/core';
export const SessionController = declareController(({ scope }) => {
const cache = scope.atom<Map<string, string>>(new Map(), {
onDestroy: () => {
console.log('cache destroyed');
},
});
scope.onDestroy(() => {
cache.mutate((map) => {
map.clear();
});
});
const cacheSize = compute(() => cache().size);
return {
state: {
cacheSize: readonlyAtom(cacheSize),
},
put: (key: string, value: string) => {
cache.mutate((map) => {
map.set(key, value);
});
},
};
});What to Watch Out For
- long-lived state needs explicit ownership
- destruction may need both resource release and value clearing
- timers, sockets, and subscriptions should be registered in cleanup as well
- clearing a
Mapor similar container in place is often better than replacing it with a new value - if the atom owns the resource directly, cleanup can also live in the atom
onDestroycallback
Common Mistakes
- assuming large state will disappear automatically
- forgetting to clear data that remains reachable through shared references
- releasing only subscriptions while leaving big caches in memory