Repository: dask/distributed

Issue:
processes=False breaks Client dashboard
Hi, I'm on Windows 10 with JupyterLab in Chrome. Was just going through the official sites tutorials and noticed that half of the Client dashboards wouldn't open(empty localhost page):

```
`from dask.distributed import Client, progress

client = Client(processes=False, threads_per_worker=4,
                                              n_workers=1, memory_limit='2GB')
client`
```

The culprit is **processes=False**, by just removing it you can access dashboard. 
Thanks for the modules and cheers.


Discussion:
I just tried this locally and was able to see the dashboard.  Do you have any ideas on what might make your situation different?
Anaconda and python 3.7.6? I turned off firewall, tried jupyter notebook and different browsers and vpn, still had the issue.
It's hard to pin-point tbh since the dashboard works if I set **processes=True** or remove that param.
Perhaps you can construct a minimal conda environment that reproduces the
issue?  Then someone else can try it, and if it fails then great, we've got
a clear bug to try to identify.  If it doesn't fail for them then there is
maybe something off with the environment.

On Sun, Feb 9, 2020 at 6:17 AM MentalOpus <notifications@github.com> wrote:

> Anaconda and python 3.7.6? I turned off firewall, tried jupyter notebook
> and different browsers and vpn, still had the issue.
> It's hard to pin-point tbh since the dashboard works if I set
> *processes=True* or remove that param.
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/dask/distributed/issues/3456?email_source=notifications&email_token=AACKZTBTF2ST7Y63JJ7JSPDRCAGAXA5CNFSM4KRZCJW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELGNTFA#issuecomment-583850388>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AACKZTBC4FO4TNCB6I7KPQLRCAGAXANCNFSM4KRZCJWQ>
> .
>

I made a new conda env with just a JupyterLab and Dask installation, issue persisted. Here is a _pip freeze_:
```
`attrs==19.3.0
backcall==0.1.0
bleach==3.1.0
bokeh==1.4.0
certifi==2019.11.28
Click==7.0
cloudpickle==1.2.2
colorama==0.4.3
cytoolz==0.10.1
dask==2.10.1
decorator==4.4.1
defusedxml==0.6.0
distributed==2.10.0
entrypoints==0.3
fsspec==0.6.2
HeapDict==1.0.1
importlib-metadata==1.5.0
inflect==4.1.0
ipykernel==5.1.4
ipython==7.12.0
ipython-genutils==0.2.0
jaraco.itertools==5.0.0
jedi==0.16.0
Jinja2==2.11.1
json5==0.9.0
jsonschema==3.2.0
jupyter-client==5.3.4
jupyter-core==4.6.1
jupyterlab==1.2.6
jupyterlab-server==1.0.6
locket==0.2.0
MarkupSafe==1.1.1
mistune==0.8.4
mkl-fft==1.0.15
mkl-random==1.1.0
mkl-service==2.3.0
more-itertools==8.2.0
msgpack==0.6.1
nbconvert==5.6.1
nbformat==5.0.4
notebook==6.0.3
numpy==1.18.1
olefile==0.46
packaging==20.1
pandas==1.0.0
pandocfilters==1.4.2
parso==0.6.0
partd==1.1.0
pickleshare==0.7.5
Pillow==7.0.0
prometheus-client==0.7.1
prompt-toolkit==3.0.3
psutil==5.6.7
pyarrow==1.0.0a0
Pygments==2.5.2
pyparsing==2.4.6
pyrsistent==0.15.7
python-dateutil==2.8.1
pytz==2019.3
pywin32==227
pywinpty==0.5.7
PyYAML==5.3
pyzmq==18.1.1
Send2Trash==1.5.0
six==1.14.0
sortedcontainers==2.1.0
tblib==1.6.0
terminado==0.8.3
testpath==0.4.4
toolz==0.10.0
tornado==6.0.3
traitlets==4.3.3
wcwidth==0.1.8
webencodings==0.5.1
wincertstore==0.2
zict==1.0.0
zipp==2.1.0`
```
And here is an _IPython.sys_info()_:
```
`{'commit_hash': '8bda98619',
 'commit_source': 'installation',
 'default_encoding': 'cp1252',
 'ipython_path': 'C:\\Users\\MO\\AppData\\Local\\Continuum\\anaconda3\\envs\\Dask\\lib\\site-packages\\IPython',
 'ipython_version': '7.12.0',
 'os_name': 'nt',
 'platform': 'Windows-10-10.0.18362-SP0',
 'sys_executable': 'C:\\Users\\MO\\AppData\\Local\\Continuum\\anaconda3\\envs\\Dask\\python.exe',
 'sys_platform': 'win32',
 'sys_version': '3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit '
                '(AMD64)]'}`
```
I made screenshots to make it clear how it looks like:
[Imgur - Dask distributed Client dashboard processes=False issue](https://imgur.com/a/Mfz1Tqj)
Do other bokeh applications / graphs work for you? Are you seeing any warnings in the browser console?
Never had any issues with bokeh and no warnings in the browser console.
I'm all out of ideas then sorry. Anything you can do on your end to debug this further would be welcome.
That's a very stranger address: `http://192.168.1.6/12536/1:8787`.  Is this a in a Windows VM  ?  And you are trying to access outsider/inside the VM ?
Note that that looks similar to addresses that we use for the inproc://
protocol.  In general we identify that the user is using inproc, and then
munge things to point to localhost.

https://github.com/dask/distributed/blob/9d79de1abf28e3784ce03f6622fd07ab1131e0be/distributed/client.py#L752-L765

Maybe something is going on there?

On Mon, Feb 10, 2020 at 8:22 AM Benjamin Zaitlen <notifications@github.com>
wrote:

> That's a very stranger address: http://192.168.1.6/12536/1:8787. Is this
> a in a Windows VM ? And you are trying to access outsider/inside the VM ?
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/dask/distributed/issues/3456?email_source=notifications&email_token=AACKZTFAPWFVI5LFRJBPAXLRCF5MRA5CNFSM4KRZCJW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELJELFA#issuecomment-584205716>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AACKZTBLAY4CRCUWJFIKJN3RCF5MRANCNFSM4KRZCJWQ>
> .
>

It's not in VM and indeed the main difference between this 2 modes of connection is the the protocol. **Tcp** works fine and **inproc** does not.
I saw a similar problem recently too when giving a Dask tutorial following https://github.com/dask/dask-tutorial/blob/master/03_array.ipynb (which uses `Client(processes=False)`).

To reproduce:
```
conda create -n test dask -y
conda activate test
```

```py
from dask.distributed import Client

client = Client(processes=False)
print(client._repr_html_())
```

Output:
```
<table style="border: 2px solid white;">
<tr>
<td style="vertical-align: top; border: 0px solid white">
<h3 style="text-align: left;">Client</h3>
<ul style="text-align: left; list-style: none; margin: 0; padding: 0;">
  <li><b>Scheduler: </b>inproc://192.168.0.11/535/1</li>
  <li><b>Dashboard: </b><a href='http://192.168.0.11/535/1:41831/status' target='_blank'>http://192.168.0.11/535/1:41831/status</a>
</ul>
</td>
<td style="vertical-align: top; border: 0px solid white">
<h3 style="text-align: left;">Cluster</h3>
<ul style="text-align: left; list-style:none; margin: 0; padding: 0;">
  <li><b>Workers: </b>1</li>
  <li><b>Cores: </b>4</li>
  <li><b>Memory: </b>16.70 GB</li>
</ul>
</td>
</tr>
</table>
```

Output (HTML rendered via github):

<table style="border: 2px solid white;">
<tr>
<td style="vertical-align: top; border: 0px solid white">
<h3 style="text-align: left;">Client</h3>
<ul style="text-align: left; list-style: none; margin: 0; padding: 0;">
  <li><b>Scheduler: </b>inproc://192.168.0.11/535/1</li>
  <li><b>Dashboard: </b><a href='http://192.168.0.11/535/1:41831/status' target='_blank'>http://192.168.0.11/535/1:41831/status</a>
</ul>
</td>
<td style="vertical-align: top; border: 0px solid white">
<h3 style="text-align: left;">Cluster</h3>
<ul style="text-align: left; list-style:none; margin: 0; padding: 0;">
  <li><b>Workers: </b>1</li>
  <li><b>Cores: </b>4</li>
  <li><b>Memory: </b>16.70 GB</li>
</ul>
</td>
</tr>
</table>

<details>
<summary>
conda list info:
</summary>

```
# packages in environment at /home/lesteve/miniconda3/envs/test:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                        main  
blas                      1.0                         mkl  
bokeh                     1.4.0                    py38_0  
ca-certificates           2020.1.1                      0  
certifi                   2019.3.9                 py38_0    conda-forge/label/pre-3.8
click                     7.0                        py_0  
cloudpickle               1.3.0                      py_0  
cytoolz                   0.10.1           py38h7b6447c_0  
dask                      2.10.1                     py_0  
dask-core                 2.10.1                     py_0  
distributed               2.10.0                     py_0  
freetype                  2.9.1                h8a8886c_1  
fsspec                    0.6.2                      py_0  
heapdict                  1.0.1                      py_0  
intel-openmp              2020.0                      166  
jinja2                    2.11.1                     py_0  
jpeg                      9b                   h024ee3a_2  
ld_impl_linux-64          2.33.1               h53a641e_7  
libedit                   3.1.20181209         hc058e9b_0  
libffi                    3.2.1                hd88cf55_4  
libgcc-ng                 9.1.0                hdf63c60_0  
libgfortran-ng            7.3.0                hdf63c60_0  
libpng                    1.6.37               hbc83047_0  
libstdcxx-ng              9.1.0                hdf63c60_0  
libtiff                   4.1.0                h2733197_0  
locket                    0.2.0                    py38_1  
markupsafe                1.1.1            py38h7b6447c_0  
mkl                       2020.0                      166  
mkl-service               2.3.0            py38he904b0f_0  
mkl_fft                   1.0.15           py38ha843d7b_0  
mkl_random                1.1.0            py38h962f231_0  
msgpack-python            0.6.1            py38hfd86e86_1  
ncurses                   6.1                  he6710b0_1  
numpy                     1.18.1           py38h4f9e942_0  
numpy-base                1.18.1           py38hde5b4d6_1  
olefile                   0.46                       py_0  
openssl                   1.1.1d               h7b6447c_4  
packaging                 20.1                       py_0  
pandas                    1.0.1            py38h0573a6f_0  
partd                     1.1.0                      py_0  
pillow                    7.0.0            py38hb39fc2d_0  
pip                       19.1                     py38_0    conda-forge/label/pre-3.8
psutil                    5.6.7            py38h7b6447c_0  
pyparsing                 2.4.6                      py_0  
python                    3.8.1                h0371630_1  
python-dateutil           2.8.1                      py_0  
pytz                      2019.3                     py_0  
pyyaml                    5.3              py38h7b6447c_0  
readline                  7.0                  h7b6447c_5  
setuptools                41.0.1                   py38_0    conda-forge/label/pre-3.8
six                       1.12.0                py38_1000    conda-forge/label/pre-3.8
sortedcontainers          2.1.0                    py38_0  
sqlite                    3.31.1               h7b6447c_0  
tblib                     1.6.0                      py_0  
tk                        8.6.8                hbc83047_0  
toolz                     0.10.0                     py_0  
tornado                   6.0.3            py38h7b6447c_3  
wheel                     0.33.1                   py38_0    conda-forge/label/pre-3.8
xz                        5.2.4                h14c3975_4  
yaml                      0.1.7                had09818_2  
zict                      1.0.0                      py_0  
zlib                      1.2.11               h7b6447c_3  
zstd                      1.3.7                h0b5b093_0  
```

</details>



Thanks for the reproducer @lesteve! Looks like a formatting issue in the dashboard address when the protocol is `inproc`. 

If I visit the correct localhost:8787 address manually the dashboard seems to be working fine.

Having a look now 👀.

Resolving patch:
diff --git a/distributed/deploy/cluster.py b/distributed/deploy/cluster.py
--- a/distributed/deploy/cluster.py
+++ b/distributed/deploy/cluster.py
@@ -199,7 +199,7 @@ def dashboard_link(self):
         except KeyError:
             return ""
         else:
-            host = self.scheduler_address.split("://")[1].split(":")[0]
+            host = self.scheduler_address.split("://")[1].split("/")[0].split(":")[0]
             return format_dashboard_link(host, port)
 
     def _widget_status(self):


Test patch:
diff --git a/distributed/tests/test_client.py b/distributed/tests/test_client.py
--- a/distributed/tests/test_client.py
+++ b/distributed/tests/test_client.py
@@ -5255,6 +5255,13 @@ def test_dashboard_link(loop, monkeypatch):
                 assert link in text
 
 
+@pytest.mark.asyncio
+async def test_dashboard_link_inproc(cleanup):
+    async with Client(processes=False, asynchronous=True) as c:
+        with dask.config.set({"distributed.dashboard.link": "{host}"}):
+            assert "/" not in c.dashboard_link
+
+
 @gen_test()
 def test_client_timeout_2():
     with dask.config.set({"distributed.comm.timeouts.connect": "10ms"}):