use of com.orientechnologies.orient.server.distributed.task.ORemoteTask in project orientdb by orientechnologies.
the class OCreateRecordTask method getFixTask.
@Override
public ORemoteTask getFixTask(final ODistributedRequest iRequest, ORemoteTask iOriginalTask, final Object iBadResponse, final Object iGoodResponse, final String executorNode, final ODistributedServerManager dManager) {
if (iBadResponse == null || (iBadResponse instanceof Throwable && !(iBadResponse instanceof ONeedRetryException)))
return null;
ORemoteTask result = null;
final OPlaceholder goodResult = (OPlaceholder) iGoodResponse;
if (iBadResponse instanceof ONeedRetryException)
return ((OCreateRecordTask) dManager.getTaskFactoryManager().getFactoryByServerName(executorNode).createTask(OCreateRecordTask.FACTORYID)).init((ORecordId) goodResult.getIdentity(), content, ORecordVersionHelper.setRollbackMode(version), recordType);
final OPlaceholder badResult = (OPlaceholder) iBadResponse;
if (!badResult.equals(goodResult)) {
// CREATE RECORD FAILED TO HAVE THE SAME RIDS. FORCE REALIGNING OF DATA CLUSTERS
if (badResult.getIdentity().getClusterId() == goodResult.getIdentity().getClusterId() && badResult.getIdentity().getClusterPosition() < goodResult.getIdentity().getClusterPosition()) {
final long minPos = Math.max(badResult.getIdentity().getClusterPosition() - 1, 0);
for (long pos = minPos; pos < goodResult.getIdentity().getClusterPosition(); ++pos) {
// UPDATE INTERMEDIATE RECORDS
final ORecordId toUpdateRid = new ORecordId(goodResult.getIdentity().getClusterId(), pos);
final ORecord toUpdateRecord;
if (dManager.getLocalNodeName().equals(executorNode)) {
// SAME SERVER: LOAD THE RECORD FROM ANOTHER NODE
final ODistributedConfiguration dCfg = dManager.getDatabaseConfiguration(iRequest.getDatabaseName());
final List<String> nodes = dCfg.getServers(ODatabaseRecordThreadLocal.INSTANCE.get().getClusterNameById(clusterId), dManager.getLocalNodeName());
final OReadRecordTask task = (OReadRecordTask) dManager.getTaskFactoryManager().getFactoryByServerNames(nodes).createTask(OReadRecordTask.FACTORYID);
task.init(toUpdateRid);
final ODistributedResponse response = dManager.sendRequest(iRequest.getDatabaseName(), null, nodes, task, dManager.getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.RESPONSE, null, null, null);
final ORawBuffer remoteReadRecord = (ORawBuffer) response.getPayload();
if (remoteReadRecord != null) {
toUpdateRecord = Orient.instance().getRecordFactoryManager().newInstance(recordType);
ORecordInternal.fill(toUpdateRecord, toUpdateRid, remoteReadRecord.version, remoteReadRecord.buffer, false);
} else
toUpdateRecord = null;
} else
// LOAD IT LOCALLY
toUpdateRecord = toUpdateRid.getRecord();
if (toUpdateRecord != null)
try {
new OFixUpdateRecordTask().init(toUpdateRid, toUpdateRecord.toStream(), toUpdateRecord.getVersion(), ORecordInternal.getRecordType(toUpdateRecord)).execute(iRequest.getId(), dManager.getServerInstance(), dManager, ODatabaseRecordThreadLocal.INSTANCE.get());
} catch (Exception e) {
throw OException.wrapException(new ODistributedOperationException("Cannot create record " + rid + " because assigned RID is different"), e);
}
}
// CREATE LAST RECORD
final OCreateRecordTask task = (OCreateRecordTask) dManager.getTaskFactoryManager().getFactoryByServerName(executorNode).createTask(OCreateRecordTask.FACTORYID);
task.init((ORecordId) goodResult.getIdentity(), content, version, recordType);
result = task;
} else if (badResult.getIdentity().getClusterId() == goodResult.getIdentity().getClusterId() && badResult.getIdentity().getClusterPosition() > goodResult.getIdentity().getClusterPosition()) {
} else {
// ANY OTHER CASE JUST DELETE IT
final OFixCreateRecordTask task = (OFixCreateRecordTask) dManager.getTaskFactoryManager().getFactoryByServerName(executorNode).createTask(OFixCreateRecordTask.FACTORYID);
task.init(new ORecordId(badResult.getIdentity()), badResult.getVersion());
result = task;
}
}
return result;
}
use of com.orientechnologies.orient.server.distributed.task.ORemoteTask in project orientdb by orientechnologies.
the class OAbstract2pcTask method getUndoTask.
@Override
public ORemoteTask getUndoTask(ODistributedServerManager dManager, final ODistributedRequestId reqId, final List<String> servers) {
final OCompleted2pcTask fixTask = (OCompleted2pcTask) dManager.getTaskFactoryManager().getFactoryByServerNames(servers).createTask(OCompleted2pcTask.FACTORYID);
fixTask.init(reqId, false, getPartitionKey());
for (ORemoteTask undoTask : localUndoTasks) fixTask.addFixTask(undoTask);
return fixTask;
}
use of com.orientechnologies.orient.server.distributed.task.ORemoteTask in project orientdb by orientechnologies.
the class OCompleted2pcTask method fromStream.
@Override
public void fromStream(final DataInput in, ORemoteTaskFactory taskFactory) throws IOException {
requestId = new ODistributedRequestId();
requestId.fromStream(in);
success = in.readBoolean();
final int tasksSize = in.readInt();
for (int i = 0; i < tasksSize; ++i) {
final ORemoteTask task = taskFactory.createTask(in.readByte());
task.fromStream(in, taskFactory);
fixTasks.add(task);
}
}
use of com.orientechnologies.orient.server.distributed.task.ORemoteTask 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.ORemoteTask 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;
}
Aggregations