/*
* Copyright 2010 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;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import voldemort.VoldemortException;
import voldemort.cluster.Node;
import voldemort.store.routed.Pipeline.Event;
/**
* PipelineData includes a common set of data that is used to represent the
* state within the {@link Pipeline} as it moves from action to action. There's
* a one-to-one correspondence between a {@link Pipeline} and
* {@link PipelineData}, though the latter is not included as an instance
* variable. Action implementations usually include the {@link PipelineData} as
* an instance variable upon creation.
*
* It's basically a POJO that includes some relevant state for the pipeline
* execution:
*
* There are some subclasses of {@link PipelineData} that are used to handle the
* different types of operations:
*
* <ol>
* <li>{@link BasicPipelineData} - used by most operations; includes a list of
* {@link Node} instances relevant to the key in the operation among other
* values
* <li>{@link GetAllPipelineData} - used by the "get all" operation
* specifically, due to the fact that it includes Map data structures which
* don't fit in well in the generic structure
* <li>{@link PutPipelineData} - used only by the "put" operation as it includes
* data specific to that operation
* </ol>
*
* @param <K> Type for the key used in the request
* @param <V> Type for the value returned by the call
*
* @see Pipeline
* @see PipelineData
* @see BasicPipelineData
* @see GetAllPipelineData
* @see PutPipelineData
*/
public abstract class PipelineData<K, V> {
private final List<Response<K, V>> responses;
protected final List<Exception> failures;
protected VoldemortException fatalError;
protected volatile String storeName;
protected final List<Node> failedNodes;
protected List<Node> replicationSet;
protected PipelineRoutedStats stats;
public void setStats(PipelineRoutedStats stats) {
this.stats = stats;
}
public List<Node> getReplicationSet() {
return replicationSet;
}
public void setReplicationSet(List<Node> replicationSet) {
this.replicationSet = replicationSet;
}
public PipelineData() {
// responses are always added from single thread.
this.responses = new ArrayList<Response<K, V>>();
this.failures = new CopyOnWriteArrayList<Exception>();
this.failedNodes = new CopyOnWriteArrayList<Node>();
}
/**
* Returns is a list of responses that are received by requests to remote
* Voldemort nodes, either synchronous or asynchronous.
*
* @return List of {@link Response} instances
*/
public List<Response<K, V>> getResponses() {
return responses;
}
/**
* Returns a "fatal" error that occurred while attempting to contact the
* remote Voldemort nodes.
*
* <p/>
*
* If a hard error occurs, fatalError will be populated and the
* {@link Event#COMPLETED} event will be pushed onto the Pipeline event
* stack.
*
* @return {@link VoldemortException}, or null if no fatal error occurred
* during processing
*/
public VoldemortException getFatalError() {
return fatalError;
}
public void setFatalError(VoldemortException fatalError) {
reportException(fatalError);
this.fatalError = fatalError;
}
/**
* Returns a list of zero or more errors that occurred while attempting to
* contact the remote Voldemort node.
*
* @return List of non-fatal exceptions
*/
public List<Exception> getFailures() {
return failures;
}
/**
* Adds an error to the list errors that occurred while attempting to
* contact the remote Voldemort node.
*
* @param e Exception
*/
public void recordFailure(Exception e) {
reportException(e);
this.failures.add(e);
}
public void addFailedNode(Node node) {
failedNodes.add(node);
}
public List<Node> getFailedNodes() {
return failedNodes;
}
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
public void reportException(Exception e) {
if(stats != null) {
stats.reportException(e);
}
}
}