[ 
http://jira.magnolia-cms.com/browse/MAGNOLIA-3167?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=27660#action_27660
 ] 

Jan Haderka commented on MAGNOLIA-3167:
---------------------------------------

Yes, that is correct.
AFAIK this scenario was not re-tested after upgrading to ehcache 1.5 so it 
might be indeed obsolete.

OTOH looking at current trunk of ehcache, I'm not so sure you had a right code, 
there the BlockingCache.get(key) method looks like:
{code}
    /**
     * Looks up an entry.  Blocks if the entry is null until a call to 
{...@link #put} is done
     * to put an Element in.
     * <p/>
     * If a put is not done, the lock is never released.
     * <p/>
     * If this method throws an exception, it is the responsibility of the 
caller to catch that exception and call
     * <code>put(new Element(key, null));</code> to release the lock acquired. 
See {...@link net.sf.ehcache.constructs.blocking.SelfPopulatingCache}
     * for an example.
     * <p/>
     * Note. If a LockTimeoutException is thrown while doing a <code>get</code> 
it means the lock was never acquired,
     * therefore it is a threading error to call {...@link #put}
     *
     * @throws LockTimeoutException if timeout millis is non zero and this 
method has been unable to
     *                              acquire a lock in that time
     * @throws RuntimeException     if thrown the lock will not released. Catch 
and call<code>put(new Element(key, null));</code>
     *                              to release the lock acquired.
     */
    public Element get(final Object key) throws RuntimeException, 
LockTimeoutException {

        Sync lock = getLockForKey(key);
        Element element;
        acquiredLockForKey(key, lock, LockType.READ);
        element = cache.get(key);
        lock.unlock(LockType.READ);
        if (element == null) {
        acquiredLockForKey(key, lock, LockType.WRITE);
        element = cache.get(key);
        if (element != null) {
            lock.unlock(LockType.WRITE);
        }
        }
        return element;
    }
{code}
and browsing through the code I'm not convinced that this issue is solved. 
There is something fishy in that and related code, i just can't pinpoint it out 
yet. I'll try to write simple test for this on Monday and re-read all the code 
again to be sure.

It might be (speculation!) that the write lock prevents second call to 
{code}
        element = cache.get(key);
{code}
to be executed, but since this internal cache is not synchronized, there is no 
guarantee by JVM that given thread will see already value put in by other 
thread. Those locks serialize only the code execution but not memory visibility 
(oh that sounds soo smart ... must be just effect of re-reading Concurency in 
Practice :D )



> cache: single blocking request can block all other requests to cached content 
> ------------------------------------------------------------------------------
>
>                 Key: MAGNOLIA-3167
>                 URL: http://jira.magnolia-cms.com/browse/MAGNOLIA-3167
>             Project: Magnolia
>          Issue Type: Bug
>          Components: cache
>    Affects Versions: 3.6.8, 4.1.4, 4.2.3, 4.3.1
>            Reporter: Philipp Bärfuss
>            Assignee: Boris Kraft
>             Fix For: 4.3.x
>
>
> the cache mechanism can block all requests:
> * cache.get() will block if an other request is caching the same key (this is 
> a feature of the BlockingCache)
>   ** mutex per key kept until cache.put() is called (either with an entry or 
> null value)
> * this code is again in a synchronized block which synchronizes on the cache 
> object itself
>   ** this blocks all other request trying to enter the synchronization block
> The critical scenario which can prevent magnolia from responding any request 
> (all threads blocked) is the following
> 1) first request to a resource which is slow or never returns (request to a 
> service, poor database connection, ..)
> 2) second request to the same resource: --> thread is blocked at 
> EhCacheWrapper.get(key):56, but also keeps the lock on the cache
> 3) all other caching requests are blocked (no matter which url) due to the 
> synchronize block at Default.shouldCache(Cache, AggregationState, 
> FlushPolicy):89
> Solution:
> * don't synchronize on the cache (why are we doing this???)
> * allow configuration of 
> [BlockingCache.timeoutMillis|http://ehcache.org/apidocs/net/sf/ehcache/constructs/blocking/BlockingCache.html#timeoutMillis]
>   ** throw an exception if a request waits for to long
> * uncomment finally block at doFilter(HttpServletRequest, 
> HttpServletResponse, FilterChain), this is a safety net and should log a 
> FATAL ERROR message
>   ** only relevant if the result is a store request

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://jira.magnolia-cms.com/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira



----------------------------------------------------------------
For list details see
http://www.magnolia-cms.com/home/community/mailing-lists.html
To unsubscribe, E-mail to: <dev-list-unsubscr...@magnolia-cms.com>
----------------------------------------------------------------

Reply via email to