-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Support serializable toolbar #2138
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
base: main
Are you sure you want to change the base?
Conversation
If the serialization logic begins throwing exceptions we can consider subclassing the encoder class and using force_str on the object itself.
* Log serialization warning when a panel errors. This will help third party panels identify issues with serializing the content of their panels in the future, without causing the entire toolbar to break. * Change setting name to SUPPRESS_SERIALIZATION_ERRORS
This matches the new naming defined in the store module and will make things eaiser to change moving forward. This will break anything using the store internally causing issues for third party packages.
The remainder of the work is to fix the individual panels' serialization errors.
This avoids needing to create an instance of a panel to get its panel ID.
The alternative here is to inspect and iterate over every collection and object passed around. This avoids having to reinvent the wheel in that scenario.
Any instance attributes shouldn't be used because they can't be relied upon for historical purposes. Especially when it comes to the titles and nav titles.
The alerts panel may eventually have other types of alerts that don't depend on the response. Such as Django's check system.
The stats must be stored as JSON, otherwise it'll be converted to a string.
This causes problems with tests and changing the settings via override_settings. Since we're using the lru_cache decorator on get_config, there's very little benefit to caching within the store too.
The majority were difficulities with caching and settings.
- Add async union view for tests. - Add async json explain for tests.
…#2121) * feat: add DatabaseStore for persistent debug data storage - Introduced `DatabaseStore` to store debug toolbar data in the database. - Added `DebugToolbarEntry` model and migrations for persistent storage. - Updated documentation to include configuration for `DatabaseStore`. - Added tests for `DatabaseStore` functionality, including CRUD operations and cache size enforcement. Fixes #2073 * refactor: rename DebugToolbarEntry to HistoryEntry and more - Updated model name from `DebugToolbarEntry` to `HistoryEntry` to make string representations of the app_model less redundant. - Adjusted verbose names to use translations with `gettext_lazy`. - Updated all references in `store.py` to use the new model name. - Modified tests to reflect the model name change. - Added a test to check the default ordering of the model and make it the default ordering in methods reliable. * Optimize entry creation logic to clean up old entries only when new entries are added * Wrap creation and update methods in atomic transactions * Avoid using .set() for database store This doesn't provide the same utility as it does for the memory store. We need to use get_or_create to generate the entry in the database regardless. The middleware will be using .set() to trim extra requests to avoid overflowing the store removing the need for save_panel to also do the same. --------- Co-authored-by: Tim Schilling <[email protected]>
The lint failure is from main and due to our usage of |
This was missed in an earlier merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very cool. I dropped a few comments as I read through. Excited to play with this more!
Each call to ``record_stats`` updates the statistics dictionary. | ||
""" | ||
for query in stats.get("queries", []): | ||
query["params"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me what this is doing?
len(cls._request_ids) - dt_settings.get_config()["RESULTS_CACHE_SIZE"] | ||
): | ||
removed_id = cls._request_ids.popleft() | ||
cls._request_store.pop(removed_id, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using _request_ids = deque(maxlen=dt_settings.get_config()["RESULTS_CACHE_SIZE"])
would keep this bounded without having to manually pop items off. You'd still have to maintain the contents of _request_store
.
Description
This change significantly revamps how panels for the toolbar work. Each panel will now persist its data in a store. A store can either be backed by various backends. The toolbar will support a memory and database backend to start.
Django applications with basic installations are backwards compatible with this change. If there are hooks into the internals of the toolbar, such as
DebugToolbar.store_id
then it will be backwards incompatible.Third-party panels will need updating. Any data that is stored in
record_stats
will need to be fetched back out fromself.get_stats()
before being able to be rendered. This is to support loading an instance of the toolbar from persisted data. A simple example of this transition can be found indebug_toolbar/panels/cache.py
in this PR.Refs: #1435, #2048, #2124
Checklist:
docs/changes.rst
.