}
if(logger.isDebugEnabled())
logger.debug("Performing serial put requests to determine master");
Node node = null;
for(; currentNode < nodes.size(); currentNode++) {
node = nodes.get(currentNode);
pipelineData.incrementNodeIndex();
VectorClock versionedClock = (VectorClock) versioned.getVersion();
final Versioned<byte[]> versionedCopy = new Versioned<byte[]>(versioned.getValue(),
versionedClock.incremented(node.getId(),
time.getMilliseconds()));
if(logger.isDebugEnabled())
logger.debug("Attempt #" + (currentNode + 1) + " to perform put (node "
+ node.getId() + ")");
long start = System.nanoTime();
try {
stores.get(node.getId()).put(key, versionedCopy, transforms);
long requestTime = (System.nanoTime() - start) / Time.NS_PER_MS;
pipelineData.incrementSuccesses();
failureDetector.recordSuccess(node, requestTime);
if(logger.isDebugEnabled())
logger.debug("Put on node " + node.getId() + " succeeded, using as master");
pipelineData.setMaster(node);
pipelineData.setVersionedCopy(versionedCopy);
pipelineData.getZoneResponses().add(node.getZoneId());
currentNode++;
break;
} catch(Exception e) {
long requestTime = (System.nanoTime() - start) / Time.NS_PER_MS;
if(logger.isDebugEnabled())
logger.debug("Master PUT at node " + currentNode + "(" + node.getHost() + ")"
+ " failed (" + e.getMessage() + ") in "
+ (System.nanoTime() - start) + " ns" + " (keyRef: "
+ System.identityHashCode(key) + ")");
if(PipelineRoutedStore.isSlopableFailure(e)) {
pipelineData.getSynchronizer().tryDelegateSlop(node);
}
if(handleResponseError(e, node, requestTime, pipeline, failureDetector))
return;
}
}
if(logger.isTraceEnabled()) {
logger.trace("PUT {key:" + key + "} currentNode=" + currentNode + " nodes.size()="
+ nodes.size());
}
if(pipelineData.getSuccesses() < 1) {
List<Exception> failures = pipelineData.getFailures();
pipelineData.setFatalError(new InsufficientOperationalNodesException("No master node succeeded!",
failures.size() > 0 ? failures.get(0)
: null));
pipeline.abort();
return;
}
// There aren't any more requests to make...
if(currentNode == nodes.size()) {
if(pipelineData.getSuccesses() < required) {
pipelineData.setFatalError(new InsufficientOperationalNodesException(required
+ " "
+ pipeline.getOperation()
.getSimpleName()
+ "s required, but only "
+ pipelineData.getSuccesses()
+ " succeeded",
new ArrayList<Node>(pipelineData.getReplicationSet()),
new ArrayList<Node>(pipelineData.getNodes()),
new ArrayList<Node>(pipelineData.getFailedNodes()),
pipelineData.getFailures()));
pipeline.abort();
} else {
if(pipelineData.getZonesRequired() != null) {
int zonesSatisfied = pipelineData.getZoneResponses().size();
if(zonesSatisfied >= (pipelineData.getZonesRequired() + 1)) {
pipeline.addEvent(completeEvent);
} else {
pipelineData.setFatalError(new InsufficientZoneResponsesException((pipelineData.getZonesRequired() + 1)
+ " "
+ pipeline.getOperation()
.getSimpleName()
+ "s required zone, but only "
+ zonesSatisfied
+ " succeeded"));
pipeline.abort();
}
} else {
if(logger.isDebugEnabled())
logger.debug("Finished master PUT for key "
+ ByteUtils.toHexString(key.get()) + " (keyRef: "
+ System.identityHashCode(key) + "); started at "
+ startMasterMs + " took "
+ (System.nanoTime() - startMasterNs) + " ns on node "
+ (node == null ? "NULL" : node.getId()) + "("
+ (node == null ? "NULL" : node.getHost()) + "); now complete");
pipeline.addEvent(completeEvent);
}
}
} else {
if(logger.isDebugEnabled())
logger.debug("Finished master PUT for key " + ByteUtils.toHexString(key.get())
+ " (keyRef: " + System.identityHashCode(key) + "); started at "
+ startMasterMs + " took " + (System.nanoTime() - startMasterNs)
+ " ns on node " + (node == null ? "NULL" : node.getId()) + "("
+ (node == null ? "NULL" : node.getHost()) + ")");
pipeline.addEvent(masterDeterminedEvent);
}
}