-
Notifications
You must be signed in to change notification settings - Fork 21.9k
Lazily deserialize cache entries #48754
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
Lazily deserialize cache entries #48754
Conversation
@@ -29,18 +29,20 @@ class MemoryStore < Store | |||
module DupCoder # :nodoc: | |||
extend self | |||
|
|||
def dump(entry) | |||
def dump_as_entry(entry) |
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.
I don't like the idea of extending the interface. I already greatly regret adding dump_compressed
.
|
||
module ActiveSupport | ||
module Cache | ||
class SerializerAdapter # :nodoc: |
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.
I still don't quite like that idea of an adapter. IMO all this logic should be inside the coder itself.
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.
SerializerAdapter
is a coder with swappable serializer and compressor.
Is the primary concern integration with something like paquito?
What if we (1) rename SerializerAdapter
to Cache::Coder
, and (2) support specifying either a :coder
option OR :serializer
and :compressor
options for Cache::Store
? When :coder
is specified, it will be used directly, no Cache::Coder
involved. Otherwise, :serializer
and :compressor
will be used via Cache::Coder
, with their default values controlled by the cache format version.
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.
Is the primary concern integration with something like paquito?
In part yes. I think if a coder
is specified, it should have total control over the serialization, Active Support shouldn't prepend anything to the provided payload etc.
support specifying either a :coder option OR :serializer and :compressor options
I think you touch on something here.
Paquito went the route of taking total control over how the Entry
(and its content) is serialized.
You can't combine that with a configurable compressor. But in many case users may only want to control how the Entry#value
is serialized.
If both were explicitly distinct I think it would make the code clearer.
So 👍 to experiment that (and sorry for dragging my feet on this, I know you've put a lot of efforts into it, I'm just super worried about the maintainability of all this).
5504340
to
c00edc7
Compare
|
||
def value | ||
if @type | ||
@value = @coder._load_payload(@value, @type) |
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.
Not a big fan of that _load_payload
.
Could we pass both the serializer
and compressor
? If the payload isn't compressed, we pass compressor = nil
.
How does that sound?
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.
If that is what you prefer, we can do that.
The reason I organized it as _load_payload
is the same reason I originally used a thunk: this code is essentially part of load
, it is merely delayed. Encapsulating the code in _load_payload
allows it to be near to load
so they can be understood together.
I've pushed a commit that passes serializer
and compressor
, and compressor = nil
when the payload isn't compressed. In my opinion, the code is disjointed and less clear.
If you can tell me what you dislike about _load_payload
, perhaps I can iterate on it. If you dislike the name, I can change it. If you dislike LazyEntry
delegating to @coder._load_payload
, I can pass (a cached copy of) method(:_load_payload)
instead.
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.
If you can tell me what you dislike about
_load_payload
,
A few things:
- It increase the interface, particularly with something that is public but private
_load
. - I like that coder, serializers etc have a simple and standard
load/dump
,inflate/deflate
API. - It makes the entry and coder reflation two way, I prefer when reference can go only in one direction.
Looking at your last commit now.
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 increase the interface, particularly with something that is public but private
_load
.I like that coder, serializers etc have a simple and standard
load/dump
,inflate/deflate
API.
These could be solved by passing something like method(:_load_payload)
instead of the coder instance.
- It makes the entry and coder reflation two way, I prefer when reference can go only in one direction.
In terms of LazyEntry
knowing about Cache::Coder
, passing method(:_load_payload)
would also abstract that relationship.
In terms of references and lifetimes, LazyEntry
must still hold references to call @serializer.load
and @compressor.inflate
, so there isn't much difference either way.
This adds a cache optimization such that expired and version-mismatched cache entries can be detected without deserializing their values. This optimization is enabled when using cache format version >= 7.1 or a custom serializer. Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
b819095
to
36f9cfd
Compare
This adds a cache optimization such that expired and version-mismatched cache entries can be detected without deserializing their values. This optimization is enabled when using cache format version >= 7.1 or a custom serializer.