Closed wlfbck closed 1 year ago
I don't think Guava datatype module has explicit support for Cache
, which would suggests it was dealt as just any old POJO.
But assuming handling was added, typically cache types would be considered transient in the sense that only an empty instance would be serialized/read. Would you expect fully contents to be serialized/deserialized back?
This behavior could be made configurable, I think, for GuavaModule
, if that is desired.
It should be possible to make it work similar to regular Map
s, but that is likely significantly more work than just doing minimum of creating an empty instance.
I see, saw what i'm seeing with Guava 30.1.1 is expected, right?
Would you expect fully contents to be serialized/deserialized back?
Yeap :) It would be very desirable to have a possibility to serialize these caches easily.
Maybe i can sketch my use case a little: We have system connected to industrial machinery. Connected means we are also on the power supply of said machinery. These kinds of machines are simply switched off, so basically there is no real shutdown happening, we are just "gone" at one point. The intention right now is to send several small packets over the network to some server, but in case the server is not reachable for a moment, this stuff needs to be cached. Here enters guava cache. Easy to use, fast, easy to configure eviction policy, fits perfectly.
Only part missing is that i need to make it persistent so i can restore that cache when we get turned on again. The persistence doesn't have to 100% perfect, that's why i was aiming to just serialize it into JSON and save it with the other stuff we already save for this type of getting shutdown.
Ok, so yes; 21.0 fails to serialize since there are no properties found. 30.x is interesting since API itself is not different, but I am guessing LocalCache$LocalManualCache
possibly implements some tag interface that prevents Jackson from throwing exception (not sure what that'd be).
As to supporting Cache
instances, things gets trickier.
First of all: supporting serialization would be relatively easy:
Cache
instances as empty JSON Object would be very easyMapSerializer
doesHowever trying to support deserialization would be much more work:
MapDeserializer
does that, so it'd be doable, just quite a bit of work.I probably won't have time to work on this, except if it made sense to support "serialize as empty Object" which seems like a small step that might be useful -- and if so, perhaps counterpart on deserialization side. I could help with a PR if anyone wants a challenge, however. Serializers/deserializers for existing Guava Maps (Immutable-) could be a useful starting point, supporting most things general JDK Map[De]Serializer does.
@wlfbck Instead of directly serializing/deserializing Cache
instances, what would probably work well and be easy enough to support would be to use a wrapper: basically declaring sort of external type to be Map<K,V>
and handling conversion yourself.
So something like:
public class CacheSerialization {
private Cache<String, Value> cache;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public CacheSerialization(Map<String, Value> map) {
// build cache instance
}
@JsonValue
protected Map<String, Value> external() {
// construct and return `Map` with cache contents
}
}
(or, if you prefer, just a logical property with Map
-valued getter and setter)
The idea here being that the hard part of serializing/deserializing entries is fully implemented by JDK Map / Jackson Map[De]Serializer -- and adding converters between that and Cache is simple enough at Java level.
Added CacheSerializer
which for now will explicitly write empty Object (as opposed failing or doing that depending on version).
Might be simple enough to implement, marking as "good first issue"
I'm trying to serialize a Guava Cache<String,String>, so nothing fancy. But this seems to either fail (using default guava version 21.0) with an InvalidDefinitionException or return
{}
(using guava 30.1.1-jre).Here's my minimal example, i hope i'm just stupid and missing something here:
My pom is minimal: