We are very happy with TreeCache and CacheLoader--the documentation for both is
first-rate, and the code works perfectly in our application.
However, there is one thing about the design that puzzles us, and we're hoping you can
explain it.
In our implementation, we currently don't use a CacheLoader. Instead, we have code
that follows this pattern:
result = null;
try
{
result = cache.get(key for what we want);
}
catch (Exception e)
{
dead...
}
if (result == null)
{
try
{
result = database.get(key for what we want);
}
catch (Exception e)
{
dead...
}
cache.put(key for what we want, result); // Spurious notification sent here.
}
return result;
}
That was how we got our prototype working, but we always planned to implement our own
CacheLoader to save and retrieve our data from our database, so that we wouldn't be
doing the puts to the cache of what we retrieved from the database.
The reason we didn't want to do the puts ourselves on reads from the database is we
figured that would send spurious notifications to other caches listening in our cluster,
at the point commented "// Spurious notification sent here.".
We think of that notification as spurious because it wasn't caused by a change to the
data--it was caused simply by reading some data and putting it in the cache, and why would
other listeners in the cluster care about a non-data-changing event? (They can fetch the
data themselves if they need it, and if they don't need it, why would they want to be
notified that another cache in the cluster happened to want it?)
We figured when you call a CacheLoader, you do a put-*without*-notification to the cache.
We figured put-without-notification is a hidden method, because it's not in the
TreeCache API (and if it was, we would have called it instead of the standard put).
So last week we dug into the CacheLoaderInterceptor code, and discovered that you
don't call a special put-without-notification method. Instead, you do this:
private NodeSPI loadNode(InvocationContext ctx, Fqn fqn, NodeSPI n, TransactionEntry
entry) throws Exception
{
if (trace) log.trace("loadNode " + fqn);
Map nodeData = loadData(fqn);
if (nodeData != null)
{
if (trace) log.trace("Node data is not null, loading");
cache.getNotifier().notifyNodeLoaded(fqn, true, Collections.emptyMap(), ctx); //
Spurious notification sent here.
if (isActivation)
{
cache.getNotifier().notifyNodeActivated(fqn, true, Collections.emptyMap(),
ctx); // Spurious notification sent here.
}
n = createNodes(fqn, entry);
// n.clearDataDirect();
n.setInternalState(nodeData);
// set this node as valid?
if (usingOptimisticInvalidation) n.setValid(true, false);
cache.getNotifier().notifyNodeLoaded(fqn, false, nodeData, ctx); // Spurious
notification sent here.
if (isActivation)
{
cache.getNotifier().notifyNodeActivated(fqn, false, nodeData, ctx); //
Spurious notification sent here.
}
}
if (n != null && !n.isDataLoaded())
{
if (trace) log.trace("Setting dataLoaded to true");
n.setDataLoaded(true);
}
return n;
}
Why do you notify other caches in a cluster when data is loaded from the database?
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4173985#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...