-
Notifications
You must be signed in to change notification settings - Fork 14
Description
📊 Priority Level:
Medium
📍 Area/Component:
Unity client - async flow using UniTask and collections holding GameObject references
📝 Description:
There is a design gap in how asynchronous UniTasks interact with collections that may be cleared or mutated during execution. Currently, UniTasks can continue executing even after the underlying array/list has been cleared, leading to access of invalid or already-destroyed GameObjects. An example case: #6491
This is not just a missing guard, but a semantic issue: collections can legally contain references to destroyed objects, and nothing enforces lifecycle ownership or validity.
🔍 Current State:
- UniTasks operate without cancellation tied to collection lifecycle.
- Arrays/lists are plain collections with no ownership semantics.
- Clearing a collection does not stop in-flight async operations.
- Collections may contain references to already-destroyed GameObjects, which is a valid but unsafe state.
- Issues are mitigated reactively (null checks, defensive code) rather than structurally prevented.
💡 Proposed Solution:
-
Introduce a CancellationToken (or equivalent mechanism) that cancels UniTasks when the underlying collection is cleared or invalidated.
-
Consider introducing an
OwnedList(or similar abstraction) that:- Owns the lifecycle of contained GameObjects.
- Handles destruction internally.
- Guarantees that iteration never observes destroyed objects.
-
Tie async execution explicitly to the ownership/lifecycle of the collection rather than relying on external discipline.
⚖️ Impact Assessment:
Performance Impact:
Minimal. Cancellation tokens add negligible overhead and may reduce wasted async work.
Maintainability Impact:
High positive impact. Makes lifecycle semantics explicit, reduces defensive checks, and prevents invalid states by construction.
Risk of Refactoring:
Medium. Requires touching async flows and collection usage, but changes are localized and conceptually clear.
📈 Effort Estimate:
M
🔗 Dependencies:
- Existing UniTask usage patterns
- Any systems that clear or reuse collections during async execution
🖥️ Additional Notes:
- This addresses the root cause rather than downstream symptoms.
- Aligns with stronger invariants and ownership-driven design.
- Prevents entire classes of lifecycle-related bugs instead of patching them individually.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status