prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  ENH: auto find available port for API
  ### Describe the bug
  ```
  ~ ❯ xinference                                                                                       6s  base 18:24:18
  Traceback (most recent call last):
    File "/Users/hekaisheng/miniconda3/bin/xinference", line 33, in <module>
      sys.exit(load_entry_point('xinference', 'console_scripts', 'xinference')())
    File "/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py", line 1128, in __call__
      return self.main(*args, **kwargs)
    File "/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py", line 1053, in main
      rv = self.invoke(ctx)
    File "/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py", line 1637, in invoke
      super().invoke(ctx)
    File "/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py", line 1395, in invoke
      return ctx.invoke(self.callback, **ctx.params)
    File "/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py", line 754, in invoke
      return __callback(*args, **kwargs)
    File "/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/decorators.py", line 26, in new_func
      return f(get_current_context(), *args, **kwargs)
    File "/Users/hekaisheng/Documents/projects/inference/xinference/deploy/cmdline.py", line 51, in cli
      main(
    File "/Users/hekaisheng/Documents/projects/inference/xinference/deploy/local.py", line 50, in main
      loop.run_until_complete(task)
    File "/Users/hekaisheng/miniconda3/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
      return future.result()
    File "/Users/hekaisheng/Documents/projects/inference/xinference/deploy/local.py", line 36, in _start_local_cluster
      url = await start_supervisor_components(address=address, host=host, port=port)
    File "/Users/hekaisheng/Documents/projects/inference/xinference/deploy/supervisor.py", line 35, in start_supervisor_components
      sock.bind((host, port))
  OSError: [Errno 48] Address already in use
  ```
  
  Use available port if users not specify.
  
  </issue>
  <code>
  [start of xinference/deploy/supervisor.py]
  1 # Copyright 2022-2023 XProbe Inc.
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #      http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 import asyncio
  16 import logging
  17 import socket
  18 from typing import Dict, Optional
  19 
  20 import xoscar as xo
  21 
  22 from ..core.gradio import GradioApp
  23 from ..core.restful_api import RESTfulAPIActor
  24 from ..core.service import SupervisorActor
  25 
  26 logger = logging.getLogger("xinference")
  27 
  28 
  29 async def start_supervisor_components(address: str, host: str, port: int):
  30     await xo.create_actor(SupervisorActor, address=address, uid=SupervisorActor.uid())
  31     gradio_block = GradioApp(address).build()
  32     # create a socket for RESTful API
  33     sockets = []
  34     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  35     sock.bind((host, port))
  36     sockets.append(sock)
  37     restful_actor = await xo.create_actor(
  38         RESTfulAPIActor,
  39         address=address,
  40         uid=RESTfulAPIActor.uid(),
  41         sockets=sockets,
  42         gradio_block=gradio_block,
  43     )
  44     await restful_actor.serve()
  45     url = f"http://{host}:{port}"
  46     logger.info(f"Server address: {url}")
  47     return url
  48 
  49 
  50 async def _start_supervisor(
  51     address: str, host: str, port: int, logging_conf: Optional[Dict] = None
  52 ):
  53     pool = None
  54     try:
  55         pool = await xo.create_actor_pool(
  56             address=address, n_process=0, logging_conf=logging_conf
  57         )
  58         await start_supervisor_components(address=address, host=host, port=port)
  59         await pool.join()
  60     except asyncio.exceptions.CancelledError:
  61         if pool is not None:
  62             await pool.stop()
  63 
  64 
  65 def main(*args, **kwargs):
  66     loop = asyncio.get_event_loop()
  67     task = loop.create_task(_start_supervisor(*args, **kwargs))
  68 
  69     try:
  70         loop.run_until_complete(task)
  71     except KeyboardInterrupt:
  72         task.cancel()
  73         loop.run_until_complete(task)
  74         # avoid displaying exception-unhandled warnings
  75         task.exception()
  76
  [end of xinference/deploy/supervisor.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/xinference/deploy/supervisor.py b/xinference/deploy/supervisor.py
  --- a/xinference/deploy/supervisor.py
  +++ b/xinference/deploy/supervisor.py
  @@ -18,7 +18,9 @@
   from typing import Dict, Optional
   
   import xoscar as xo
  +from xoscar.utils import get_next_port
   
  +from ..constants import XINFERENCE_DEFAULT_ENDPOINT_PORT
   from ..core.gradio import GradioApp
   from ..core.restful_api import RESTfulAPIActor
   from ..core.service import SupervisorActor
  @@ -30,10 +32,26 @@
       await xo.create_actor(SupervisorActor, address=address, uid=SupervisorActor.uid())
       gradio_block = GradioApp(address).build()
       # create a socket for RESTful API
  -    sockets = []
  -    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  -    sock.bind((host, port))
  -    sockets.append(sock)
  +    try:
  +        sockets = []
  +        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  +        sock.bind((host, port))
  +        sockets.append(sock)
  +    except OSError:
  +        if port is XINFERENCE_DEFAULT_ENDPOINT_PORT:
  +            while True:
  +                try:
  +                    sockets = []
  +                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  +                    port = get_next_port()
  +                    sock.bind((host, port))
  +                    sockets.append(sock)
  +                    break
  +                except OSError:
  +                    pass
  +        else:
  +            raise OSError
  +
       restful_actor = await xo.create_actor(
           RESTfulAPIActor,
           address=address,
  
verification_info: {"golden_diff": "diff --git a/xinference/deploy/supervisor.py b/xinference/deploy/supervisor.py\n--- a/xinference/deploy/supervisor.py\n+++ b/xinference/deploy/supervisor.py\n@@ -18,7 +18,9 @@\n from typing import Dict, Optional\n \n import xoscar as xo\n+from xoscar.utils import get_next_port\n \n+from ..constants import XINFERENCE_DEFAULT_ENDPOINT_PORT\n from ..core.gradio import GradioApp\n from ..core.restful_api import RESTfulAPIActor\n from ..core.service import SupervisorActor\n@@ -30,10 +32,26 @@\n     await xo.create_actor(SupervisorActor, address=address, uid=SupervisorActor.uid())\n     gradio_block = GradioApp(address).build()\n     # create a socket for RESTful API\n-    sockets = []\n-    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n-    sock.bind((host, port))\n-    sockets.append(sock)\n+    try:\n+        sockets = []\n+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+        sock.bind((host, port))\n+        sockets.append(sock)\n+    except OSError:\n+        if port is XINFERENCE_DEFAULT_ENDPOINT_PORT:\n+            while True:\n+                try:\n+                    sockets = []\n+                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n+                    port = get_next_port()\n+                    sock.bind((host, port))\n+                    sockets.append(sock)\n+                    break\n+                except OSError:\n+                    pass\n+        else:\n+            raise OSError\n+\n     restful_actor = await xo.create_actor(\n         RESTfulAPIActor,\n         address=address,\n", "issue": "ENH: auto find available port for API\n### Describe the bug\r\n```\r\n~ \u276f xinference                                                                                       6s \ue73c base 18:24:18\r\nTraceback (most recent call last):\r\n  File \"/Users/hekaisheng/miniconda3/bin/xinference\", line 33, in <module>\r\n    sys.exit(load_entry_point('xinference', 'console_scripts', 'xinference')())\r\n  File \"/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py\", line 1128, in __call__\r\n    return self.main(*args, **kwargs)\r\n  File \"/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py\", line 1053, in main\r\n    rv = self.invoke(ctx)\r\n  File \"/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py\", line 1637, in invoke\r\n    super().invoke(ctx)\r\n  File \"/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py\", line 1395, in invoke\r\n    return ctx.invoke(self.callback, **ctx.params)\r\n  File \"/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/core.py\", line 754, in invoke\r\n    return __callback(*args, **kwargs)\r\n  File \"/Users/hekaisheng/miniconda3/lib/python3.9/site-packages/click/decorators.py\", line 26, in new_func\r\n    return f(get_current_context(), *args, **kwargs)\r\n  File \"/Users/hekaisheng/Documents/projects/inference/xinference/deploy/cmdline.py\", line 51, in cli\r\n    main(\r\n  File \"/Users/hekaisheng/Documents/projects/inference/xinference/deploy/local.py\", line 50, in main\r\n    loop.run_until_complete(task)\r\n  File \"/Users/hekaisheng/miniconda3/lib/python3.9/asyncio/base_events.py\", line 647, in run_until_complete\r\n    return future.result()\r\n  File \"/Users/hekaisheng/Documents/projects/inference/xinference/deploy/local.py\", line 36, in _start_local_cluster\r\n    url = await start_supervisor_components(address=address, host=host, port=port)\r\n  File \"/Users/hekaisheng/Documents/projects/inference/xinference/deploy/supervisor.py\", line 35, in start_supervisor_components\r\n    sock.bind((host, port))\r\nOSError: [Errno 48] Address already in use\r\n```\r\n\r\nUse available port if users not specify.\n", "before_files": [{"content": "# Copyright 2022-2023 XProbe Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport asyncio\nimport logging\nimport socket\nfrom typing import Dict, Optional\n\nimport xoscar as xo\n\nfrom ..core.gradio import GradioApp\nfrom ..core.restful_api import RESTfulAPIActor\nfrom ..core.service import SupervisorActor\n\nlogger = logging.getLogger(\"xinference\")\n\n\nasync def start_supervisor_components(address: str, host: str, port: int):\n    await xo.create_actor(SupervisorActor, address=address, uid=SupervisorActor.uid())\n    gradio_block = GradioApp(address).build()\n    # create a socket for RESTful API\n    sockets = []\n    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    sock.bind((host, port))\n    sockets.append(sock)\n    restful_actor = await xo.create_actor(\n        RESTfulAPIActor,\n        address=address,\n        uid=RESTfulAPIActor.uid(),\n        sockets=sockets,\n        gradio_block=gradio_block,\n    )\n    await restful_actor.serve()\n    url = f\"http://{host}:{port}\"\n    logger.info(f\"Server address: {url}\")\n    return url\n\n\nasync def _start_supervisor(\n    address: str, host: str, port: int, logging_conf: Optional[Dict] = None\n):\n    pool = None\n    try:\n        pool = await xo.create_actor_pool(\n            address=address, n_process=0, logging_conf=logging_conf\n        )\n        await start_supervisor_components(address=address, host=host, port=port)\n        await pool.join()\n    except asyncio.exceptions.CancelledError:\n        if pool is not None:\n            await pool.stop()\n\n\ndef main(*args, **kwargs):\n    loop = asyncio.get_event_loop()\n    task = loop.create_task(_start_supervisor(*args, **kwargs))\n\n    try:\n        loop.run_until_complete(task)\n    except KeyboardInterrupt:\n        task.cancel()\n        loop.run_until_complete(task)\n        # avoid displaying exception-unhandled warnings\n        task.exception()\n", "path": "xinference/deploy/supervisor.py"}]}