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
Fix caching mechanism for Sagas #2517
Conversation
…perly, as well as leading to NPE
messaging/src/main/java/org/axonframework/common/caching/Cache.java
Outdated
Show resolved
Hide resolved
- Fix indentations - Solve warnings - Make Cache#computeIfAbsent a default implementation, throwing an unsupported exception when not implemented. #2517
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.
Overall this looks good, but as discussed offline, an integration test validating bulk operations against a cached Saga work would be a great addition. Let's get that in, before we merge this.
messaging/src/main/java/org/axonframework/common/caching/Cache.java
Outdated
Show resolved
Hide resolved
Add integration tests for EhCache and WeakReferenceCache, using a common test suite for validation. #2517
messaging/src/main/java/org/axonframework/common/caching/Cache.java
Outdated
Show resolved
Hide resolved
…exception if the value supplier returns null to differentiate between faulty cache and faulty saga stores
Provide working default implementation of computeIfAbsent. As, if users do have their own implementation of the Cache, their migration to a more recent version of Axon Framework would horribly break. #2517
- Consistently use newValue as the result of the valueSupplier - Suppress warnings #2517
- Move common used fields to constants - Remove manual cache clearing, as that's a job of the IT implementations to define when these are cleared. - Maintain references to the associations set, to ensure the weak reference implementation doesn't fail on the missing associations - Validate whether the saga cache entry is present before verifying the contents, instead of an assertion. This it to cover for cache implementation that may have cleared out the entries between the (bulk) updates and validation. As this is a perfectly valid scenario, just don't validate the cache if it's not there instead of breaking the test case. - Suppress unimportant warnings #2517
As I'm working on these changes myself, my review may be dismissed.
By introducing the default implementation on the Cache interface, we can get rid of the concrete implementation on the EhCache and JCache adapters. #2517
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.
Some nitty gritty stuff
messaging/src/main/java/org/axonframework/common/caching/WeakReferenceCache.java
Outdated
Show resolved
Hide resolved
messaging/src/main/java/org/axonframework/common/caching/WeakReferenceCache.java
Outdated
Show resolved
Hide resolved
messaging/src/main/java/org/axonframework/common/caching/JCacheAdapter.java
Outdated
Show resolved
Hide resolved
messaging/src/main/java/org/axonframework/common/caching/EhCacheAdapter.java
Outdated
Show resolved
Hide resolved
- Reuse existingValue instead of retrieving it from the entry. - Use ObjectUtils.getOrDefault #2517
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 think this looks good as it is right now...let's wait for a third pair of eyes before merging, though.
As discussed offline, we (Mitchell, Allard, me) approve of this current solution. |
SonarCloud Quality Gate failed. |
This PR expands the
Cache
interface with acomputeIfAbsent(Object key, Supplier<T> valueSupplier)
method, which lazily fetches data when data is not found in the cache.The current implementation always queries the Saga store, and puts it in the cache afterwards. The NPE experienced by a customer might be because of eventual consistency in the cache. We
get
it, right after weput
it, so it might not have replicated yet (this depends on the configuration) and produce anull
value.This is not the case when using the new method. This will check the cache and only query for the value when necessary. In addition, it will return the produced value instead of the value in the cache, ensuring there actually is a value upon return.