-
Notifications
You must be signed in to change notification settings - Fork 0
fix(proxy): Enforce immutable snapshots and #11
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: update-readme
Are you sure you want to change the base?
fix(proxy): Enforce immutable snapshots and #11
Conversation
coherent cache - Recursively freeze collections via _freeze_collections (dict→MappingProxyType, - list→tuple) - Treat MappingProxyType as a collection; apply freezing in - build/from_obj/refresh - Add version-stamped LRU attr/item cache; bump version on refresh and evict stale entries - Make refresh copy-on-write and thread-safe; clear cache on swap - Introduce __slots__ to reduce footprint Use obj metadata in __repr__ - to avoid __getattr__ recursion - Minor formatting and doc improvements
Summary of ChangesHello @srnnkls, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the SerializationProxy by enforcing true immutability of serialized data snapshots and introducing a robust, thread-safe caching mechanism. These changes prevent unintended mutations, improve cache coherence across refresh operations, and optimize memory usage, leading to more predictable and efficient proxy behavior. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
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.
Code Review
This pull request significantly improves the SerializationProxy by enforcing snapshot immutability and introducing a coherent, thread-safe caching mechanism. The recursive freezing of collections and the version-stamped LRU cache are excellent additions for robustness in concurrent scenarios. The code is well-structured, and the inclusion of __slots__ and the fix for __repr__ recursion are thoughtful optimizations. My review includes a couple of suggestions to enhance maintainability by removing a now-redundant check and refactoring duplicated cache-handling logic.
| if isinstance(ser, dict) and not isinstance(ser, MappingProxyType): | ||
| ser = MappingProxyType(ser) |
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 check appears to be redundant. The self.serialized attribute is consistently processed by _freeze_collections during proxy creation and refresh, which wraps any dict in a MappingProxyType. Therefore, isinstance(ser, dict) should always be False here for a mapping type. Removing this defensive code would make the implementation cleaner and more reliant on the immutability guarantee provided elsewhere.
| with self._attr_cache_lock: | ||
| if cache_key in self._attr_cache: | ||
| self._attr_cache.move_to_end(cache_key) | ||
| return self._attr_cache[cache_key] | ||
|
|
||
| # Hoist to local for micro-optimization | ||
| cached_ver, cached_proxy = self._attr_cache[cache_key] | ||
| if cached_ver == ver: | ||
| # Cache hit with matching version | ||
| self._attr_cache.move_to_end(cache_key) | ||
| return cached_proxy | ||
| else: | ||
| # Stale entry from pre-refresh, evict it | ||
| self._attr_cache.pop(cache_key, 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.
The logic for checking and retrieving from the versioned cache is duplicated here and in __getattr__ (lines 460-470). Similarly, the logic for adding a new entry to the cache is duplicated (here at lines 550-555 and in __getattr__ at lines 491-496). To improve maintainability and reduce code duplication, consider extracting this cache management logic into private helper methods (e.g., _get_cached_proxy and _cache_proxy).
coherent cache