cache JsonProvider result in JsonBindingBuilder#363
cache JsonProvider result in JsonBindingBuilder#363Simulant87 wants to merge 5 commits intoeclipse-ee4j:masterfrom
Conversation
Signed-off-by: Simulant <nfaupel.dev@gmail.com>
aguibert
left a comment
There was a problem hiding this comment.
hi @Simulant87, thanks for having a go at this enhancement. There are a few things that I would like to change in order to widen the scope of caching to make it cover more realistic scenarios
| public class JsonBindingBuilder implements JsonbBuilder { | ||
| private JsonbConfig config = new JsonbConfig(); | ||
| private JsonProvider provider = null; | ||
| private JsonBinding bindingCache = null; |
There was a problem hiding this comment.
A few things on the binding cache here:
- The binding cache needs to be
staticso that it is global (i.e. across multiple different instances ofJsonBindingBuilder). - We should allow more than one configuration of a
JsonbBindingto be cached. Consider creating a composite key class (that combines provider and config) so we can store cached instances in aMap<JsonbKey,Jsonbinding>. This would also allow us to eagerly initialize the map and make itfinal - whatever data structure we use to store the JsonBinding instances needs to be a weak reference so we don't cause claassloader leaks when this is used in an app server environment where the server-side Yasson code has references to application-side classes that may be restarted/recycled multiple times during the same instance of the server-side code
There was a problem hiding this comment.
the JsonbKey class could look like this:
private static class JsonbKey {
private final JsonbConfig config;
private final JsonProvider provider;
public JsonbKey(JsonbConfig config, JsonProvider provider) {
// set final fields
}
// implement equals() and hashCode()
}In order for this to work, we will need to properly compare equality for Jsonb instances which can be done by doing configA.getAsMap().equals(configB.getAsMap())
| public JsonbBuilder withConfig(JsonbConfig config) { | ||
| this.config = config; | ||
| return this; | ||
| synchronized (this) { |
There was a problem hiding this comment.
synchronization shouldn't be necessary here or in withProvider. Instead, if we store cached instances in a map we can handle all concurrency within the build method
| @Override | ||
| public Jsonb build() { | ||
| return new JsonBinding(this); | ||
| synchronized (this) { |
There was a problem hiding this comment.
Instead of synchronizing here, we could take advantage of some concurrent map operations. For example:
JsonbKey currentKey = new JsonbKey(config, provider);
return jsonbCache.computeIfAbsent(currentKey, key -> new JsonBinding(this));| public class JsonBindingBuilderTest { | ||
|
|
||
| @Test | ||
| public void testMultipleCallsToBuildWithoutChangesReturnTheSameInstance() { |
There was a problem hiding this comment.
lets write tests that are more similar to how our users interact with Yasson/JSONB. In this case, you are doing new JsonBindingBuilder() which is from a Yasson internal package and users should never be using.
Instead, lets do things like JsonbBuilder.create() or JsonbBuilder.newBuilder().build()
|
|
||
|
|
||
| @Test | ||
| public void testMultipleCallsToBuildWithChangedConfigReturnNotTheSameInstance() { |
There was a problem hiding this comment.
lets also test that multiple instances with config changed in the same way are equal. In this case, 2 instances that both do config.withStrictIJSON(true); should be equal
|
|
||
| assertNotSame(jsonb1, jsonb2); | ||
| } | ||
|
|
There was a problem hiding this comment.
lets also add a test that verifies 2 instances that both specify the same Adapter instance are the same, likewise another test that verifies 2 instances with different instances of the same Adapter class are different
|
Another complexity I just realized is that the
|
|
Hi @Simulant87 , your build is failing on copyright job in our pipeline. Currently there is an issue with that on our side. See PR #365 . Please when this PR is merged, just rebase on it and everything should be fine. |
Fix StackOverflowError on recursive references Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com>
* Copyright plugin version fix. Printing of incorrect copyrights improved. Signed-off-by: David Kral <david.k.kral@oracle.com> * Suggestions of aguibert according to copyright implemented. Signed-off-by: David Kral <david.k.kral@oracle.com>
Signed-off-by: David Kral <david.k.kral@oracle.com>
implement ticket #333