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
ISPN-11424 Deprecate StorageType Configuration #8240
ISPN-11424 Deprecate StorageType Configuration #8240
Conversation
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.
We also need to update the user guide as all the old examples are completely out of date. And we need to explain when you can and can't use sized based eviction and make sure we have ample examples.
@@ -65,6 +82,11 @@ public EncodingConfiguration create() { | |||
|
|||
@Override | |||
public void validate(GlobalConfiguration globalConfig) { | |||
if(mediaType != null) { |
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.
Nitpick: space
return ELEMENT_DEFINITION; | ||
} | ||
|
||
public boolean offHeap() { |
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.
public boolean offHeap() { | |
public boolean isStoredOffHeap() { |
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 builders in general seem to avoid the is
for boolean properties, was just following the trend
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 can see either way. To me the name offHeap doesn't really convey what the setting is personally. Some Configuration objects have is or uses etc for prefixes of such config options. It is just a suggestion.
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 also prefer the way you suggested, I will change it
*/ | ||
public long maxSizeBytes() { | ||
String str = attributes.attribute(MAX_SIZE).get(); | ||
if(str == null) return -1; |
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.
Nitpick: space
public long maxSizeBytes() { | ||
String str = attributes.attribute(MAX_SIZE).get(); | ||
if(str == null) return -1; | ||
return ByteQuantity.parse(str); |
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 wonder if instead we should store the parsed value in the Configuration object. Otherwise everytime we invoke this we have to parse the String.
public void validate() { | ||
if (hasLegacyConfiguration()) { | ||
if (isSizeBounded() || isCountBounded()) { | ||
CONFIG.ignoredMemoryDeprecatedSettings("size", memoryStorageConfigurationBuilder.size()); |
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 would just throw an exception if using both, to remove ambiguity.
<xs:documentation> | ||
Defines the size of the data container in a byte quantity plus an optional multiplier. | ||
Supported multipliers are kB (kilobytes), MB (megabytes), GB (gigabytes) and TB (terabytes). | ||
Eviction occurs either the amount of memory exceeds the maximum size. |
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.
Eviction occurs either the amount of memory exceeds the maximum size. | |
Eviction occurs after the approximate memory usage exceeds the maximum size. |
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.
Guessing we may also want to mention that binary or off heap media type is specified.
<xs:attribute name="max-count" type="xs:long" default="-1"> | ||
<xs:annotation> | ||
<xs:documentation> | ||
Defines the max number of entries in the data container, before eviction occurs. |
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.
To keep consistent with max-size
Defines the max number of entries in the data container, before eviction occurs. | |
Defines the size of the data container by a count of entries. Eviction occurs after the container size exceeds the maximum count. |
<xs:documentation> | ||
Specifies a strategy for evicting cache entries. Eviction always | ||
takes place when you define either the max-size or the max-count | ||
(but not both) for the data container. |
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.
Should probably mention that REMOVE is used if no strategy is defined but size or count are.
/** | ||
* @return true if the MediaType's java type is a byte array. | ||
*/ | ||
public boolean isBinary() { |
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.
So to clarify we assume everything is binary if it has ByteArray as a type in the media type (ie. application/object;type=ByteArray) or it doesn't match application object?
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.
Media types like text/* wouldn't be binary, although they could support size based eviction.
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.
Also I am not sure for application/unknown etc.
To be honest thinking more we may need pluggable size calculators based on media type moving forward.
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 idea is that everything is binary by default. text/plain
is UTF-8 byte[]
, same as application/json
.
Regarding size calculators, it's enough to know the java type from the MediaType, right?
Most MediaType are byte[]
, apart from that, application/x-java-object
represents random Java objects, a type
can make it more specific, like application/x-java-object; type=java.lang.String
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 idea is that everything is binary by default.
Okay that was the part I was unaware.
I guess in that case the size calculators are probably fine then how they are.
* | ||
* @since 11.0 | ||
*/ | ||
public final class ByteQuantity { |
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.
We have the MemoryUnit
class that already does a lot of this. Maybe we can consolidate?
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 have completely missed that 👍
To avoid sending a massive PR at once, I limited the changes to only "production" code here. Next PR will remove all the deprecated stuff from tests, and yes, the doc needs updating as well |
Conflict |
1e6493b
to
4b0caa5
Compare
Updated and rebased @wburns |
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 haven't dug deeper, but it seems we should be able to simplify the conversion still. But maybe there is something I am not seeing that would block that.
/** | ||
* @deprecated since 11.0, use {@link ByteQuantity} instead. | ||
*/ | ||
@Deprecated |
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.
Hrmm, is there any reason we couldn't have added enhanced the parser of this class instead?
Also we don't have all the enum instances with the new one or conversions between.
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 public interface is based on long
for the quantity, I think the new one is more flexible.
MemoryUnit
can convert from one type to another, but it is not really used apart from a unit test?
* @since 11.0 | ||
*/ | ||
class AttributeChangeTracker { | ||
private boolean isTracking = true; |
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 wonder if this needs to be volatile or not.
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 had it volatile before but I removed: I am almost sure builders and attributes are inherently thread-confined
if (this.isTracking) { | ||
String name = attr.name(); | ||
Object value = attr.get(); | ||
changedAttributes.add(name.concat("=").concat(value == null ? "" : value.toString())); |
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.
Why calling concat here? I would worry this would prevent StringBuilder optimization for +'s.
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 hardly a hotspot, but I will remove the concats :)
@@ -65,6 +82,11 @@ public EncodingConfiguration create() { | |||
|
|||
@Override | |||
public void validate(GlobalConfiguration globalConfig) { | |||
if (mediaType != null) { | |||
CONFIG.ignoringSpecificMediaTypes(); |
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 seems a bit odd to me. We already set the key and value metadatatype in mediaType. And also shouldn't we only log this if the key or value media types were explicitly defined?
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.
Why? This mediatype is just a cascade switch to set both key and value at the same time (less typing), and it takes precedence over anything that is set individually.
Ok, I realized it was setting twice, removing...
And also shouldn't we only log this if the key or value media types were explicitly defined?
Yes, I will change it, otherwise the yellow lines will keep popping up in the console...
/** | ||
* @return The configured {@link EvictionStrategy}. | ||
*/ | ||
public EvictionStrategy whenFull() { |
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 isn't needed. We should be able to just maintain the eviction strategy in the MemoryConfiguration(Builder) directly and the MemoryStorageConfiguration(Builder) just invokes the parent when setting or retrieving the value.
I have a feeling we can do the same with size.
That is unless there was a reason we had to have separate config values for all of theses? But I would think that should reduce the complexity of the validate and other methods. This is what I did originally when changing eviction to memory element. https://github.com/infinispan/infinispan/blob/9.4.x/core/src/main/java/org/infinispan/configuration/cache/EvictionConfigurationBuilder.java#L82
You can also maintain the value in the child to see if it was set or not.
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 specific name when-full
was a suggestion from @danberindei in the JIRA I had forgot to add. I think it was quite a expressive attribute name.
I separated on purpose the attributes to be able to detect when using legacy and new configs together, and throw an exception when they are mixed.
The problem I found with syncing attributes one by one in the "setter" is that the JSON parser sets the Attribute
values directly, and there's a read
method that also sets attributes directly.
Some other places recycle builders, meaning they create a Configuration
from the builder, then re-feed the Configuration
into the builder's read
and then build again (one or more times). So yes, it's a bit complex but the config system is full of back doors...
@@ -250,6 +248,7 @@ private void writeCacheContainer(XMLExtendedStreamWriter writer, ConfigurationHo | |||
default: | |||
break; | |||
} | |||
writeExtraConfiguration(writer, config.modules()); |
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.
We may want to include this in a separate PR. I just worry if this is tested, since xml schema validation can be ordered.
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.
Curious that I did not change it. Intellij did this for some bizarre reason...
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 was probably a stale merge from adff9c9
4b0caa5
to
e8786e6
Compare
Updated |
I must admit I am not a fan of the whole legacy config stuff, it seems overly complex for very little benefit, but I don't want that to hold this PR up. |
Integrated into master, thanks @gustavonalle ! |
Thanks @wburns, I am not a fan either. I did tried the simpler approach, but the fact the some new [and sometimes overlapping] configs were introduced, and the way the JSON parsing currently works (attributes only, bypassing builder methods) made it messy. |
https://issues.redhat.com/browse/ISPN-11424