use of com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask in project orientdb by orientechnologies.
the class ODistributedResponseManager method fixNodesInConflict.
protected boolean fixNodesInConflict(final List<ODistributedResponse> bestResponsesGroup, final int conflicts) {
// NO FIFTY/FIFTY CASE: FIX THE CONFLICTED NODES BY OVERWRITING THE RECORD WITH THE WINNER'S RESULT
final ODistributedResponse goodResponse = bestResponsesGroup.get(0);
if (goodResponse.getPayload() instanceof Throwable)
return false;
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "Detected %d conflicts, but the quorum (%d) has been reached. Fixing remote records. Request (%s)", conflicts, quorum, request);
for (List<ODistributedResponse> responseGroup : responseGroups) {
if (responseGroup != bestResponsesGroup) {
// CONFLICT GROUP: FIX THEM ONE BY ONE
for (ODistributedResponse r : responseGroup) {
if (r.getPayload() instanceof ODistributedRecordLockedException)
// NO FIX, THE RECORD WAS LOCKED
return false;
final ORemoteTask fixTask = ((OAbstractReplicatedTask) request.getTask()).getFixTask(request, request.getTask(), r.getPayload(), goodResponse.getPayload(), r.getExecutorNodeName(), dManager);
if (fixTask == null)
// FIX NOT AVAILABLE: UNDO THE ENTIRE OPERATION
return false;
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), r.getExecutorNodeName(), DIRECTION.OUT, "Sending fix message (%s) for response (%s) on request (%s) to be: %s", fixTask, r, request, goodResponse);
dManager.sendRequest(request.getDatabaseName(), null, OMultiValue.getSingletonList(r.getExecutorNodeName()), fixTask, dManager.getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.NO_RESPONSE, null, null);
}
}
}
return true;
}
use of com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask in project orientdb by orientechnologies.
the class ODistributedResponseManager method end.
private void end() {
if (endCallback != null)
// CUSTOM CALLBACK
endCallback.call(this);
else {
// DEFAULT CALLBACK
if (groupResponsesByResult) {
final String localNodeName = dManager.getLocalNodeName();
final Set<String> serversToFollowup = getServersWithoutFollowup();
serversToFollowup.remove(localNodeName);
if (!serversToFollowup.isEmpty()) {
ODistributedServerLog.debug(this, localNodeName, serversToFollowup.toString(), ODistributedServerLog.DIRECTION.OUT, "Distributed transaction (reqId=%s quorum=%d result=%s), checking for any fix needed...", request.getId(), quorum, quorumResponse);
for (String s : serversToFollowup) {
Object response = responses.get(s);
if (response == NO_RESPONSE)
response = null;
if (quorumResponse != null && !quorumResponse.equals(response)) {
// SEND FIX
final Object payload = response instanceof ODistributedResponse ? ((ODistributedResponse) response).getPayload() : null;
final ORemoteTask fixTask = ((OAbstractReplicatedTask) request.getTask()).getFixTask(request, request.getTask(), payload, quorumResponse.getPayload(), s, dManager);
if (fixTask == null) {
// FIX NOT AVAILABLE: UNDO THE ENTIRE OPERATION
ODistributedServerLog.debug(this, localNodeName, null, DIRECTION.NONE, "No fix operation available: cannot fix the operation, undo the entire operation (reqId=%s)", request);
continue;
}
executeFix(s, fixTask, response, quorumResponse.getPayload());
}
}
}
}
}
}
use of com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask in project orientdb by orientechnologies.
the class ODistributedResponseManager method undoRequest.
protected boolean undoRequest() {
final ORemoteTask task = request.getTask();
if (task.isIdempotent()) {
// NO UNDO IS NECESSARY
ODistributedServerLog.warn(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "No undo because the task (%s) is idempotent", task);
return false;
}
// DETERMINE IF ANY CREATE FAILED TO RESTORE RIDS
for (ODistributedResponse r : getReceivedResponses()) {
if (r.getPayload() instanceof Throwable)
// TODO: CONSIDER DIFFERENT TYPE OF EXCEPTION, SOME OF THOSE COULD REQUIRE AN UNDO
continue;
if (r == localResponse)
// SKIP LOCAL SERVER (IT'S MANAGED APART)
continue;
final String targetNode = r.getExecutorNodeName();
if (targetNode.equals(dManager.getLocalNodeName()))
// AVOID TO UNDO LOCAL NODE BECAUSE THE OPERATION IS MANAGED APART
continue;
if (task instanceof OAbstractReplicatedTask) {
final List<String> servers = OMultiValue.getSingletonList(targetNode);
final ORemoteTask undoTask = ((OAbstractReplicatedTask) task).getUndoTask(dManager, request.getId(), servers);
if (undoTask != null) {
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), targetNode, DIRECTION.OUT, "Sending undo message (%s) for request (%s) database '%s' to server %s", undoTask, request, request.getDatabaseName(), targetNode);
final ODistributedResponse result = dManager.sendRequest(request.getDatabaseName(), null, servers, undoTask, dManager.getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.RESPONSE, null, null, null);
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), targetNode, DIRECTION.OUT, "Received response from undo message (%s) for request (%s) to server %s: %s", undoTask, request, targetNode, result);
}
}
}
return true;
}
use of com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask in project orientdb by orientechnologies.
the class ODistributedResponseManager method fixNodesInConflict.
protected boolean fixNodesInConflict(final List<ODistributedResponse> bestResponsesGroup, final int conflicts, final boolean cannotFixRecordLockException) {
// NO FIFTY/FIFTY CASE: FIX THE CONFLICTED NODES BY OVERWRITING THE RECORD WITH THE WINNER'S RESULT
final ODistributedResponse goodResponse = bestResponsesGroup.get(0);
if (goodResponse.getPayload() instanceof Throwable)
return false;
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "Detected %d conflicts, but the quorum (%d) has been reached. Checking responses and in case fixing remote records (reqId=%s)", conflicts, quorum, request.getId());
for (List<ODistributedResponse> responseGroup : responseGroups) {
if (responseGroup != bestResponsesGroup) {
// CONFLICT GROUP: FIX THEM ONE BY ONE
for (ODistributedResponse r : responseGroup) {
if (cannotFixRecordLockException && r.getPayload() instanceof ODistributedRecordLockedException) {
// NO FIX, THE RECORD WAS LOCKED
if (ODistributedServerLog.isDebugEnabled())
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "Node '%s' responded with a record lock exception: cannot fix the operation, undo the entire operation (reqId=%s)", r.getExecutorNodeName(), request);
return false;
}
final ORemoteTask fixTask = ((OAbstractReplicatedTask) request.getTask()).getFixTask(request, request.getTask(), r.getPayload(), goodResponse.getPayload(), r.getExecutorNodeName(), dManager);
if (fixTask == null) {
// FIX NOT AVAILABLE: UNDO THE ENTIRE OPERATION
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "No fix operation available: cannot fix the operation, undo the entire operation (reqId=%s)", request);
return false;
}
executeFix(r.getExecutorNodeName(), fixTask, r.getPayload(), goodResponse);
}
}
}
return true;
}
use of com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask in project orientdb by orientechnologies.
the class ODistributedAbstractPlugin method requestDatabaseFullSync.
protected boolean requestDatabaseFullSync(final ODistributedDatabaseImpl distrDatabase, final boolean backupDatabase, final String databaseName, final boolean iAskToAllNodes, final OModifiableDistributedConfiguration cfg) {
// GET ALL THE OTHER SERVERS
final Collection<String> nodes = cfg.getServers(null, nodeName);
if (nodes.isEmpty()) {
ODistributedServerLog.warn(this, nodeName, null, DIRECTION.NONE, "Cannot request full deploy of database '%s' because there are no nodes available with such database", databaseName);
return false;
}
final List<String> selectedNodes = new ArrayList<String>();
if (!iAskToAllNodes) {
// VALID FOR FURTHER NODES
for (String n : nodes) {
if (isNodeStatusEqualsTo(n, databaseName, DB_STATUS.BACKUP)) {
// SERVER ALREADY IN BACKUP: USE IT
selectedNodes.add(n);
break;
}
}
if (selectedNodes.isEmpty()) {
// GET THE FIRST ONE TO ASK FOR DATABASE. THIS FORCES TO HAVE ONE NODE TO DO BACKUP SAVING RESOURCES IN CASE BACKUP IS STILL
// VALID FOR FURTHER NODES
final Iterator<String> it = nodes.iterator();
while (it.hasNext()) {
final String f = it.next();
if (isNodeStatusEqualsTo(f, databaseName, DB_STATUS.ONLINE, DB_STATUS.BACKUP)) {
selectedNodes.add(f);
break;
}
}
}
}
if (selectedNodes.isEmpty())
// NO NODE ONLINE, SEND THE MESSAGE TO EVERYONE
selectedNodes.addAll(nodes);
ODistributedServerLog.info(this, nodeName, selectedNodes.toString(), DIRECTION.OUT, "Requesting deploy of database '%s' on local server...", databaseName);
final OLogSequenceNumber lastLSN = distrDatabase.getSyncConfiguration().getLastLSN(getLocalNodeName());
final OAbstractReplicatedTask deployTask = new OSyncDatabaseTask(lastLSN, distrDatabase.getSyncConfiguration().getLastOperationTimestamp());
final Map<String, Object> results = (Map<String, Object>) sendRequest(databaseName, null, selectedNodes, deployTask, getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.RESPONSE, null, null, null).getPayload();
ODistributedServerLog.debug(this, nodeName, selectedNodes.toString(), DIRECTION.OUT, "Deploy returned: %s", results);
final String dbPath = serverInstance.getDatabaseDirectory() + databaseName;
// EXTRACT THE REAL RESULT
for (Map.Entry<String, Object> r : results.entrySet()) {
final Object value = r.getValue();
if (value instanceof Boolean)
continue;
else if (value instanceof ODatabaseIsOldException) {
// MANAGE THIS EXCEPTION AT UPPER LEVEL
throw (ODatabaseIsOldException) value;
} else if (value instanceof Throwable) {
ODistributedServerLog.error(this, nodeName, r.getKey(), DIRECTION.IN, "Error on installing database '%s' in %s", (Exception) value, databaseName, dbPath);
setDatabaseStatus(nodeName, databaseName, DB_STATUS.NOT_AVAILABLE);
if (value instanceof ODistributedException)
throw (ODistributedException) value;
} else if (value instanceof ODistributedDatabaseChunk) {
// DISABLED BECAUSE MOMENTUM IS NOT RELIABLE YET
// distrDatabase.filterBeforeThisMomentum(((ODistributedDatabaseChunk) value).getMomentum());
final File uniqueClustersBackupDirectory = getClusterOwnedExclusivelyByCurrentNode(dbPath, databaseName);
// CLOSE THE STORAGE FIRST
final ODistributedStorage stg = storages.remove(databaseName);
if (stg != null)
stg.close(true, false);
if (backupDatabase)
backupCurrentDatabase(databaseName);
installDatabaseFromNetwork(dbPath, databaseName, distrDatabase, r.getKey(), (ODistributedDatabaseChunk) value, false, uniqueClustersBackupDirectory, cfg);
OStorage storage = storages.get(databaseName);
replaceStorageInSessions(storage);
distrDatabase.resume();
return true;
} else
throw new IllegalArgumentException("Type " + value + " not supported");
}
throw new ODistributedException("No response received from remote nodes for auto-deploy of database '" + databaseName + "'");
}
Aggregations