Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [cdt-dev] EDC and asynchronous operations

At 04:04 PM 10/26/2010, Pawel Piech wrote:
I don't think that's the case for the Transaction as implemented in bug 31345.  That's because the request monitor which is passed to a cache in ICache.update() ends up holding the strong reference to that cache.  However, this reference is for a cancel listener and could change with future changes to RequestMonitor.  It would be better to add the strong reference to the cache in Transaction itself.

Ah. Yes, I see that reference buried in there. I agree that that we need something more explicit and thus less fragile.


There's another problem to keep in mind.  Unless the cache objects themselves are listeners to events, it's important to hold the cache objects in the cache as long as there are strong references to it.  Otherwise a client holding a cache object may be reading stale data which should have been invalidated through the cache manager.  I guess this is another way to look at the 2.b.i statement, where leaf nodes should be collected before parents.

My cache objects are listeners, but only while they are in the valid state. An event from the source can invalidate a cache object, but it won't validate it, thus there is no point in remaining a listener when its state flips to invalid. I realize that technically a source event could be used to directly update and validate a cache object, but doing so could get tricky and it could prove to be pointless processing (the transaction might outright fail using another cache object).

However, the point you bring up is a non-issue in my cache manager implementation. Cleanup is done at the end of a transaction. A transaction's logic is expected to tell the cache manager when it begins and ends so that it can do the necessary tracking and cleanup. Also, it must never store a cache object anywhere. It must always ask the cache manager for anything it needs.

protected <sometype> process() throws InvalidCacheException, CoreException {
    boolean invalidCache = false;
    CacheManager cacheMgr = EDCLaunch.getCacheManager(dsfSession.getId());
    cacheMgr.beginTransaction();
    try {
        // ... logic  that uses cache objects obtained from cacheMgr
        return result;
     }
    catch (InvalidCacheException exc) {
        invalidCache = true;
        throw exc;
    }
    finally {
        cacheMgr.endTransaction(invalidCache);
    }
}


Also, using weak references could leave the cache being purged too aggressively.  A combination of soft references and weak references would solve the problem.

.... I'm looking forward to see what you come up with :-)

I'm thinking that, too. And combining weak references with soft references just sounds a bit messy and over-engineered. I think "simple" will work here. My manager works using a configurable ceiling. When the number of cache objects exceeds that limit by 20%, it goes through and purges as many of the least recently referenced (obtained) objects as possible to get back to the max count. It makes sure to not purge any cache objects that have been part of an InvalidCacheException-failed transaction.

John

Back to the top