-
-
Notifications
You must be signed in to change notification settings - Fork 628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lifetime of objects owning a BindableProperty
#4109
Comments
Interesting observation, @andybayer! If I understand correctly, the main issue is the object reference stored in the bindable_properties[(id(owner), self.name)] = owner The dictionary is used in three places:
So it should be possible to replace the dictionary with a set of keys, removing the object references. Do you think this fixes the memory leak? |
Thank you very much for your quick reply. I tested replacing the import weakref
from datetime import datetime
from nicegui import ui
from nicegui.binding import BindableProperty
class Model:
name = BindableProperty()
def __init__(self, name: str) -> None:
self.name = name
weakref.finalize(self, lambda: log(f'Model "{name}" FINALIZED'))
log(f'Model "{name}" initialized')
@ui.page('/')
async def main() -> None:
automatic = Model('automatic')
ui.label('Models').classes('text-h6')
ui.label(automatic.name).bind_text(automatic, 'name')
def log(message: str) -> None:
now = datetime.now().time().isoformat(timespec='seconds')
print(f'{now} {message}')
ui.run(show=False, reload=False, show_welcome_message=False) I got the following output after connecting to the UI via the browser and closing the browser tab shortly after. So it seems to work. There is even no need to force a manual garbage collection run. At least on my system (OpenSUSE Tumbleweed, Python 3.11.10, NiceGUI 2.8.0).
However, I hope I didn't misinterpret anything, as my knowledge of web technologies and GUIs in particular is quite limited. |
When I stumbled across
BindableProperty
, I thought it would also be very useful for modeling data that can be modified through various "widgets" and keyboard shortcuts. Basically, a model-like object that encapsulates the single source of truth for some data. A small example on the official website seems to support that this is an intended use case.So I built a small application using this idea. It seems to work quite well. Since I also needed to clean up some resources for which a
with
-statement would not be very practical (and would also require some minor refactoring), I simply usedweakref.finalize
to add a "finalizer" to the model that does the cleanup. This is similar to RAII in C++, but without the deterministic behavior of when exactly the finalizer will run.Then I noticed that the resources were never cleaned up, even when the garbage collection was forced to run. So I looked for references to my model. Since I used
BindableProperty
and bindings in general a lot, there were several references to my model in the global objects in thebindings
module. I then looked up how these are all cleaned up. It seems that they are only cleaned up when the client is deleted (except for some special behavior forui.scene
)? The client by default only callsbinding.remove
for elements added to it. But at least it seems to remove related references to the model'sBindableProperty
as well.What is left is a reference to the model in
binding.bindable_properties
, since it is the owner of the property. This will keep the model alive if it is not explicitly deleted, and will also leak memory. You could add a deleter manually inapp.on_disconnect
or as a client finalizer, but I am not sure if this is really a good solution. Maybe it would be better to remove the reference to the owner inbinding.bindable_properties
as I cannot see that it is currently needed anywhere, and add a finalizer usingweakref.finalize
to clean up the(id, name)
tuples? But maybe the reference to the owner has some use I have not seen.Below is a small example that shows the behavior described above. The naive model is not deleted when you disconnect from the client. The fixed model is deleted when you disconnect and start the next session.
The text was updated successfully, but these errors were encountered: