/*
* Copyright 2010-2012 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package voldemort.store.routed.action;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import voldemort.VoldemortApplicationException;
import voldemort.cluster.Node;
import voldemort.cluster.failuredetector.FailureDetector;
import voldemort.store.StoreTimeoutException;
import voldemort.store.UnreachableStoreException;
import voldemort.store.routed.Pipeline;
import voldemort.store.routed.Pipeline.Event;
import voldemort.store.routed.PipelineData;
import voldemort.store.routed.Response;
import voldemort.utils.Utils;
import voldemort.versioning.ObsoleteVersionException;
public abstract class AbstractAction<K, V, PD extends PipelineData<K, V>> implements Action {
protected final PD pipelineData;
protected final Event completeEvent;
protected final Logger logger = Logger.getLogger(getClass());
protected AbstractAction(PD pipelineData, Event completeEvent) {
this.pipelineData = Utils.notNull(pipelineData);
this.completeEvent = Utils.notNull(completeEvent);
}
protected boolean handleResponseError(Response<?, ?> response,
Pipeline pipeline,
FailureDetector failureDetector) {
return handleResponseError((Exception) response.getValue(),
response.getNode(),
response.getRequestTime(),
pipeline,
failureDetector);
}
protected boolean handleResponseError(Exception e,
Node node,
long requestTime,
Pipeline pipeline,
FailureDetector failureDetector) {
if(e instanceof StoreTimeoutException || e instanceof ObsoleteVersionException
|| e instanceof UnreachableStoreException) {
// Quietly mask all errors that are "expected" regularly.
if(logger.isEnabledFor(Level.DEBUG)) {
logger.debug("Error in " + pipeline.getOperation().getSimpleName() + " on node "
+ node.getId() + " (" + node.getHost() + ") : " + e.getMessage());
}
} else {
// Printing Call Stack causes EKG ticket to be opened. So only include the call stack for Debug level or Inner exceptions.
if(logger.isEnabledFor(Level.WARN)) {
String errorMessage = "Error in " + pipeline.getOperation().getSimpleName() + " on node "
+ node.getId() + " (" + node.getHost() + ")";
if(logger.isEnabledFor(Level.DEBUG) || e.getCause() != null) {
logger.warn(errorMessage, e);
}
else {
errorMessage += " : ExceptionType " + e.getClass().getSimpleName();
errorMessage += " : ExceptionMessage " + e.getMessage();
logger.warn(errorMessage);
}
}
}
if(e instanceof UnreachableStoreException) {
if(logger.isTraceEnabled()) {
logger.trace("Adding node [" + node + "] to failed nodes list");
}
pipelineData.addFailedNode(node);
pipelineData.recordFailure(e);
failureDetector.recordException(node, requestTime, (UnreachableStoreException) e);
} else if(e instanceof VoldemortApplicationException) {
pipelineData.setFatalError((VoldemortApplicationException) e);
pipeline.abort();
if(logger.isEnabledFor(Level.TRACE))
logger.trace("Error is terminal - aborting further pipeline processing");
return true;
} else {
pipelineData.recordFailure(e);
}
return false;
}
}