django-debug-toolbar icon indicating copy to clipboard operation
django-debug-toolbar copied to clipboard

Profiler raises ValueError in Python 3.12

Open anorthall opened this issue 1 year ago • 20 comments

Enabling the profiling panel in Python 3.12 and Django 5.0.1 causes the following exception:

   File "/usr/local/lib/python3.12/site-packages/debug_toolbar/panels/profiling.py", line 144, in process_request
     return self.profiler.runcall(super().process_request, request)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.12/cProfile.py", line 109, in runcall
     self.enable()
 ValueError: Another profiling tool is already active

This is due to a change in Python 3.12: https://github.com/python/cpython/issues/110770

There is also some relevant discussion of the same issue over on the django-silk repo which may be helpful in finding a way forward: https://github.com/jazzband/django-silk/issues/682

anorthall avatar Feb 04 '24 18:02 anorthall

Hello,

Can you give me step for reproduce the bug. I try enable the profiling panel with django 5.0.1 and python 3.12.1, I have not the problem.

elineda avatar Feb 09 '24 14:02 elineda

It happens to me as well, but only intermittently. Maybe reloading a few times, enabling and disabling the profiler panel using the checkbox and/or restarting the development server works when trying to reproduce the problem?

matthiask avatar Feb 11 '24 16:02 matthiask

This issue is happening for me as well, but I can't seem to determine what's causing the issue.

Tried to go through all the installed apps and no conflicts seem to resolve it and tried loading with 2 browsers as well.

Django 5.0.2 / Python 3.12.1

What's the progress on this or are there any updates on this?

Working the profile panel disabled by default in settings for now.

ddkasa avatar Feb 23 '24 14:02 ddkasa

I don't have a solution, but I have found a way to consistently produce the bug. When running a NextJS app that depends on a django api with the vscode debugger, every hard refresh from the nextjs frontend results in this error on the backend. I have no idea if the vscode debugger is contributing to the error, but note that I am running both the frontend and the backend from vscode. I hope this can be useful for someone to eventually debug the problem! (In the meantime, I'll be disabling the panel).

mfosterw avatar Feb 23 '24 20:02 mfosterw

Ok seem the problem occurs only the two requests are send on the runserver in the same times. Using a debuger like pycharm one is not necessary. That's strange because runserver only do one request at the time. Need to find one profiler open even if the other is not finished

elineda avatar Feb 29 '24 09:02 elineda

Found : you need to put --nothreading in runserver @mfosterw @ddkasa and @matthiask can you test this ?

elineda avatar Feb 29 '24 11:02 elineda

I propose to add a note in installation.rst or tip.rst. I don't know if it's possible by adding something in the debug toolbar to disable the multitreading.

elineda avatar Feb 29 '24 11:02 elineda

@elineda Adding --nothreading to the runserver command does seem to resolve the issue for me.

I am running my development server through Uvicorn though, so I am curious if you know a solution for that as well?

ddkasa avatar Feb 29 '24 13:02 ddkasa

@elineda Adding --nothreading to the runserver command does seem to resolve the issue for me.

I am running my development server through Uvicorn though, so I am curious if you know know a solution for that as well?

Nan no way, uvicorn doesn't accept thread value

elineda avatar Feb 29 '24 14:02 elineda

I propose to add a note in installation.rst or tip.rst. I don't know if it's possible by adding something in the debug toolbar to disable the multitreading.

@elineda What do you think about putting it as an admonition/warning in the Profiling panel area of the docs? I think I have a slight preference to that, but would also be okay with it going in tip.rst. I'd prefer to keep the installation docs as short as possible.

tim-schilling avatar Mar 04 '24 14:03 tim-schilling

I'm ok to add a note in profiling. If you have a problem with it you will check (I hope) the panel doc before complain.

elineda avatar Mar 04 '24 15:03 elineda

Agreed

tim-schilling avatar Mar 04 '24 16:03 tim-schilling

I wonder if it would be possible to add a counter variable which tracks the number of currently active profiling sessions; the profiler would only be activated when incrementing from zero and would only be deactivated when decrementing to zero?

matthiask avatar Mar 04 '24 19:03 matthiask

I think we'd have to count that across threads.

tim-schilling avatar Mar 04 '24 19:03 tim-schilling

I wonder if it would be possible to add a counter variable which tracks the number of currently active profiling sessions; the profiler would only be activated when incrementing from zero and would only be deactivated when decrementing to zero?

in that case what we do when another request come, we do it without profiler or we wait ?

elineda avatar Mar 05 '24 07:03 elineda

I think we'd have to count that across threads.

we can use cache for that.

elineda avatar Mar 05 '24 07:03 elineda

I think we'd have to count that across threads.

we can use cache for that.

Yes, that's an option. It would create a dependency on the CACHES setting being configured to run at least this particular panel. That's not ideal.

tim-schilling avatar Mar 05 '24 11:03 tim-schilling

with async compatibilty we will need a cache, for the same reason isn't ?

elineda avatar Mar 05 '24 12:03 elineda

So the configs become:

DEBUG_TOOLBAR_CONFIG = {
    "DISABLE_PANELS": [
        "debug_toolbar.panels.profiling.ProfilingPanel",  # additional one
        "debug_toolbar.panels.redirects.RedirectsPanel",
    ],
    "SHOW_TEMPLATE_CONTEXT": True,
}

https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#toolbar-options

It's fixed for me as uvicorn doesn't have --nothreading parameter, especially for who use the django-cookie-cutter.

Meanwhile, to reproduce the profiler issue, we can just ctcl+s (save multiple times the python files in the project to trigger restarts).

agusmakmun avatar Apr 29 '24 09:04 agusmakmun