SIGN IN SIGN UP

Bound State._tasks_to_resolve to fix unbounded memory growth (#10534)

* Bound State._tasks_to_resolve to fix unbounded memory growth

A task event carrying a parent_id whose parent is not yet in State.tasks
registers the child in _tasks_to_resolve[parent_id]. That entry is only
popped when a later event for the parent itself arrives.

If the parent never arrives again -- because its events were already
processed, or a monitor evicted it from `tasks` on a READY_STATE, as the
docs' real-time monitoring example used to encourage -- the entry stays
forever. The child Tasks are held in a WeakSet and do get collected, but
the _tasks_to_resolve dict key does not, so a long-running monitor leaks
memory without bound.

Bound it the same way as every other mapping on State, using
max_tasks_in_memory.

Fixes #4832

* Add integration test for #4832 memory leak fix

Exercises the real event pipeline (EventDispatcher -> broker ->
EventReceiver -> State) instead of calling State.event() directly,
verifying _tasks_to_resolve stays bounded when parent tasks never
arrive.

---------

Co-authored-by: Asif Saif Uddin {"Auvi":"অভি"} <auvipy@gmail.com>
M
Michele Ghirardelli committed
e522ec899ebd78c3e8365cef5417f482736efefe
Parent: 937b066
Committed by GitHub <noreply@github.com> on 8/31/2026, 6:54:38 PM