gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
32.49k stars 2.44k forks source link

blocks close will raise error #8352

Open DoiiarX opened 4 months ago

DoiiarX commented 4 months ago

Describe the bug

I use the close() method to terminate and restart a block. However, I noticed some differences in the implementation within the Gradio source code:

In the file .conda\lib\site-packages\gradio\routes.py, on line 620, the code for stopping the stream is defined as follows:

async def stop_stream():
    await app.stop_event.wait()
    return "stop"

Meanwhile, in the close() method located in .conda\lib\site-packages\gradio\blocks.py on line 2490, the stop_event is triggered by:

self.app.stop_event.set()

This indicates that the close() method directly sets the stop_event, while the stop_stream function waits for this event to be set before proceeding.

Certainly, here's a continuation of your text, explaining the issue with the error:


However, this implementation leads to an error when await app.stop_event.wait() is executed. The error message is as follows:

|   File ".conda\lib\site-packages\gradio\routes.py", line 620, in stop_stream
|     # await app.stop_event.wait()
| AttributeError: 'NoneType' object has no attribute 'wait'

This error indicates that app.stop_event is None at the time stop_stream tries to call wait() on it. This could happen if app.stop_event is not properly initialized before stop_stream is called, or if it has been set to None elsewhere in the code prior to this call. It is essential to ensure that stop_event is correctly initialized and maintained throughout the application lifecycle to prevent such errors.

Have you searched existing issues? πŸ”Ž

Reproduction

import gradio as gr
import asyncio

def run_block():
    with gr.Blocks() as demo:
        btn = gr.Button("关闭幢重启")

        def restart_interface():
            print("closeing...")
            demo.close()  # close
            print("closed. restart...")
            run_block()  #restart

        btn.click(restart_interface)

    demo.launch()

run_block()

Screenshot

No response

Logs

+ Exception Group Traceback (most recent call last):
  |   File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 407, in run_asgi
  |     result = await app(  # type: ignore[func-returns-value]
  |   File "xxx.conda\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 69, in __call__
  |     return await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\fastapi\applications.py", line 1054, in __call__
  |     await super().__call__(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\applications.py", line 123, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
  |     await self.app(scope, receive, _send)
  |   File "xxx.conda\lib\site-packages\gradio\route_utils.py", line 689, in __call__
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\exceptions.py", line 65, in __call__
  |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 756, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 776, in app
  |     await route.handle(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 297, in handle
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 77, in app
  |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 75, in app
  |     await response(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 258, in __call__
  |     async with anyio.create_task_group() as task_group:
  |   File "xxx.conda\lib\site-packages\anyio\_backends\_asyncio.py", line 678, in __aexit__
  |     raise BaseExceptionGroup(
  | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    |     await func()
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 250, in stream_response
    |     async for chunk in self.body_iterator:
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in iterator
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in <listcomp>
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 620, in stop_stream
    |     await app.stop_event.wait()
    | AttributeError: 'NoneType' object has no attribute 'wait'
    +------------------------------------
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 265, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    await func()
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 238, in listen_for_disconnect
    message = await receive()
  File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 535, in receive
    await self.message_event.wait()
  File "xxx.conda\lib\asyncio\locks.py", line 214, in wait
    await fut
asyncio.exceptions.CancelledError: Cancelled by cancel scope 235cdb2c970

During handling of the above exception, another exception occurred:

  + Exception Group Traceback (most recent call last):
  |   File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 407, in run_asgi
  |     result = await app(  # type: ignore[func-returns-value]
  |   File "xxx.conda\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 69, in __call__
  |     return await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\fastapi\applications.py", line 1054, in __call__
  |     await super().__call__(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\applications.py", line 123, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
  |     await self.app(scope, receive, _send)
  |   File "xxx.conda\lib\site-packages\gradio\route_utils.py", line 689, in __call__
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\exceptions.py", line 65, in __call__
  |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 756, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 776, in app
  |     await route.handle(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 297, in handle
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 77, in app
  |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 75, in app
  |     await response(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 258, in __call__
  |     async with anyio.create_task_group() as task_group:
  |   File "xxx.conda\lib\site-packages\anyio\_backends\_asyncio.py", line 678, in __aexit__
  |     raise BaseExceptionGroup(
  | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    |     await func()
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 250, in stream_response
    |     async for chunk in self.body_iterator:
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in iterator
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in <listcomp>
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 620, in stop_stream
    |     await app.stop_event.wait()
    | AttributeError: 'NoneType' object has no attribute 'wait'
    +------------------------------------
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 265, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    await func()
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 238, in listen_for_disconnect
    message = await receive()
  File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 535, in receive
    await self.message_event.wait()
  File "xxx.conda\lib\asyncio\locks.py", line 214, in wait
    await fut
asyncio.exceptions.CancelledError: Cancelled by cancel scope 235cdb2ccd0

During handling of the above exception, another exception occurred:

  + Exception Group Traceback (most recent call last):
  |   File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 407, in run_asgi
  |     result = await app(  # type: ignore[func-returns-value]
  |   File "xxx.conda\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 69, in __call__
  |     return await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\fastapi\applications.py", line 1054, in __call__
  |     await super().__call__(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\applications.py", line 123, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
  |     await self.app(scope, receive, _send)
  |   File "xxx.conda\lib\site-packages\gradio\route_utils.py", line 689, in __call__
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\exceptions.py", line 65, in __call__
  |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 756, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 776, in app
  |     await route.handle(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 297, in handle
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 77, in app
  |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 75, in app
  |     await response(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 258, in __call__
  |     async with anyio.create_task_group() as task_group:
  |   File "xxx.conda\lib\site-packages\anyio\_backends\_asyncio.py", line 678, in __aexit__
  |     raise BaseExceptionGroup(
  | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    |     await func()
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 250, in stream_response
    |     async for chunk in self.body_iterator:
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in iterator
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in <listcomp>
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 620, in stop_stream
    |     await app.stop_event.wait()
    | AttributeError: 'NoneType' object has no attribute 'wait'
    +------------------------------------
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 265, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    await func()
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 238, in listen_for_disconnect
    message = await receive()
  File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 535, in receive
    await self.message_event.wait()
  File "xxx.conda\lib\asyncio\locks.py", line 214, in wait
    await fut
asyncio.exceptions.CancelledError: Cancelled by cancel scope 235ce15e980

During handling of the above exception, another exception occurred:

  + Exception Group Traceback (most recent call last):
  |   File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 407, in run_asgi
  |     result = await app(  # type: ignore[func-returns-value]
  |   File "xxx.conda\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 69, in __call__
  |     return await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\fastapi\applications.py", line 1054, in __call__
  |     await super().__call__(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\applications.py", line 123, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
  |     await self.app(scope, receive, _send)
  |   File "xxx.conda\lib\site-packages\gradio\route_utils.py", line 689, in __call__
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\exceptions.py", line 65, in __call__
  |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 756, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 776, in app
  |     await route.handle(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 297, in handle
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 77, in app
  |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 75, in app
  |     await response(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 258, in __call__
  |     async with anyio.create_task_group() as task_group:
  |   File "xxx.conda\lib\site-packages\anyio\_backends\_asyncio.py", line 678, in __aexit__
  |     raise BaseExceptionGroup(
  | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    |     await func()
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 250, in stream_response
    |     async for chunk in self.body_iterator:
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in iterator
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in <listcomp>
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 620, in stop_stream
    |     await app.stop_event.wait()
    | AttributeError: 'NoneType' object has no attribute 'wait'
    +------------------------------------
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 265, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    await func()
  File "xxx.conda\lib\site-packages\starlette\responses.py", line 238, in listen_for_disconnect
    message = await receive()
  File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 535, in receive
    await self.message_event.wait()
  File "xxx.conda\lib\asyncio\locks.py", line 214, in wait
    await fut
asyncio.exceptions.CancelledError: Cancelled by cancel scope 235ce15f520

During handling of the above exception, another exception occurred:

  + Exception Group Traceback (most recent call last):
  |   File "xxx.conda\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 407, in run_asgi
  |     result = await app(  # type: ignore[func-returns-value]
  |   File "xxx.conda\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 69, in __call__
  |     return await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\fastapi\applications.py", line 1054, in __call__
  |     await super().__call__(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\applications.py", line 123, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
  |     await self.app(scope, receive, _send)
  |   File "xxx.conda\lib\site-packages\gradio\route_utils.py", line 689, in __call__
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\middleware\exceptions.py", line 65, in __call__
  |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 756, in __call__
  |     await self.middleware_stack(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 776, in app
  |     await route.handle(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 297, in handle
  |     await self.app(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 77, in app
  |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
  |     raise exc
  |   File "xxx.conda\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
  |     await app(scope, receive, sender)
  |   File "xxx.conda\lib\site-packages\starlette\routing.py", line 75, in app
  |     await response(scope, receive, send)
  |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 258, in __call__
  |     async with anyio.create_task_group() as task_group:
  |   File "xxx.conda\lib\site-packages\anyio\_backends\_asyncio.py", line 678, in __aexit__
  |     raise BaseExceptionGroup(
  | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 261, in wrap
    |     await func()
    |   File "xxx.conda\lib\site-packages\starlette\responses.py", line 250, in stream_response
    |     async for chunk in self.body_iterator:
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in iterator
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 635, in <listcomp>
    |     done = [d.result() for d in done]
    |   File "xxx.conda\lib\site-packages\gradio\routes.py", line 620, in stop_stream
    |     # await app.stop_event.wait()
    | AttributeError: 'NoneType' object has no attribute 'wait'
    +------------------------------------
Keyboard interruption in main thread... closing server.

System Info

4.27.0

Severity

I can work around it

DoiiarX commented 4 months ago

fix it here.

and need both use gr.close_all() and blocks.close() together

https://github.com/gradio-app/gradio/pull/8357