Skip to content

Commit

Permalink
Ensure gc.collect is not excessively called (#3259)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored Mar 25, 2022
1 parent 02acacc commit 2e43510
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
25 changes: 25 additions & 0 deletions panel/io/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Utilities for creating bokeh Server instances.
"""
import datetime as dt
import gc
import html
import logging
import os
Expand Down Expand Up @@ -165,6 +166,28 @@ def autoload_js_script(doc, resources, token, element_id, app_path, absolute_url

return AUTOLOAD_JS.render(bundle=bundle, elementid=element_id)


def destroy_document(self, session):
"""
Override for Document.destroy() without calling gc.collect directly.
The gc.collect() call is scheduled as a task, ensuring that when
multiple documents are destroyed in quick succession we do not
schedule excessive garbage collection.
"""
self.remove_on_change(session)
del self._roots
del self._theme
del self._template
self._session_context = None

self.callbacks.destroy()
self.models.destroy()
self.modules.destroy()

at = dt.datetime.now() + dt.timedelta(seconds=5)
state.schedule_task('gc.collect', gc.collect, at=at)


# Patch Application to handle session callbacks
class Application(BkApplication):

Expand Down Expand Up @@ -349,7 +372,9 @@ def handle_exception(handler, e):

def _log_session_destroyed(session_context):
logger.info(LOG_SESSION_DESTROYED, id(doc))

doc.on_session_destroyed(_log_session_destroyed)
doc.destroy = partial(destroy_document, doc)
finally:
state._launching.remove(doc)
if config.profiler:
Expand Down
2 changes: 1 addition & 1 deletion panel/io/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ def schedule_task(self, name, callback, at=None, period=None, cron=None):
"A separate task was already scheduled under the "
f"name {name!r}. The new task will be ignored. If "
"you want to replace the existing task cancel it "
"with `state.cancel_task({name!r})` before adding "
f"with `state.cancel_task({name!r})` before adding "
"adding a new task under the same name."
)
return
Expand Down

0 comments on commit 2e43510

Please sign in to comment.