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:
createCache
is called.createCache
makes sureallCaches
does not include the cachecreateCache
adds the cache to the ehCache-backedcacheManager
- Now,
getCache(String, Class, Class)
is called with the same argument. getCache
tries to find the same cache inallCaches
but does it does not existgetCache
looks in the ehCache-backedcacheManager
, and finds the cache as it's already added theregetCache
creates a newJCache
based on aJCacheConfiguration
with the default configuration and puts it intoallCaches
createCache
creates a newJCache
with the correct configuration and tries to add it withallCaches.putIfAbsent
, but it already existscreateCache
returns the misconfigured cache that is already present inallCaches
, and does not callenableStatistics
orenableManagement
for it.
The same problem occurs when using the second overload, getCache(String)
:
createCache
is called.createCache
makes sureallCaches
does not include the cachecreateCache
adds the cache to the ehCache-backedcacheManager
getCache(String)
is called with the same cache name as argument.getCache
looks inallCaches
, but does not find the cachegetCache
callsrefreshAllCaches()
refreshAllCaches
iterates over all caches in the ehCache-backedcacheManager
, creates newJCache
instances for them and puts them intoallCaches
- The problem is that
new JCacheConfiguration()
does not properly set themanagementEnabled
andstatisticsEnabled
attributes when a ehCacheCacheConfiguration
is provided as argument createCache
again uses the already existing, but misconfigured cache and returns that,enableStatistics
andenableManagement
are not called.
I see three possibilities to solve this problem:
- Use
synchronized
on all the methods touching or readingallCaches
. This may lead to performance loss, but is the simplest to implement - Use
ReadWriteLock
so that concurrent e.g.getCache
orgetCacheNames
can be called concurrently. - Lock cache names right when they are created using a concurrent set, and do not synchronize ehcaches to
allCaches
for those in this set. However, I don't think this will work becausegetCache
is 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