This patch changes the CallbackManager to use WeakMethods (weakrefs) to break the ref cycle and allow the GC to clean up the wallet objects. unregister_callbacks() will also get called automatically, from EventListener.__del__, to clean up the CallbackManager. I also added a few unit tests for this. fixes https://github.com/spesmilo/electrum/issues/10427 ----- original problem: In many subclasses of `EventListener`, such as `Abstract_Wallet`, `LNWatcher`, `LNPeerManager`, we call `register_callbacks()` in `__init__`. `unregister_callbacks()` is usually called in the `stop()` method. Example - consider the wallet object: - `Abstract_Wallet.__init__()` calls `register_callbacks()` - there is a `start_network()` method - there is a `stop()` method, which calls `unregister_callbacks()` - typically the wallet API user only calls `stop()` if they also called `start_network()`. This means the callbacks are often left registered, leading to the wallet objects not getting GC-ed. The GC won't clean them up as `util.callback_mgr.callbacks` stores strong refs to instance methods of `Abstract_Wallet`, hence strong refs to the `Abstract_Wallet` objects. An annoying example is `daemon.check_password_for_directory`, which potentially creates wallet objects for all wallet files in the datadir. It simply constructs the wallets, does not call `start_network()` and neither does it call `stop()`.
18 KiB
18 KiB