Breaking circular reference between Actor and its ActorRef#250
Breaking circular reference between Actor and its ActorRef#250JayPay108 wants to merge 3 commits intojodal:mainfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #250 +/- ##
=======================================
Coverage 94.32% 94.32%
=======================================
Files 14 14
Lines 581 582 +1
Branches 50 50
=======================================
+ Hits 548 549 +1
Misses 29 29
Partials 4 4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
I find it a bit icky to let I looked at if Another approach here would be to make This patch seems to pass the test suite, but does it solve your problem? Can you test if the actor is properly garbage collected with this patch? diff --git i/src/pykka/_proxy.py w/src/pykka/_proxy.py
index 3371704..0c06fed 100644
--- i/src/pykka/_proxy.py
+++ w/src/pykka/_proxy.py
@@ -139,7 +139,10 @@ class ActorProxy(Generic[A]):
msg = f"{actor_ref} not found"
raise ActorDeadError(msg)
self.actor_ref = actor_ref
- self._actor = actor_ref._actor # noqa: SLF001
+ self._actor = actor_ref._actor_weakref() # noqa: SLF001
+ if self._actor is None:
+ msg = f"{actor_ref} not found (weakref has been deallocated)"
+ raise ActorDeadError(msg)
self._attr_path = attr_path or ()
self._known_attrs = introspect_attrs(root=self._actor, proxy=self)
self._actor_proxies = {}
diff --git i/src/pykka/_ref.py w/src/pykka/_ref.py
index 7ca8677..4eadc63 100644
--- i/src/pykka/_ref.py
+++ w/src/pykka/_ref.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+import weakref
from typing import (
TYPE_CHECKING,
Any,
@@ -51,7 +52,7 @@ class ActorRef(Generic[A]):
self,
actor: A,
) -> None:
- self._actor = actor
+ self._actor_weakref = weakref.ref(actor)
self.actor_class = actor.__class__
self.actor_urn = actor.actor_urn
self.actor_inbox = actor.actor_inbox |
|
@jodal Super fair. Looks like your patch works great. A stopped actor is garbage collected instantly after removing the last external reference. Thanks! |
|
Thanks for testing, I'll get this into a release this weekend 😄 |
Actor and ActorRef both had references to each other, creating a cycle that blocked instant memory freeing since the actor's reference count never reached zero. This changes the ActorRef reference to the actor to use a weakref, so that the ActorRef doesn't contribute to the Actor's reference count, enabling instant freeing of the memory. Fixes #249, #250
|
v4.4.2 with the fix is out now! |
Fixes #249