Fix compatibility between the cache compute methods and a load #5348
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The
asMap().compute
implementation did not take into account that the present value may be loading. A load does not block other writes to that entry and takes into account that it may be clobbered, causing it to automatically discard itself. This is a known design choice that breaks linearizability assumptions (#1881). The compute should check if a load is in progress and call the appropriate internal removal method.Because a zombie entry remained in the cache and still is marked as loading, the loader could discover entry and try to wait for it to materialize. When the computation is a removal, indicated by a null value, the loader would see this as the zombie's result. Since a cache loader may not return null it would throw an exception to indicate a user bug.
A new
ComputingValueReference
resolves both issues by indicating that the load has completed. The compute'sremoveEntry
will then actually remove this entry and the loader will not wait on the zombie. Instead if it observes the entry, it will neither receive a non-null value or wait for it to load, but rather try to load anew under the lock. This piggybacks on the reference collection support where an entry is present but its value was garbage collected, causing the load to proceed. By the time the lock is obtained the compute method's entry was removed and the load proceeds as normal (so no unnecessary notification is produced).fixes #5342
fixes #2827
resolves underlying cause of #2108