This repository was archived by the owner on Oct 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 48
This repository was archived by the owner on Oct 3, 2022. It is now read-only.
Race Condition in JCacheManager between createCache() and getCache() #41
Copy link
Copy link
Open
Milestone
Description
As far as I understand, jsr-107's CacheManager is supposed to be thread-safe, and it is only practical for it to be.
There is a possibility for the cache configuration created by JCacheManager.createCache() to be configured incorrectly if JCacheManager.getCache() is called at the same time with the same cache name. In particular, there is a realistic chance that the statistics and management beans are not created.
This works as follows:
createCacheis called.createCachemakes sureallCachesdoes not include the cachecreateCacheadds the cache to the ehCache-backedcacheManager- Now,
getCache(String, Class, Class)is called with the same argument. getCachetries to find the same cache inallCachesbut does it does not existgetCachelooks in the ehCache-backedcacheManager, and finds the cache as it's already added theregetCachecreates a newJCachebased on aJCacheConfigurationwith the default configuration and puts it intoallCachescreateCachecreates a newJCachewith the correct configuration and tries to add it withallCaches.putIfAbsent, but it already existscreateCachereturns the misconfigured cache that is already present inallCaches, and does not callenableStatisticsorenableManagementfor it.
The same problem occurs when using the second overload, getCache(String):
createCacheis called.createCachemakes sureallCachesdoes not include the cachecreateCacheadds the cache to the ehCache-backedcacheManagergetCache(String)is called with the same cache name as argument.getCachelooks inallCaches, but does not find the cachegetCachecallsrefreshAllCaches()refreshAllCachesiterates over all caches in the ehCache-backedcacheManager, creates newJCacheinstances for them and puts them intoallCaches- The problem is that
new JCacheConfiguration()does not properly set themanagementEnabledandstatisticsEnabledattributes when a ehCacheCacheConfigurationis provided as argument createCacheagain uses the already existing, but misconfigured cache and returns that,enableStatisticsandenableManagementare not called.
I see three possibilities to solve this problem:
- Use
synchronizedon all the methods touching or readingallCaches. This may lead to performance loss, but is the simplest to implement - Use
ReadWriteLockso that concurrent e.g.getCacheorgetCacheNamescan be called concurrently. - Lock cache names right when they are created using a concurrent set, and do not synchronize ehcaches to
allCachesfor those in this set. However, I don't think this will work becausegetCacheis expected to wait for a cache being added to be completely configured befure returning it. That's only possible with locking.
I will create a pull request to fix this when we have agreed on a solution.
Metadata
Metadata
Assignees
Labels
No labels