mongkok / fastapi-debug-toolbar

A debug toolbar for FastAPI.
https://fastapi-debug-toolbar.domake.io
BSD 3-Clause "New" or "Revised" License
134 stars 13 forks source link

RuntimeError: Failed to stop profiling. Make sure that you start/stop profiling on the same thread. #51

Open MartinSchmidt123 opened 3 months ago

MartinSchmidt123 commented 3 months ago

I am not quite sure what to do about the error

RuntimeError: Failed to stop profiling. Make sure that you start/stop profiling on the same thread.

It happens regularly, but not for every request. It also affects different endpoints. The endpoints use SQLAlchemy with the following config:

db_engine = create_engine(
    f"mysql+mysqlconnector://{config.DB_USER}:{config.DB_PASSWORD}@{config.DB_HOST}:{config.DB_PORT}/{config.DB_NAME}",
    connect_args={"connect_timeout": 10},
    pool_recycle=3600,
    pool_pre_ping=True,
    pool_size=10,
    max_overflow=40
    )

For example:

@router.get("/get_list", status_code=200, response_model=list[SchemaOut],)
def get_list(
        session: Session = Depends(create_session),
):
    data = session.query(
        [..]
    ).join(
        [..]
    ).filter(
        [..]
    ).order_by(
        [..]
    ).all()

    return data

There is only one uvicorn worker that is started with

pipenv run uvicorn app.api:app

Is it possible to disable profiling? It seems optional in the web ui. I would also be thankful for help finding the source of the error. I do not really know how to debug this.

Full stacktrace:

ERROR:    Exception in ASGI application
  + Exception Group Traceback (most recent call last):
  |   File "[..].venv/lib/python3.11/site-packages/starlette/_utils.py", line 87, in collapse_excgroups
  |     yield
  |   File "[..].venv/lib/python3.11/site-packages/starlette/middleware/base.py", line 190, in __call__
  |     async with anyio.create_task_group() as task_group:
  |   File "[..].venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 678, in __aexit__
  |     raise BaseExceptionGroup(
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "[..].venv/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 411, in run_asgi
    |     result = await app(  # type: ignore[func-returns-value]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 69, in __call__
    |     return await self.app(scope, receive, send)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__
    |     await super().__call__(scope, receive, send)
    |   File "[..].venv/lib/python3.11/site-packages/starlette/applications.py", line 123, in __call__
    |     await self.middleware_stack(scope, receive, send)
    |   File "[..].venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 186, in __call__
    |     raise exc
    |   File "[..].venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 164, in __call__
    |     await self.app(scope, receive, _send)
    |   File "[..].venv/lib/python3.11/site-packages/starlette/middleware/base.py", line 189, in __call__
    |     with collapse_excgroups():
    |   File "[..].pyenv/versions/3.11.4/lib/python3.11/contextlib.py", line 155, in __exit__
    |     self.gen.throw(typ, value, traceback)
    |   File "[..].venv/lib/python3.11/site-packages/starlette/_utils.py", line 93, in collapse_excgroups
    |     raise exc
    |   File "[..].venv/lib/python3.11/site-packages/starlette/middleware/base.py", line 191, in __call__
    |     response = await self.dispatch_func(request, call_next)
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/middleware.py", line 75, in dispatch
    |     response = t.cast(StreamingResponse, await toolbar.process_request(request))
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    |     return await self.call_next(request)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/timer.py", line 58, in process_request
    |     return await super().process_request(request)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    |     return await self.call_next(request)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    |     return await self.call_next(request)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    |     return await self.call_next(request)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   [Previous line repeated 2 more times]
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/logging.py", line 96, in process_request
    |     return await super().process_request(request)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    |     return await self.call_next(request)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/profiling.py", line 28, in process_request
    |     await call(self.profiler.stop)
    |   File "[..].venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread
    |     return await future
    |            ^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 851, in run
    |     result = context.run(func, *args)
    |              ^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "[..].venv/lib/python3.11/site-packages/pyinstrument/profiler.py", line 151, in stop
    |     raise RuntimeError(
    | RuntimeError: Failed to stop profiling. Make sure that you start/stop profiling on the same thread.
    +------------------------------------

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "[..].venv/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 411, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 69, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "[..].venv/lib/python3.11/site-packages/starlette/applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "[..].venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 186, in __call__
    raise exc
  File "[..].venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "[..].venv/lib/python3.11/site-packages/starlette/middleware/base.py", line 189, in __call__
    with collapse_excgroups():
  File "[..].pyenv/versions/3.11.4/lib/python3.11/contextlib.py", line 155, in __exit__
    self.gen.throw(typ, value, traceback)
  File "[..].venv/lib/python3.11/site-packages/starlette/_utils.py", line 93, in collapse_excgroups
    raise exc
  File "[..].venv/lib/python3.11/site-packages/starlette/middleware/base.py", line 191, in __call__
    response = await self.dispatch_func(request, call_next)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/middleware.py", line 75, in dispatch
    response = t.cast(StreamingResponse, await toolbar.process_request(request))
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    return await self.call_next(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/timer.py", line 58, in process_request
    return await super().process_request(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    return await self.call_next(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    return await self.call_next(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    return await self.call_next(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  [Previous line repeated 2 more times]
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/logging.py", line 96, in process_request
    return await super().process_request(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/__init__.py", line 79, in process_request
    return await self.call_next(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/debug_toolbar/panels/profiling.py", line 28, in process_request
    await call(self.profiler.stop)
  File "[..].venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread
    return await future
           ^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 851, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "[..].venv/lib/python3.11/site-packages/pyinstrument/profiler.py", line 151, in stop
    raise RuntimeError(
RuntimeError: Failed to stop profiling. Make sure that you start/stop profiling on the same thread.

Used versions:

sam-aiplanet commented 1 month ago

+1 , I am also facing this same issue

theognis1002 commented 2 weeks ago

+1, same.

RuntimeError: There is already a profiler running. You cannot run multiple profilers in the same thread or async context, unless you disable async support.