The new version seems to be working great, except it now seems to log
every ObsoleteVersionException at warning level, in addition to
throwing it into the application.
In our system we have a lot of concurrency and we expect
ObsoleteVersionExceptions to be thrown, we handle these by doing a
manual get-merge-put when we catch it. Additionally we have our own
logging so voldemort logging exceptions which it also throws into the
application would cause exceptions to get logged twice.
To put we are using this method:
http://project-voldemort.com/javadoc/all/voldemort/client/StoreClient.html#put%28K,%20voldemort.versioning.Versioned%29
Do we need to use putIfNotObsolete instead?
Just wondering if anyone else experiences this, if it is a bug in the
new version, or if we are not using the API correctly. Thanks!
Our investigation into the voldemort source is below.
---
In 0.90.1 PUTs seem to be handled by class PerformSerialPutRequests:
https://github.com/voldemort/voldemort/blob/master/src/java/voldemort/store/routed/action/PerformSerialPutRequests.java
...which catches exceptions as follows:
<pre>
} catch(Exception e) {
long requestTime = (System.nanoTime() - start) /
Time.NS_PER_MS;
if(handleResponseError(e, node, requestTime, pipeline,
failureDetector))
return;
}
</pre>
...it then calls handleResponseError in its superclass:
https://github.com/voldemort/voldemort/blob/master/src/java/voldemort/store/routed/action/AbstractAction.java
...which logs the exception then enters the "e instanceof
VoldemortApplicationException" branch since ObsoleteVersionException
extends VoldemortApplicationException.
That sets ObsoleteVersionException into pipelineData.
<pre>
if(logger.isEnabledFor(Level.WARN))
logger.warn("Error in " +
pipeline.getOperation().getSimpleName() + " on node "
+ node.getId() + "(" + node.getHost() + ")",
e);
if(e instanceof UnreachableStoreException) {
pipelineData.addFailedNode(node);
pipelineData.recordFailure(e);
failureDetector.recordException(node, requestTime,
(UnreachableStoreException) e);
} else if(e instanceof VoldemortApplicationException) {
pipelineData.setFatalError((VoldemortApplicationException)
e);
pipeline.abort();
</pre>
Control then returns to:
https://github.com/voldemort/voldemort/blob/master/src/java/voldemort/store/routed/PipelineRoutedStore.java
<pre>
pipeline.execute();
if(pipelineData.getFatalError() != null)
throw pipelineData.getFatalError();
</pre>
This class checks if pipelineData contains a fatal error, and if so
throws it. So voldemort has logged and then throws
ObsoleteVersionException.