@@ -167,6 +167,27 @@ def __init__(self, **params):
167167 # Create widgets
168168 self .create_widgets ()
169169
170+ # Register cleanup on session destroy
171+ if pn .state .curdoc :
172+ pn .state .curdoc .on_session_destroyed (self ._cleanup_session )
173+
174+ def _cleanup_session (self , session_context ):
175+ """Clean up resources when session ends"""
176+
177+ self .clear_bokeh_data ()
178+
179+ if hasattr (self , 'electrode_source' ):
180+ del self .electrode_source
181+ if hasattr (self , 'tool_state_source' ):
182+ del self .tool_state_source
183+ if hasattr (self , 'plot' ):
184+ del self .plot
185+ if hasattr (self , 'plot_pane' ):
186+ del self .plot_pane
187+
188+ gc .collect ()
189+ print (f"🧹🧹🧹 Session { session_context .id } cleaned up" )
190+
170191
171192 #####################################
172193 ##### Probe geometry and wiring #####
@@ -493,9 +514,7 @@ def on_electrode_selection(self, _, old, new):
493514 # Clear the selection to allow for new interactions
494515 self .electrode_source .selected .indices = []
495516
496- # Force garbage collection after large selections to free memory
497- if len (new ) > 100 :
498- gc .collect ()
517+ gc .collect ()
499518
500519
501520 def get_zigzag_subset (self ):
@@ -676,10 +695,8 @@ def generate_pdf_content(self):
676695 buffer .seek (0 )
677696
678697 finally :
679- # Force cleanup of matplotlib resources
680- plt .close ('all' ) # Close all figures
681- plt .clf () # Clear current figure
682- plt .cla () # Clear current axes
698+ plt .close ('all' )
699+ gc .collect ()
683700
684701 return buffer
685702
0 commit comments