a2ui-project / a2ui-project/a2ui

[v0.9] Fix memory leaks and standardize subscription lifecycle in web_core and react renderers

オープン
#963 コメント 12 件 リアクション 0 件 担当者 1 名 @josemontespg が担当を希望しています GitHub で見る
component: angular renderer component: react renderer javascript P2 sprint ready type: bug type: feature/enhancement
主要言語
TypeScript
スター
16.4k
フォーク
1.3k
平均マージ
2日 13時間
マージ済み PR(30日)
134

説明

This issue tracks critical memory leaks and architectural redundancies identified in the A2UI v0.9 Web, React, and Angular renderers. These issues lead to unbounded memory growth in long-lived surfaces and leaked background processes (e.g., timers) when components are unmounted.

#### Identified Issues

**Core & Shared Logic:**
1. **Unbounded Signal Cache in `DataModel`**: The `DataModel.signals` Map caches every path ever queried. These are only cleared when the entire surface is disposed. In surfaces with many ephemeral components or large lists, this leads to significant memory growth.
2. **`FormatString` Recursive Leaks**: The `formatString` implementation in `basic_functions.ts` resolves internal expressions into signals using `context.resolveSignal(part)` but never calls `unsubscribe` on them. Any function call (like `${now()}`) inside a string will leak its listeners/timers until the DataModel is disposed.
3. **Broken Cleanup Chain in `DataContext`**: `resolveSignal` in `DataContext.ts` creates recursive effects for function arguments but does not properly take ownership of `unsubscribe` methods on signals returned by function implementations.

**React Renderer:**
4. **Redundant Subscription Layers**: The React adapter wraps the `GenericBinder` in additional `useSyncExternalStore` and `useEffect` layers. While not a leak, it increases complexity and makes cleanup harder to audit.

**Angular Renderer:**
5. **Root-Scoped Leaks in `ComponentBinder`**: `ComponentBinder.ts` injects `DestroyRef` at the root level. All subscriptions created via `bind()` are tied to the application lifetime rather than the component lifetime, causing massive leaks as users navigate surfaces.
6. **Stale Bindings**: Angular does not listen to `ComponentModel.onUpdated`. If component properties change in the protocol (e.g., type remains same but props change), the Angular UI stays stale.

#### Goals
* Implement reference counting or explicit signal removal in `DataModel`.
* Ensure all recursive signals created by `formatString` and function calls are tracked and disposed of via a unified `unsubscribe` chain.
* Fix the `DestroyRef` scoping in the Angular renderer.
* Implement property refresh logic in Angular to match the React `GenericBinder` behavior.
* Add exhaustive regression tests verifying that `AbortSignal` listeners and internal Maps are cleared after component unmount across all frameworks.

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。