bencher.bench_plot_server ========================= .. py:module:: bencher.bench_plot_server .. autoapi-nested-parse:: A server for display plots of benchmark results Attributes ---------- .. autoapisummary:: bencher.bench_plot_server._PORT_RANGE_MIN bencher.bench_plot_server._PORT_RANGE_MAX bencher.bench_plot_server._PORT_PROBE_ATTEMPTS Classes ------- .. autoapisummary:: bencher.bench_plot_server._CorsStaticHandler bencher.bench_plot_server.BenchPlotServer Module Contents --------------- .. py:data:: _PORT_RANGE_MIN :value: 49152 .. py:data:: _PORT_RANGE_MAX :value: 65535 .. py:data:: _PORT_PROBE_ATTEMPTS :value: 100 .. py:class:: _CorsStaticHandler(application: Application, request: tornado.httputil.HTTPServerRequest, **kwargs: Any) Bases: :py:obj:`tornado.web.StaticFileHandler` A Tornado static file handler that adds CORS headers. Required for rerun integration: the rerun web viewer fetches .rrd files from the Panel server. Without Access-Control-Allow-Origin and OPTIONS preflight handling the browser silently blocks the cross-origin fetch and the viewer shows 0 B. Note: ``Allow-Origin: *`` is appropriate here because this server is intended for local development only, not public-facing deployments. .. py:method:: data_received(chunk) Implement this method to handle streamed request data. Requires the `.stream_request_body` decorator. May be a coroutine for flow control. .. py:method:: set_default_headers() Override this to set HTTP headers at the beginning of the request. For example, this is the place to set a custom ``Server`` header. Note that setting such headers in the normal flow of request processing may not do what you want, since headers may be reset during error handling. .. py:method:: options(*_args) .. py:class:: BenchPlotServer A server for display plots of benchmark results .. py:method:: plot_server(bench_name: str, plot_cfg: bencher.bench_cfg.BenchPlotSrvCfg | None = None, plots_instance=None) -> threading.Thread Load previously calculated benchmark data from the database and start a plot server to display it :param bench_name: The name of the benchmark and output folder for the figures :type bench_name: str :param plot_cfg: Options for the plot server. Defaults to None. :type plot_cfg: BenchPlotSrvCfg, optional :raises FileNotFoundError: No data found was found in the database to plot .. py:method:: load_data_from_cache(bench_name: str) -> tuple[bencher.bench_cfg.BenchCfg, list[panel.panel]] | None Load previously calculated benchmark data from the database and start a plot server to display it :param bench_name: The name of the benchmark and output folder for the figures :type bench_name: str :returns: benchmark result data and any additional panels :rtype: tuple[BenchCfg, list[pn.panel]] | None :raises FileNotFoundError: No data found was found in the database to plot .. py:method:: _find_free_port() -> int :staticmethod: Find a free port by testing random ports in the dynamic/private range. Using ``port=0`` with Tornado/Bokeh can fail on some Linux kernels (notably 6.x) because the kernel deterministically assigns the same ephemeral port, causing ``EADDRINUSE`` when a previous server is still running. Picking a random port from the IANA dynamic range avoids this. Note: there is an inherent TOCTOU race between probing the port here and the actual ``bind()`` inside Panel/Bokeh. In practice the window is very small and the random selection makes collisions unlikely, but callers should be prepared for a rare ``OSError`` on server start. .. py:method:: serve(bench_name: str, plots_instance: list[panel.panel], port: int | None = None, show: bool = True) -> threading.Thread Launch a panel server to view results :param bench_cfg: benchmark results :type bench_cfg: BenchCfg :param plots_instance: list of panel objects to display :type plots_instance: list[pn.panel] :param port: use a fixed port to launch the server :type port: int .. py:method:: _rrd_extra_patterns() -> list :staticmethod: Return Tornado route patterns for serving .rrd files with CORS headers. Mounts ``cachedir/rrd/`` at ``/rrd_static/`` so that the local rerun viewer can fetch ``.rrd`` files from the Panel server. See the module docstring in ``utils_rerun.py`` for the full architecture explanation.