Skip to content
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

Fixes for profiler #2664

Merged
merged 2 commits into from Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 36 additions & 6 deletions panel/command/serve.py
Expand Up @@ -14,8 +14,10 @@
from bokeh.command.util import build_single_handler_applications

from bokeh.application import Application
from bokeh.application.handlers.document_lifecycle import DocumentLifecycleHandler
from bokeh.application.handlers.function import FunctionHandler
from bokeh.server.contexts import ApplicationContext
from tornado.ioloop import PeriodicCallback, IOLoop
from tornado.web import StaticFileHandler

from ..auth import OAuthProvider
Expand Down Expand Up @@ -63,6 +65,28 @@ def parse_vars(items):
return dict((parse_var(item) for item in items))


class AdminApplicationContext(ApplicationContext):

def __init__(self, application, unused_timeout=15000, **kwargs):
super().__init__(application, io_loop=IOLoop.current(), **kwargs)
self._unused_timeout = unused_timeout
self._cleanup_cb = None
self._loop.add_callback(self.run_load_hook)

async def cleanup_sessions(self):
await self._cleanup_sessions(self._unused_timeout)

def run_load_hook(self):
self._cleanup_cb = PeriodicCallback(self.cleanup_sessions, self._unused_timeout)
self._cleanup_cb.start()
super().run_load_hook()

def run_unload_hook(self):
if self._cleanup_cb:
self._cleanup_cb.stop()
super().run_unload_hook()


class Serve(_BkServe):

args = _BkServe.args + (
Expand Down Expand Up @@ -203,23 +227,30 @@ def customize_kwargs(self, args, server_kwargs):
doc = app.create_document()
_cleanup_doc(doc)

prefix = args.prefix
if prefix is None:
prefix = ""
prefix = prefix.strip("/")
if prefix:
prefix = "/" + prefix

config.profiler = args.profiler
if args.admin:
from ..io.admin import admin_panel
from ..io.server import per_app_patterns
config._admin = True
app = Application(FunctionHandler(admin_panel))
app_ctx = ApplicationContext(app, url='/admin')
unused_timeout = args.check_unused_sessions or 15000
app_ctx = AdminApplicationContext(app, unused_timeout=unused_timeout, url='/admin')
if all(not isinstance(handler, DocumentLifecycleHandler) for handler in app._handlers):
app.add(DocumentLifecycleHandler())
app_patterns = []
for p in per_app_patterns:
route = '/admin' + p[0]
context = {"application_context": app_ctx}
route = (args.prefix or '') + route
route = prefix + route
app_patterns.append((route, p[1], context))

from tornado.ioloop import IOLoop
app_ctx._loop = IOLoop.current()

websocket_path = None
for r in app_patterns:
if r[0].endswith("/ws"):
Expand All @@ -238,7 +269,6 @@ def customize_kwargs(self, args, server_kwargs):
pass
patterns.extend(app_patterns)


config.session_history = args.session_history
if args.rest_session_info:
pattern = REST_PROVIDERS['param'](files, 'rest')
Expand Down
5 changes: 3 additions & 2 deletions panel/config.py
Expand Up @@ -95,8 +95,9 @@ class _config(_base_config):
loading_color = param.Color(default='#c3c3c3', doc="""
Color of the loading indicator.""")

profiler = param.Selector(default=None, objects=['pyinstrument', 'snakeviz'], doc="""
The profiler to enable.""")
profiler = param.Selector(default=None, allow_None=True, objects=[
'pyinstrument', 'snakeviz'], doc="""
The profiler engine to enable.""")

safe_embed = param.Boolean(default=False, doc="""
Ensure all bokeh property changes trigger events which are
Expand Down
8 changes: 6 additions & 2 deletions panel/io/profile.py
Expand Up @@ -117,8 +117,12 @@ def profile_ctx(engine='pyinstrument'):
"""
if engine == 'pyinstrument':
from pyinstrument import Profiler
prof = Profiler()
prof.start()
try:
prof = Profiler()
prof.start()
except RuntimeError:
prof = Profiler(async_mode='disabled')
prof.start()
elif engine == 'snakeviz':
prof = Profile()
prof.enable()
Expand Down