prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  No such file or directory "bokeh" - in release 1.9.2 (conda install)
  Get this error in my logs:
  
  ```
  scheduler_1 | distributed.scheduler - INFO -            http at:           172.17.0.4:9786
  scheduler_1 | distributed.scheduler - WARNING - Could not start Bokeh web UI
  scheduler_1 | Traceback (most recent call last):
  scheduler_1 |   File "/opt/conda/envs/fire/lib/python3.5/site-packages/distributed/cli/dscheduler.py", line scheduler_1 |     bokeh_proc[0] = subprocess.Popen(args)
  scheduler_1 |   File "/opt/conda/envs/fire/lib/python3.5/subprocess.py", line 950, in __init__
  scheduler_1 |     restore_signals, start_new_session)
  scheduler_1 |   File "/opt/conda/envs/fire/lib/python3.5/subprocess.py", line 1544, in _execute_child
  scheduler_1 |     raise child_exception_type(errno_num, err_msg)
  scheduler_1 | FileNotFoundError: [Errno 2] No such file or directory: 'bokeh'
  scheduler_1 | distributed.core - INFO - Connection from 172.17.0.6:60119 to Scheduler
  scheduler_1 | distributed.scheduler - INFO - Register 172.17.0.6:5700
  scheduler_1 | distributed.scheduler - INFO - Starting worker compute stream, 172.17.0.6:5700
  ```
  
  
  </issue>
  <code>
  [start of distributed/cli/dscheduler.py]
  1 from __future__ import print_function, division, absolute_import
  2 
  3 import logging
  4 import os
  5 import socket
  6 import subprocess
  7 from sys import argv, exit
  8 from time import sleep
  9 
  10 import click
  11 
  12 import distributed
  13 from distributed import Scheduler
  14 from distributed.utils import get_ip
  15 from distributed.http import HTTPScheduler
  16 from distributed.cli.utils import check_python_3
  17 from tornado.ioloop import IOLoop
  18 
  19 logger = logging.getLogger('distributed.scheduler')
  20 
  21 ip = get_ip()
  22 
  23 import signal
  24 
  25 bokeh_proc = [False]
  26 
  27 
  28 def handle_signal(sig, frame):
  29     if bokeh_proc[0]:
  30         bokeh_proc[0].terminate()
  31     IOLoop.instance().add_callback(IOLoop.instance().stop)
  32 
  33 signal.signal(signal.SIGINT, handle_signal)
  34 signal.signal(signal.SIGTERM, handle_signal)
  35 
  36 
  37 @click.command()
  38 @click.argument('center', type=str, default='')
  39 @click.option('--port', type=int, default=8786, help="Serving port")
  40 @click.option('--http-port', type=int, default=9786, help="HTTP port")
  41 @click.option('--bokeh-port', type=int, default=8787, help="HTTP port")
  42 @click.option('--bokeh/--no-bokeh', '_bokeh', default=True, show_default=True,
  43               required=False, help="Launch Bokeh Web UI")
  44 @click.option('--host', type=str, default=ip,
  45               help="Serving host defaults to %s" % ip)
  46 @click.option('--show/--no-show', default=False, help="Show web UI")
  47 def main(center, host, port, http_port, bokeh_port, show, _bokeh):
  48     ip = socket.gethostbyname(host)
  49     loop = IOLoop.current()
  50     scheduler = Scheduler(center, ip=ip,
  51                           services={('http', http_port): HTTPScheduler})
  52     if center:
  53         loop.run_sync(scheduler.sync_center)
  54     scheduler.start(port)
  55 
  56     if _bokeh:
  57         try:
  58             import bokeh
  59             import distributed.bokeh
  60             hosts = ['%s:%d' % (h, bokeh_port) for h in
  61                      ['localhost', '127.0.0.1', ip, socket.gethostname(), host]]
  62             dirname = os.path.dirname(distributed.__file__)
  63             paths = [os.path.join(dirname, 'bokeh', name)
  64                      for name in ['status', 'tasks']]
  65             args = (['bokeh', 'serve'] + paths +
  66                     ['--log-level', 'warning',
  67                      '--check-unused-sessions=50',
  68                      '--unused-session-lifetime=1',
  69                      '--port', str(bokeh_port)] +
  70                      sum([['--host', host] for host in hosts], []))
  71             if show:
  72                 args.append('--show')
  73             bokeh_proc[0] = subprocess.Popen(args)
  74 
  75             logger.info(" Start Bokeh UI at:        http://%s:%d/status/"
  76                         % (ip, bokeh_port))
  77         except ImportError:
  78             logger.info("Please install Bokeh to get Web UI")
  79         except Exception as e:
  80             logger.warn("Could not start Bokeh web UI", exc_info=True)
  81 
  82     loop.start()
  83     loop.close()
  84     scheduler.stop()
  85     bokeh_proc[0].terminate()
  86 
  87     logger.info("End scheduler at %s:%d", ip, port)
  88 
  89 
  90 def go():
  91     check_python_3()
  92     main()
  93 
  94 
  95 if __name__ == '__main__':
  96     go()
  97
  [end of distributed/cli/dscheduler.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/distributed/cli/dscheduler.py b/distributed/cli/dscheduler.py
  --- a/distributed/cli/dscheduler.py
  +++ b/distributed/cli/dscheduler.py
  @@ -1,9 +1,9 @@
   from __future__ import print_function, division, absolute_import
   
   import logging
  +import multiprocessing
   import os
   import socket
  -import subprocess
   from sys import argv, exit
   from time import sleep
   
  @@ -22,12 +22,8 @@
   
   import signal
   
  -bokeh_proc = [False]
  -
   
   def handle_signal(sig, frame):
  -    if bokeh_proc[0]:
  -        bokeh_proc[0].terminate()
       IOLoop.instance().add_callback(IOLoop.instance().stop)
   
   signal.signal(signal.SIGINT, handle_signal)
  @@ -70,7 +66,10 @@
                        sum([['--host', host] for host in hosts], []))
               if show:
                   args.append('--show')
  -            bokeh_proc[0] = subprocess.Popen(args)
  +            from bokeh.command.bootstrap import main
  +            proc = multiprocessing.Process(target=main, args=(args,))
  +            proc.daemon = True
  +            proc.start()
   
               logger.info(" Start Bokeh UI at:        http://%s:%d/status/"
                           % (ip, bokeh_port))
  @@ -82,7 +81,7 @@
       loop.start()
       loop.close()
       scheduler.stop()
  -    bokeh_proc[0].terminate()
  +    proc.terminate()
   
       logger.info("End scheduler at %s:%d", ip, port)
  
verification_info: {"golden_diff": "diff --git a/distributed/cli/dscheduler.py b/distributed/cli/dscheduler.py\n--- a/distributed/cli/dscheduler.py\n+++ b/distributed/cli/dscheduler.py\n@@ -1,9 +1,9 @@\n from __future__ import print_function, division, absolute_import\n \n import logging\n+import multiprocessing\n import os\n import socket\n-import subprocess\n from sys import argv, exit\n from time import sleep\n \n@@ -22,12 +22,8 @@\n \n import signal\n \n-bokeh_proc = [False]\n-\n \n def handle_signal(sig, frame):\n-    if bokeh_proc[0]:\n-        bokeh_proc[0].terminate()\n     IOLoop.instance().add_callback(IOLoop.instance().stop)\n \n signal.signal(signal.SIGINT, handle_signal)\n@@ -70,7 +66,10 @@\n                      sum([['--host', host] for host in hosts], []))\n             if show:\n                 args.append('--show')\n-            bokeh_proc[0] = subprocess.Popen(args)\n+            from bokeh.command.bootstrap import main\n+            proc = multiprocessing.Process(target=main, args=(args,))\n+            proc.daemon = True\n+            proc.start()\n \n             logger.info(\" Start Bokeh UI at:        http://%s:%d/status/\"\n                         % (ip, bokeh_port))\n@@ -82,7 +81,7 @@\n     loop.start()\n     loop.close()\n     scheduler.stop()\n-    bokeh_proc[0].terminate()\n+    proc.terminate()\n \n     logger.info(\"End scheduler at %s:%d\", ip, port)\n", "issue": "No such file or directory \"bokeh\" - in release 1.9.2 (conda install)\nGet this error in my logs:\n\n```\nscheduler_1 | distributed.scheduler - INFO -            http at:           172.17.0.4:9786\nscheduler_1 | distributed.scheduler - WARNING - Could not start Bokeh web UI\nscheduler_1 | Traceback (most recent call last):\nscheduler_1 |   File \"/opt/conda/envs/fire/lib/python3.5/site-packages/distributed/cli/dscheduler.py\", line scheduler_1 |     bokeh_proc[0] = subprocess.Popen(args)\nscheduler_1 |   File \"/opt/conda/envs/fire/lib/python3.5/subprocess.py\", line 950, in __init__\nscheduler_1 |     restore_signals, start_new_session)\nscheduler_1 |   File \"/opt/conda/envs/fire/lib/python3.5/subprocess.py\", line 1544, in _execute_child\nscheduler_1 |     raise child_exception_type(errno_num, err_msg)\nscheduler_1 | FileNotFoundError: [Errno 2] No such file or directory: 'bokeh'\nscheduler_1 | distributed.core - INFO - Connection from 172.17.0.6:60119 to Scheduler\nscheduler_1 | distributed.scheduler - INFO - Register 172.17.0.6:5700\nscheduler_1 | distributed.scheduler - INFO - Starting worker compute stream, 172.17.0.6:5700\n```\n\n", "before_files": [{"content": "from __future__ import print_function, division, absolute_import\n\nimport logging\nimport os\nimport socket\nimport subprocess\nfrom sys import argv, exit\nfrom time import sleep\n\nimport click\n\nimport distributed\nfrom distributed import Scheduler\nfrom distributed.utils import get_ip\nfrom distributed.http import HTTPScheduler\nfrom distributed.cli.utils import check_python_3\nfrom tornado.ioloop import IOLoop\n\nlogger = logging.getLogger('distributed.scheduler')\n\nip = get_ip()\n\nimport signal\n\nbokeh_proc = [False]\n\n\ndef handle_signal(sig, frame):\n    if bokeh_proc[0]:\n        bokeh_proc[0].terminate()\n    IOLoop.instance().add_callback(IOLoop.instance().stop)\n\nsignal.signal(signal.SIGINT, handle_signal)\nsignal.signal(signal.SIGTERM, handle_signal)\n\n\n@click.command()\n@click.argument('center', type=str, default='')\n@click.option('--port', type=int, default=8786, help=\"Serving port\")\n@click.option('--http-port', type=int, default=9786, help=\"HTTP port\")\n@click.option('--bokeh-port', type=int, default=8787, help=\"HTTP port\")\n@click.option('--bokeh/--no-bokeh', '_bokeh', default=True, show_default=True,\n              required=False, help=\"Launch Bokeh Web UI\")\n@click.option('--host', type=str, default=ip,\n              help=\"Serving host defaults to %s\" % ip)\n@click.option('--show/--no-show', default=False, help=\"Show web UI\")\ndef main(center, host, port, http_port, bokeh_port, show, _bokeh):\n    ip = socket.gethostbyname(host)\n    loop = IOLoop.current()\n    scheduler = Scheduler(center, ip=ip,\n                          services={('http', http_port): HTTPScheduler})\n    if center:\n        loop.run_sync(scheduler.sync_center)\n    scheduler.start(port)\n\n    if _bokeh:\n        try:\n            import bokeh\n            import distributed.bokeh\n            hosts = ['%s:%d' % (h, bokeh_port) for h in\n                     ['localhost', '127.0.0.1', ip, socket.gethostname(), host]]\n            dirname = os.path.dirname(distributed.__file__)\n            paths = [os.path.join(dirname, 'bokeh', name)\n                     for name in ['status', 'tasks']]\n            args = (['bokeh', 'serve'] + paths +\n                    ['--log-level', 'warning',\n                     '--check-unused-sessions=50',\n                     '--unused-session-lifetime=1',\n                     '--port', str(bokeh_port)] +\n                     sum([['--host', host] for host in hosts], []))\n            if show:\n                args.append('--show')\n            bokeh_proc[0] = subprocess.Popen(args)\n\n            logger.info(\" Start Bokeh UI at:        http://%s:%d/status/\"\n                        % (ip, bokeh_port))\n        except ImportError:\n            logger.info(\"Please install Bokeh to get Web UI\")\n        except Exception as e:\n            logger.warn(\"Could not start Bokeh web UI\", exc_info=True)\n\n    loop.start()\n    loop.close()\n    scheduler.stop()\n    bokeh_proc[0].terminate()\n\n    logger.info(\"End scheduler at %s:%d\", ip, port)\n\n\ndef go():\n    check_python_3()\n    main()\n\n\nif __name__ == '__main__':\n    go()\n", "path": "distributed/cli/dscheduler.py"}]}