Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't try to undo cache method monkey patching #1770

Merged
merged 1 commit into from
May 9, 2023

Conversation

living180
Copy link
Contributor

Description

Trying to undo the monkey patch of cache methods in the CachePanel.disable_instrumentation() method is fragile in the presence of other code which may also monkey patch the same methods (such as Sentry's Django integration), and there are theoretically situations where it is actually impossible to do correctly. Thus once a cache has been monkey-patched, leave it that way, and instead rely on checking in the patched methods to see if recording needs to happen. This is done via a _djdt_panel attribute which is set to the current panel in the enable_instrumentation() method and then set to None in the disable_instrumentation() method.

Fixes #1769

Checklist:

  • I have added the relevant tests for this change.
  • I have added an item to the Pending section of docs/changes.rst.

Trying to undo the monkey patch of cache methods in the
CachePanel.disable_instrumentation() method is fragile in the presence
of other code which may also monkey patch the same methods (such as
Sentry's Django integration), and there are theoretically situations
where it is actually impossible to do correctly.  Thus once a cache has
been monkey-patched, leave it that way, and instead rely on checking in
the patched methods to see if recording needs to happen.  This is done
via a _djdt_panel attribute which is set to the current panel in the
enable_instrumentation() method and then set to None in the
disable_instrumentation() method.
Copy link
Member

@matthiask matthiask left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good idea. I haven't tested it out, it would certainly be helpful if the change were tested by those who reported crashes in the other issue.

Sorry for the bikeshedding, but maybe _djdt_recording was a more fitting name than _djdt_panel; or maybe I misunderstand the intention of the variable?

I also think we should generally move towards using from time import perf_counter instead of time.time() to measure short durations; my understanding is that time.time could be affected by updating the system clock. It's extremely unlikely to matter of course, but perf_counter would be more correct. And it's also what Django does, see https://github.com/django/django/blob/1586a09b7949bbb7b0d84cb74ce1cadc25cbb355/django/test/utils.py#L934-L941

@living180
Copy link
Contributor Author

Sorry for the bikeshedding, but maybe _djdt_recording was a more fitting name than _djdt_panel; or maybe I misunderstand the intention of the variable?

So the type of the variable actually changed: previously it was a bool, now it is an instance of CachePanel if instrumentation is enabled, or None otherwise. This is necessary because with this PR, once a cache has been monkey patched, it stays that way, but each request creates a new CachePanel (previously the cache was being monkey patched for each request specifically for the associated CachePanel).

@living180
Copy link
Contributor Author

I also think we should generally move towards using from time import perf_counter instead of time.time() to measure short durations; my understanding is that time.time could be affected by updating the system clock. It's extremely unlikely to matter of course, but perf_counter would be more correct. And it's also what Django does, see https://github.com/django/django/blob/1586a09b7949bbb7b0d84cb74ce1cadc25cbb355/django/test/utils.py#L934-L941

Totally agree, though that is really orthogonal to this change. I can look at making a new PR switching to perf_counter across the codebase (I'm pretty sure the SQL panel would also need to be updated, and perhaps others).

@matthiask
Copy link
Member

So the type of the variable actually changed: previously it was a bool, now it is an instance of CachePanel if instrumentation is enabled, or None otherwise. This is necessary because with this PR, once a cache has been monkey patched, it stays that way, but each request creates a new CachePanel (previously the cache was being monkey patched for each request specifically for the associated CachePanel).

Ah of course, thank you!

@matthiask matthiask merged commit a6b65a7 into django-commons:main May 9, 2023
@living180 living180 deleted the cache_monkey_patching branch May 9, 2023 13:41
humitos added a commit to readthedocs/readthedocs.org that referenced this pull request May 23, 2023
humitos added a commit to readthedocs/readthedocs.org that referenced this pull request May 23, 2023
humitos added a commit to readthedocs/readthedocs.org that referenced this pull request May 23, 2023
humitos added a commit to readthedocs/readthedocs.org that referenced this pull request May 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

After upgrading to Django 4.2 LTS, I receive AttributeError on each page load. Using DDT 4.0.0
2 participants