Repository: jupyterhub/jupyterhub

Issue:
Startup progress bar page stalls when starting instance when old still stopping.
**How to reproduce the issue**

Use 0.9-dev.

Use KubeSpawner (or other spawner where can take a while to start and stop instances).

Select My Server to start an instance.

Once it is up and running, go to the Control Panel and select Stop My Server.

After a period this will change to show the My Server button again, but if the instance hasn't actually stopped by that point and you select My Server, the startup progress bar page comes up but stalls and doesn't do anything. The prior instance will be stopped, by no new instance will be created and progress bar page persists.

**What you expected to happen**

Should work.

Maybe need progress bar on stopping, or only show My Server again when confirmed stopped.

**What actually happens**

Startup progress bar page displays but doesn't do anything.

There are no exceptions in the log. You can only see how progress page comes up while existing instance hasn't yet stopped.

```

[I 2018-06-06 00:26:15.113 JupyterHub log:158] 200 GET /hub/home (grahamdumpleton@::ffff:10.128.2.1) 12.28ms
--
  | [I 2018-06-06 00:26:16.289 JupyterHub proxy:262] Removing user grahamdumpleton from proxy (/user/grahamdumpleton/)
  | 00:26:16.292 - info: [ConfigProxy] Removing route /user/grahamdumpleton
  | 00:26:16.292 - info: [ConfigProxy] 204 DELETE /api/routes/user/grahamdumpleton
  | [I 2018-06-06 00:26:16.293 JupyterHub spawner:1264] Deleting pod poc-dask-cluster-2-nb-grahamdumpleton
  | [W 2018-06-06 00:26:26.294 JupyterHub base:750] User grahamdumpleton: server is slow to stop
  | [I 2018-06-06 00:26:26.294 JupyterHub log:158] 202 DELETE /hub/api/users/grahamdumpleton/server (grahamdumpleton@::ffff:10.128.2.1) 10015.39ms
  | [I 2018-06-06 00:26:28.893 JupyterHub log:158] 302 GET /user/grahamdumpleton/ -> /hub/user/grahamdumpleton/ (@::ffff:10.128.2.1) 0.65ms
  | [I 2018-06-06 00:26:28.944 JupyterHub base:956] grahamdumpleton is pending stop
  | [I 2018-06-06 00:26:28.945 JupyterHub log:158] 200 GET /hub/user/grahamdumpleton/ (grahamdumpleton@::ffff:10.128.2.1) 7.61ms
  | [W 2018-06-06 00:26:29.476 JupyterHub web:1618] 400 GET /hub/api/users/grahamdumpleton/server/progress (::ffff:10.128.2.1): grahamdumpleton is not starting...
  | [W 2018-06-06 00:26:29.477 JupyterHub log:158] 400 GET /hub/api/users/grahamdumpleton/server/progress (grahamdumpleton@::ffff:10.128.2.1) 11.60ms
  | [I 2018-06-06 00:27:13.000 JupyterHub base:743] User grahamdumpleton server took 56.711 seconds to stop
  | 00:27:42.541 - info: [ConfigProxy] 200 GET /api/routes
  | [I 2018-06-06 00:27:42.542 JupyterHub proxy:299] Checking routes


```

**Share what version of JupyterHub you are using**

0.9-dev. Current master from repo.



Discussion:

Resolving patch:
diff --git a/jupyterhub/handlers/base.py b/jupyterhub/handlers/base.py
--- a/jupyterhub/handlers/base.py
+++ b/jupyterhub/handlers/base.py
@@ -942,7 +942,7 @@ async def get(self, name, user_path):
                 raise copy.copy(exc).with_traceback(exc.__traceback__)
 
             # check for pending spawn
-            if spawner.pending and spawner._spawn_future:
+            if spawner.pending == 'spawn' and spawner._spawn_future:
                 # wait on the pending spawn
                 self.log.debug("Waiting for %s pending %s", spawner._log_name, spawner.pending)
                 try:
@@ -952,14 +952,20 @@ async def get(self, name, user_path):
                     pass
 
             # we may have waited above, check pending again:
+            # page could be pending spawn *or* stop
             if spawner.pending:
                 self.log.info("%s is pending %s", spawner._log_name, spawner.pending)
                 # spawn has started, but not finished
                 self.statsd.incr('redirects.user_spawn_pending', 1)
                 url_parts = []
+                if spawner.pending == "stop":
+                    page = "stop_pending.html"
+                else:
+                    page = "spawn_pending.html"
                 html = self.render_template(
-                    "spawn_pending.html",
+                    page,
                     user=user,
+                    spawner=spawner,
                     progress_url=spawner._progress_url,
                 )
                 self.finish(html)


Test patch: