|
| 1 | +import logging |
| 2 | + |
1 | 3 | import dash |
2 | 4 | import os |
3 | 5 | import requests |
|
9 | 11 | import sys |
10 | 12 | import inspect |
11 | 13 | import traceback |
| 14 | +import threading |
12 | 15 | import warnings |
13 | 16 | import queue |
14 | 17 |
|
|
18 | 21 | from ansi2html import Ansi2HTMLConverter |
19 | 22 | import uuid |
20 | 23 |
|
| 24 | +from werkzeug.serving import make_server |
| 25 | + |
21 | 26 | from .comms import _dash_comm, _jupyter_config, _request_jupyter_config |
22 | | -from ._stoppable_thread import StoppableThread |
23 | 27 |
|
24 | 28 |
|
25 | 29 | def _get_skip(error: Exception): |
@@ -50,7 +54,7 @@ class JupyterDash(dash.Dash): |
50 | 54 | _in_colab = "google.colab" in sys.modules |
51 | 55 | _token = str(uuid.uuid4()) |
52 | 56 |
|
53 | | - _server_threads = {} |
| 57 | + _servers = {} |
54 | 58 |
|
55 | 59 | @classmethod |
56 | 60 | def infer_jupyter_proxy_config(cls): |
@@ -147,6 +151,7 @@ def alive(): |
147 | 151 | return 'Alive' |
148 | 152 |
|
149 | 153 | self.server.logger.disabled = True |
| 154 | + self._exception_handling_added = False |
150 | 155 |
|
151 | 156 | def run( |
152 | 157 | self, |
@@ -186,11 +191,8 @@ def run( |
186 | 191 | return |
187 | 192 |
|
188 | 193 | # Get host and port |
189 | | - host = kwargs.get("host", os.getenv("HOST", "127.0.0.1")) |
190 | | - port = kwargs.get("port", os.getenv("PORT", "8050")) |
191 | | - |
192 | | - kwargs['host'] = host |
193 | | - kwargs['port'] = port |
| 194 | + host = kwargs.pop("host", os.getenv("HOST", "127.0.0.1")) |
| 195 | + port = kwargs.pop("port", os.getenv("PORT", "8050")) |
194 | 196 |
|
195 | 197 | # Validate / infer display mode |
196 | 198 | if JupyterDash._in_colab: |
@@ -222,11 +224,10 @@ def run( |
222 | 224 | inline_exceptions = mode == "inline" |
223 | 225 |
|
224 | 226 | # Terminate any existing server using this port |
225 | | - old_server = self._server_threads.get((host, port)) |
| 227 | + old_server = self._servers.get((host, port)) |
226 | 228 | if old_server: |
227 | | - old_server.kill() |
228 | | - old_server.join() |
229 | | - del self._server_threads[(host, port)] |
| 229 | + old_server.shutdown() |
| 230 | + del self._servers[(host, port)] |
230 | 231 |
|
231 | 232 | # Configure pathname prefix |
232 | 233 | requests_pathname_prefix = self.config.get('requests_pathname_prefix', None) |
@@ -302,25 +303,32 @@ def run( |
302 | 303 |
|
303 | 304 | err_q = queue.Queue() |
304 | 305 |
|
| 306 | + server = make_server( |
| 307 | + host, port, self.server, |
| 308 | + threaded=True, |
| 309 | + processes=0 |
| 310 | + ) |
| 311 | + logging.getLogger("werkzeug").setLevel(logging.ERROR) |
| 312 | + |
305 | 313 | @retry( |
306 | 314 | stop_max_attempt_number=15, |
307 | 315 | wait_exponential_multiplier=100, |
308 | 316 | wait_exponential_max=1000 |
309 | 317 | ) |
310 | 318 | def run(): |
311 | 319 | try: |
312 | | - super_run_server(**kwargs) |
| 320 | + server.serve_forever() |
313 | 321 | except SystemExit: |
314 | 322 | pass |
315 | 323 | except Exception as error: |
316 | 324 | err_q.put(error) |
317 | 325 | raise error |
318 | 326 |
|
319 | | - thread = StoppableThread(target=run) |
320 | | - thread.setDaemon(True) |
| 327 | + thread = threading.Thread(target=run) |
| 328 | + thread.daemon = True |
321 | 329 | thread.start() |
322 | 330 |
|
323 | | - self._server_threads[(host, port)] = thread |
| 331 | + self._servers[(host, port)] = server |
324 | 332 |
|
325 | 333 | # Wait for server to start up |
326 | 334 | alive_url = "http://{host}:{port}/_alive_{token}".format( |
|
0 commit comments