Search in sources :

Example 11 with ORemoteTask

use of com.orientechnologies.orient.server.distributed.task.ORemoteTask 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 12 with ORemoteTask

use of com.orientechnologies.orient.server.distributed.task.ORemoteTask in project orientdb by orientechnologies.

the class ODistributedDatabaseImpl method send2Nodes.

@Override
public ODistributedResponse send2Nodes(final ODistributedRequest iRequest, final Collection<String> iClusterNames, Collection<String> iNodes, final ODistributedRequest.EXECUTION_MODE iExecutionMode, final Object localResult, final OCallable<Void, ODistributedRequestId> iAfterSentCallback, final OCallable<Void, ODistributedResponseManager> endCallback) {
    boolean afterSendCallBackCalled = false;
    try {
        checkForServerOnline(iRequest);
        final String databaseName = iRequest.getDatabaseName();
        if (iNodes.isEmpty()) {
            ODistributedServerLog.error(this, localNodeName, null, DIRECTION.OUT, "No nodes configured for database '%s' request: %s", databaseName, iRequest);
            throw new ODistributedException("No nodes configured for partition '" + databaseName + "' request: " + iRequest);
        }
        final ODistributedConfiguration cfg = manager.getDatabaseConfiguration(databaseName);
        final ORemoteTask task = iRequest.getTask();
        final boolean checkNodesAreOnline = task.isNodeOnlineRequired();
        final Set<String> nodesConcurToTheQuorum = manager.getDistributedStrategy().getNodesConcurInQuorum(manager, cfg, iRequest, iNodes, databaseName, localResult);
        // AFTER COMPUTED THE QUORUM, REMOVE THE OFFLINE NODES TO HAVE THE LIST OF REAL AVAILABLE NODES
        final int availableNodes = checkNodesAreOnline ? manager.getNodesWithStatus(iNodes, databaseName, ODistributedServerManager.DB_STATUS.ONLINE, ODistributedServerManager.DB_STATUS.BACKUP, ODistributedServerManager.DB_STATUS.SYNCHRONIZING) : iNodes.size();
        final int expectedResponses = localResult != null ? availableNodes + 1 : availableNodes;
        final int quorum = calculateQuorum(task.getQuorumType(), iClusterNames, cfg, expectedResponses, nodesConcurToTheQuorum.size(), checkNodesAreOnline, localNodeName);
        final boolean groupByResponse = task.getResultStrategy() != OAbstractRemoteTask.RESULT_STRATEGY.UNION;
        final boolean waitLocalNode = waitForLocalNode(cfg, iClusterNames, iNodes);
        // CREATE THE RESPONSE MANAGER
        final ODistributedResponseManager currentResponseMgr = new ODistributedResponseManager(manager, iRequest, iNodes, nodesConcurToTheQuorum, expectedResponses, quorum, waitLocalNode, adjustTimeoutWithLatency(iNodes, task.getSynchronousTimeout(expectedResponses), iRequest.getId()), adjustTimeoutWithLatency(iNodes, task.getTotalTimeout(availableNodes), iRequest.getId()), groupByResponse, endCallback);
        if (localResult != null && currentResponseMgr.setLocalResult(localNodeName, localResult)) {
            // COLLECT LOCAL RESULT
            return currentResponseMgr.getQuorumResponse();
        }
        // SORT THE NODE TO GUARANTEE THE SAME ORDER OF DELIVERY
        if (!(iNodes instanceof List))
            iNodes = new ArrayList<String>(iNodes);
        if (iNodes.size() > 1)
            Collections.sort((List<String>) iNodes);
        msgService.registerRequest(iRequest.getId().getMessageId(), currentResponseMgr);
        if (ODistributedServerLog.isDebugEnabled())
            ODistributedServerLog.debug(this, localNodeName, iNodes.toString(), DIRECTION.OUT, "Sending request %s...", iRequest);
        for (String node : iNodes) {
            // CATCH ANY EXCEPTION LOG IT AND IGNORE TO CONTINUE SENDING REQUESTS TO OTHER NODES
            try {
                final ORemoteServerController remoteServer = manager.getRemoteServer(node);
                remoteServer.sendRequest(iRequest);
            } catch (Throwable e) {
                currentResponseMgr.removeServerBecauseUnreachable(node);
                String reason = e.getMessage();
                if (e instanceof ODistributedException && e.getCause() instanceof IOException) {
                    // CONNECTION ERROR: REMOVE THE CONNECTION
                    reason = e.getCause().getMessage();
                    manager.closeRemoteServer(node);
                } else if (e instanceof OSecurityAccessException) {
                    // THE CONNECTION COULD BE STALE, CREATE A NEW ONE AND RETRY
                    manager.closeRemoteServer(node);
                    try {
                        final ORemoteServerController remoteServer = manager.getRemoteServer(node);
                        remoteServer.sendRequest(iRequest);
                        continue;
                    } catch (Throwable ex) {
                    // IGNORE IT BECAUSE MANAGED BELOW
                    }
                }
                if (!manager.isNodeAvailable(node))
                    // NODE IS NOT AVAILABLE
                    ODistributedServerLog.debug(this, localNodeName, node, ODistributedServerLog.DIRECTION.OUT, "Error on sending distributed request %s. The target node is not available. Active nodes: %s", e, iRequest, manager.getAvailableNodeNames(databaseName));
                else
                    ODistributedServerLog.error(this, localNodeName, node, ODistributedServerLog.DIRECTION.OUT, "Error on sending distributed request %s (err=%s). Active nodes: %s", iRequest, reason, manager.getAvailableNodeNames(databaseName));
            }
        }
        if (currentResponseMgr.getExpectedNodes().isEmpty())
            // NO SERVER TO SEND A MESSAGE
            throw new ODistributedException("No server active for distributed request (" + iRequest + ") against database '" + databaseName + (iClusterNames != null ? "." + iClusterNames : "") + "' to nodes " + iNodes);
        if (ODistributedServerLog.isDebugEnabled())
            ODistributedServerLog.debug(this, localNodeName, iNodes.toString(), DIRECTION.OUT, "Sent request %s", iRequest);
        totalSentRequests.incrementAndGet();
        afterSendCallBackCalled = true;
        if (iAfterSentCallback != null)
            iAfterSentCallback.call(iRequest.getId());
        if (iExecutionMode == ODistributedRequest.EXECUTION_MODE.RESPONSE)
            return waitForResponse(iRequest, currentResponseMgr);
        return null;
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw OException.wrapException(new ODistributedException("Error on executing distributed request (" + iRequest + ") against database '" + databaseName + (iClusterNames != null ? "." + iClusterNames : "") + "' to nodes " + iNodes), e);
    } finally {
        if (iAfterSentCallback != null && !afterSendCallBackCalled)
            iAfterSentCallback.call(iRequest.getId());
    }
}
Also used : IOException(java.io.IOException) ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask) OConfigurationException(com.orientechnologies.orient.core.exception.OConfigurationException) OException(com.orientechnologies.common.exception.OException) ODistributedOperationException(com.orientechnologies.orient.server.distributed.task.ODistributedOperationException) ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) IOException(java.io.IOException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OSecurityAccessException(com.orientechnologies.orient.core.exception.OSecurityAccessException) OSecurityAccessException(com.orientechnologies.orient.core.exception.OSecurityAccessException)

Example 13 with ORemoteTask

use of com.orientechnologies.orient.server.distributed.task.ORemoteTask in project orientdb by orientechnologies.

the class OAbstract2pcTask method getFixTask.

@Override
public ORemoteTask getFixTask(final ODistributedRequest iRequest, final ORemoteTask iOriginalTask, final Object iBadResponse, final Object iGoodResponse, final String executorNodeName, final ODistributedServerManager dManager) {
    if (!(iGoodResponse instanceof OTxTaskResult)) {
        // TODO: MANAGE ERROR ON LOCAL NODE
        ODistributedServerLog.debug(this, getNodeSource(), null, DIRECTION.NONE, "Error on creating fix-task for request: '%s' because good response is not expected type: %s", iRequest, iBadResponse);
        return null;
    }
    final OCompleted2pcTask fixTask = (OCompleted2pcTask) dManager.getTaskFactoryManager().getFactoryByServerName(executorNodeName).createTask(OCompleted2pcTask.FACTORYID);
    fixTask.init(iRequest.getId(), false, getPartitionKey());
    for (int i = 0; i < tasks.size(); ++i) {
        final OAbstractRecordReplicatedTask t = tasks.get(i);
        final Object badResult = iBadResponse == null ? null : iBadResponse instanceof Throwable ? iBadResponse : ((OTxTaskResult) iBadResponse).results.get(i);
        final Object goodResult = ((OTxTaskResult) iGoodResponse).results.get(i);
        final ORemoteTask undoTask = t.getFixTask(iRequest, t, badResult, goodResult, executorNodeName, dManager);
        if (undoTask == null)
            return null;
        fixTask.addFixTask(undoTask);
    }
    return fixTask;
}
Also used : OAbstractRecordReplicatedTask(com.orientechnologies.orient.server.distributed.task.OAbstractRecordReplicatedTask) ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask)

Example 14 with ORemoteTask

use of com.orientechnologies.orient.server.distributed.task.ORemoteTask in project orientdb by orientechnologies.

the class OAbstract2pcTask method fromStream.

@Override
public void fromStream(final DataInput in, final ORemoteTaskFactory factory) throws IOException {
    final int size = in.readInt();
    for (int i = 0; i < size; ++i) {
        final ORemoteTask task = factory.createTask(in.readByte());
        task.fromStream(in, factory);
        tasks.add((OAbstractRecordReplicatedTask) task);
    }
    final boolean hasLastLSN = in.readBoolean();
    if (hasLastLSN)
        lastLSN = new OLogSequenceNumber(in);
}
Also used : OLogSequenceNumber(com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OLogSequenceNumber) ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask)

Example 15 with ORemoteTask

use of com.orientechnologies.orient.server.distributed.task.ORemoteTask in project orientdb by orientechnologies.

the class OCompleted2pcTask method toStream.

@Override
public void toStream(final DataOutput out) throws IOException {
    requestId.toStream(out);
    out.writeBoolean(success);
    out.writeInt(fixTasks.size());
    for (ORemoteTask task : fixTasks) {
        out.writeByte(task.getFactoryId());
        task.toStream(out);
    }
}
Also used : ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask)

Aggregations

ORemoteTask (com.orientechnologies.orient.server.distributed.task.ORemoteTask)16 ODistributedOperationException (com.orientechnologies.orient.server.distributed.task.ODistributedOperationException)6 OAbstractReplicatedTask (com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)4 ODistributedRecordLockedException (com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException)4 OException (com.orientechnologies.common.exception.OException)3 IOException (java.io.IOException)3 OOfflineNodeException (com.orientechnologies.common.concur.OOfflineNodeException)2 OConfigurationException (com.orientechnologies.orient.core.exception.OConfigurationException)2 OSecurityAccessException (com.orientechnologies.orient.core.exception.OSecurityAccessException)2 ORecordId (com.orientechnologies.orient.core.id.ORecordId)2 OWaitForTask (com.orientechnologies.orient.server.distributed.impl.task.OWaitForTask)2 OAbstractRecordReplicatedTask (com.orientechnologies.orient.server.distributed.task.OAbstractRecordReplicatedTask)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 ONeedRetryException (com.orientechnologies.common.concur.ONeedRetryException)1 OModificationOperationProhibitedException (com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException)1 OPlaceholder (com.orientechnologies.orient.core.db.record.OPlaceholder)1 ORID (com.orientechnologies.orient.core.id.ORID)1 OSecurityUser (com.orientechnologies.orient.core.metadata.security.OSecurityUser)1 ORecord (com.orientechnologies.orient.core.record.ORecord)1 ORawBuffer (com.orientechnologies.orient.core.storage.ORawBuffer)1