Bokeh server not responding with holoviews.operation.datashader.rasterize

Hi folks, I am facing a weird issue with holoviews. I am rendering panel apps via bokeh server,
The apps works fine, until I import the following:

from holoviews.operation.datashader import rasterize

After I import this the bokeh server stops responding and none of the panel apps work.
There is absolutely nothing in the bokeh server logs.

The piece of log I get on the import above:

2020-08-19 14:50:28,021      INFO  129 numexpr.utils: Note: NumExpr detected 12 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
2020-08-19 14:50:28,021      INFO  141 numexpr.utils: NumExpr defaulting to 8 threads.

I create bokeh server from from bokeh.server.server import Server

  • holoviews.version
    ‘1.13.3’
  • bokeh.version
    ‘2.1.1’
  • tornado.version
    ‘6.0.4’

Update: Here is a minimally reproducible example:
If you uncomment the following import: from holoviews.operation.datashader import rasterize the panel app will not load, otherwise it works.

import logging

from bokeh.server.server import Server
from tornado.ioloop import IOLoop

import panel as pn


def sample_app(doc):
    pn_row = pn.Row(pn.pane.HTML("hello"))
    doc.add_root(pn_row.get_root())


def start_bokeh_server():
    # from holoviews.operation.datashader import rasterize
    server = Server(
        applications={f"/sample": sample_app},
        io_loop=IOLoop(),
        allow_websocket_origin=['localhost:5006'],
    )
    logging.info("Starting Bokeh server!")
    server.start()
    server.io_loop.start()


if __name__ == "__main__":
    logging_format = "%(asctime)s %(levelname)9s %(lineno)4s %(name)s: %(message)s"
    logging.basicConfig(level=logging.INFO, format=logging_format)
    start_bokeh_server()

So I haven’t yet figured out what the issue here is but there’s really no need to manually create a Server when panel has a helper function to do precisely that:

import logging
import panel as pn

def sample_app():
    return pn.Row(pn.pane.HTML("hello"))

def start_bokeh_server():
    from holoviews.operation.datashader import rasterize
    pn.serve({'sample': sample_app}, show=False, port=5006)

if __name__ == "__main__":
    logging_format = "%(asctime)s %(levelname)9s %(lineno)4s %(name)s: %(message)s"
    logging.basicConfig(level=logging.INFO, format=logging_format)
    start_bokeh_server()

This does the same thing but actually works.

I think the original issue was simply related to using the wrong IOLoop, I suspect importing datashader imports dask which fiddles with the Tornado IOLoop in some way, if instead you let Bokeh use the current IOLoop that approach works too:


def start_bokeh_server():
    server = Server(
        applications={f"/sample": sample_app},
        port=5006,
        allow_websocket_origin=['localhost:5006'],
    )
    logging.info("Starting Bokeh server!")
    server.io_loop.start()