Skip to content

[TECH DEBT] OwnerList for managing lifecycle of objects in async context #6518

@NickKhalow

Description

@NickKhalow

📊 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

No one assigned

    Labels

    2-mediumAffects secondary features or support features; doesn’t block main flows.tech debt

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions