You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Thomas Vandahl (JIRA)" <ji...@apache.org> on 2012/11/09 21:53:12 UTC

[jira] [Resolved] (JCS-73) concurrent cache access causes values loss

     [ https://issues.apache.org/jira/browse/JCS-73?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Thomas Vandahl resolved JCS-73.
-------------------------------

    Resolution: Fixed

I added some cruel synchronization to the get method. This fixes the problem but slows down the cache. This needs some more improvement. Check out the latest trunk.
                
> concurrent cache access causes values loss
> ------------------------------------------
>
>                 Key: JCS-73
>                 URL: https://issues.apache.org/jira/browse/JCS-73
>             Project: Commons JCS
>          Issue Type: Bug
>          Components: Indexed Disk Cache
>    Affects Versions: jcs-1.3
>            Reporter: Alexander Kleymenov
>            Assignee: Thomas Vandahl
>             Fix For: jcs-2.0.0
>
>         Attachments: patch.txt, repro.zip
>
>
> The following groovy code demonstrates the problem: several threads write to the cache and try to read previously written values. Sometimes just written values can't be retrieved. In this case, subsequent tries can get the value, but not always.
> {code}
> cache = org.apache.jcs.JCS.getInstance("cache")
> group = "group"
> worker = {
>     def name = Thread.currentThread().name
>     10000.times { idx ->
>         if (idx) {
>             // get previously stored value
>             def res = cache.getFromGroup(idx-1, group)
>             if (!res) {
>                 // null value got inspite of the fact it was placed in cache!
>                 println "ERROR: for ${idx} in " + name
>                 // try to get the value again:
>                 def n = 5
>                 while (n-- > 0) {
>                     res = cache.getFromGroup(idx-1, group)
>                     if (res) {
>                         // the value finally appeared in cache
>                         println "ERROR FIXED for ${idx}: ${res} " + name
>                         break
>                     }
>                     println "ERROR STILL PERSISTS for ${idx} in " + name
>                     Thread.sleep(1000)
>                 }
>             }
>         }
>         // put value in the cache
>         cache.putInGroup(idx, group, [value:[a:1, b:2, c:3], aux:[1:'a', 2:'b', 3:'c', t:name]])
>         if (!(idx % 10000)) {
>             println name+" "+idx
>         }
>     }
> }
> Thread.start worker
> Thread.start worker
> Thread.start worker
> Thread.start worker
> Thread.start worker
> Thread.start worker
> Thread.start worker
> Thread.start worker
> {code}
> Cache configuration:
> {code}
> jcs.default=CACHE
> jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
> jcs.default.cacheattributes.MaxObjects=-1
> jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
> jcs.default.cacheattributes.DiskUsagePatternName=UPDATE
> jcs.default.cacheattributes.UseMemoryShrinker=true
> jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds=10
> jcs.default.cacheattributes.ShrinkerIntervalSeconds=10
> jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes
> jcs.default.elementattributes.IsRemote=false
> jcs.default.elementattributes.IsLateral=false
> jcs.default.elementattributes.IsSpool=true
> jcs.default.elementattributes.IsEternal=true
> jcs.auxiliary.CACHE=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
> jcs.auxiliary.CACHE.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
> jcs.auxiliary.CACHE.attributes.DiskPath=./cache
> jcs.auxiliary.CACHE.attributes.MaxPurgatorySize=-1
> jcs.auxiliary.CACHE.attributes.MaxKeySize=-1
> jcs.auxiliary.CACHE.attributes.MaxRecycleBinSize=500
> jcs.auxiliary.CACHE.attributes.ShutdownSpoolTimeLimit=60
> jcs.auxiliary.CACHE.attributes.OptimizeAtRemoveCount=30000
> jcs.auxiliary.CACHE.attributes.OptimizeOnShutdown=true
> jcs.auxiliary.CACHE.attributes.EventQueueType=SINGLE
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira