Search in sources :

Example 1 with OAbstractReplicatedTask

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;
}
Also used : ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask) OAbstractReplicatedTask(com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)

Example 2 with OAbstractReplicatedTask

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());
                    }
                }
            }
        }
    }
}
Also used : ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask) OAbstractReplicatedTask(com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)

Example 3 with OAbstractReplicatedTask

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;
}
Also used : ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask) OAbstractReplicatedTask(com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)

Example 4 with OAbstractReplicatedTask

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;
}
Also used : ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask) OAbstractReplicatedTask(com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)

Example 5 with OAbstractReplicatedTask

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 + "'");
}
Also used : ODatabaseIsOldException(com.orientechnologies.orient.server.distributed.task.ODatabaseIsOldException) OStorage(com.orientechnologies.orient.core.storage.OStorage) OLogSequenceNumber(com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OLogSequenceNumber) OClusterPositionMap(com.orientechnologies.orient.core.storage.impl.local.paginated.OClusterPositionMap) OAbstractReplicatedTask(com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)

Aggregations

OAbstractReplicatedTask (com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)5 ORemoteTask (com.orientechnologies.orient.server.distributed.task.ORemoteTask)4 ODistributedRecordLockedException (com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException)2 OStorage (com.orientechnologies.orient.core.storage.OStorage)1 OClusterPositionMap (com.orientechnologies.orient.core.storage.impl.local.paginated.OClusterPositionMap)1 OLogSequenceNumber (com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OLogSequenceNumber)1 ODatabaseIsOldException (com.orientechnologies.orient.server.distributed.task.ODatabaseIsOldException)1