panel icon indicating copy to clipboard operation
panel copied to clipboard

tornado.websocket.WebSocketClosedError with xarray app

Open MarcSkovMadsen opened this issue 3 years ago • 3 comments

panel=0.13.1, hvplot=0.8.0, holoviews=1.15.0, datashader=0.14.0, linux on JupyterHub.

I'm trying to help a user here https://discourse.holoviz.org/t/interactive-and-dynamically-created-dict-of-widgets-to-xarray-sel/4000/5

When I select another file the app dies with the log

2022-08-07 15:20:48,049 Task exception was never retrieved
future: <Task finished name='Task-276' coro=<WebSocketProtocol13.write_message.<locals>.wrapper() done, defined at /opt/conda/lib/python3.9/site-packages/tornado/websocket.py:1100> exception=WebSocketClosedError()>
Traceback (most recent call last):
  File "/opt/conda/lib/python3.9/site-packages/tornado/websocket.py", line 1102, in wrapper
    await fut
tornado.iostream.StreamClosedError: Stream is closed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/conda/lib/python3.9/site-packages/tornado/websocket.py", line 1104, in wrapper
    raise WebSocketClosedError()
tornado.websocket.WebSocketClosedError

image

Code

import collections
from pathlib import Path

import cartopy.crs as ccrs
import gdown
import hvplot
import hvplot.xarray
import numpy as np
import panel as pn
import panel.widgets as pnw
import xarray as xr
import pathlib

collections.Callable = collections.abc.Callable

CONFIG = {
    "2022070700_231_example.nc": "1vI5xH-kmA4OkoqJJz9keze-vN3cYCIf4",
    "2022070700_237_example.nc": "1RnWmfiW3U7VYS4Qoqo7_uFdeAIXAajye",
}

for file, file_id in CONFIG.items():
    if not pathlib.Path(file).exists():
        gdown.download(id=file_id, output=file, quiet=False)

file_list = [pathlib.Path(file) for file in CONFIG]

def open_dataset(file):
    key = f"file {file}"
    if not key in pn.state.cache:
        pn.state.cache[key]=xr.open_dataset(file)
    return pn.state.cache[key]

def get_sub_dataset(file, field):
    xds = open_dataset(file)
    return xds[field]

def get_options(file, field):
    options = {}
    xds_sub = get_sub_dataset(file, field)
    for (_, d) in enumerate(xds_sub.dims):
        for (_, c) in enumerate(xds_sub.coords):
            if d == c and (d != "lon" and d != "lat"):
                if xds_sub.coords[c].dtype == np.dtype("<M8[ns]"):
                    time_list = []
                    for _, el in np.ndenumerate(
                        xds_sub.coords["time"].values
                    ):
                        time_list.append(np.datetime_as_string(el, timezone="UTC"))
                    options[d] = time_list
                else:
                    options[d] = xds_sub.coords[c].values.tolist()
    return options

def get_widgets(file, field):
    options=get_options(file, field)
    print("options", file,field,options)
    return {key: pnw.DiscreteSlider(options=value) for key, value in options.items()}

xds = open_dataset(file_list[0])
select_file = pnw.Select(name="File", options=file_list)
select_field = pnw.Select(name="Field", value="HU", options=list(xds.data_vars))

# I just want to see the options
def warm():
    for file in file_list:
        xds = open_dataset(file)
        for field in xds.data_vars:
            options = get_options(file, field)
            print(file, field, options)
warm()

@pn.depends(select_file, select_field)
def load_file(file, field):
    xds_sub = get_sub_dataset(file,field)
    widgets = get_widgets(file, field)
    
    return (
        xds_sub
        .interactive.sel(**widgets)
        .hvplot(
            kind="quadmesh",
            rasterize=True,
            data_aspect=1,
            frame_height=800,
            cmap="jet",
            crs=ccrs.PlateCarree(),
            projection=ccrs.PlateCarree(),
            project=True,
            geo=True,
            coastline=True,
            global_extent=True,
        )
    )


pn.Row(pn.Card(select_file, select_field), load_file).servable()

Additional Context

I'm running on a JupyterHub. One guess could be that I do not have enough resource (CPU/ RAM) to work with this app? If that is the case a more helpful error message would be appreciated that could help guide me to the cause and solution.

MarcSkovMadsen avatar Aug 07 '22 15:08 MarcSkovMadsen

I've tried increasing the memory to 32GB but still experience the issue.

MarcSkovMadsen avatar Aug 07 '22 15:08 MarcSkovMadsen

Thank you Mr. @MarcSkovMadsen for your effort and I can confirm that this issue persists in JupyterLab on Windows 10 both using .servable() and .show()

itsgifnotjiff avatar Aug 07 '22 18:08 itsgifnotjiff

I doubt this is related to memory usage, much more likely that we are exceeding the max websocket message size configured by Jupyter or something related to that.

philippjfr avatar Aug 08 '22 09:08 philippjfr