use of com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException in project orientdb by orientechnologies.
the class ODistributedWorker method onMessage.
/**
* Executes the remote call on the local node and send back the result
*/
protected void onMessage(final ODistributedRequest iRequest) {
String senderNodeName = null;
for (int retry = 0; retry < 10; retry++) {
senderNodeName = manager.getNodeNameById(iRequest.getId().getNodeId());
if (senderNodeName != null)
break;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new ODistributedException("Execution has been interrupted");
}
}
if (senderNodeName == null) {
ODistributedServerLog.warn(this, localNodeName, senderNodeName, DIRECTION.IN, "Sender server id %d is not registered in the cluster configuration, discard the request: (%s) (worker=%d)", iRequest.getId().getNodeId(), iRequest, id);
sendResponseBack(iRequest, new ODistributedException("Sender server id " + iRequest.getId().getNodeId() + " is not registered in the cluster configuration, discard the request"));
return;
}
final ORemoteTask task = iRequest.getTask();
if (ODistributedServerLog.isDebugEnabled())
ODistributedServerLog.debug(this, localNodeName, senderNodeName, DIRECTION.IN, "Received request: (%s) (worker=%d)", iRequest, id);
// EXECUTE IT LOCALLY
Object responsePayload = null;
OSecurityUser origin = null;
try {
waitNodeIsOnline();
distributed.waitIsReady(task);
if (task.isUsingDatabase()) {
initDatabaseInstance();
if (database == null)
throw new ODistributedOperationException("Error on executing remote request because the database '" + databaseName + "' is not available");
}
// reset to original user
if (database != null) {
database.activateOnCurrentThread();
origin = database.getUser();
try {
if (iRequest.getUserRID() != null && iRequest.getUserRID().isValid() && (lastUser == null || !(lastUser.getIdentity()).equals(iRequest.getUserRID()))) {
lastUser = database.getMetadata().getSecurity().getUser(iRequest.getUserRID());
// set to new user
database.setUser(lastUser);
} else
origin = null;
} catch (Throwable ex) {
OLogManager.instance().error(this, "Failed on user switching database. " + ex.getMessage());
}
}
// EXECUTE THE TASK
for (int retry = 1; running; ++retry) {
responsePayload = manager.executeOnLocalNode(iRequest.getId(), iRequest.getTask(), database);
if (responsePayload instanceof OModificationOperationProhibitedException) {
// RETRY
try {
ODistributedServerLog.info(this, localNodeName, senderNodeName, DIRECTION.IN, "Database is frozen, waiting and retrying. Request %s (retry=%d, worker=%d)", iRequest, retry, id);
Thread.sleep(1000);
} catch (InterruptedException e) {
}
} else {
// OPERATION EXECUTED (OK OR ERROR), NO RETRY NEEDED
if (retry > 1)
ODistributedServerLog.info(this, localNodeName, senderNodeName, DIRECTION.IN, "Request %s succeed after retry=%d", iRequest, retry);
break;
}
}
} catch (RuntimeException e) {
sendResponseBack(iRequest, e);
throw e;
} finally {
if (database != null && !database.isClosed()) {
database.activateOnCurrentThread();
if (!database.isClosed()) {
database.rollback();
database.getLocalCache().clear();
if (origin != null)
database.setUser(origin);
}
}
}
sendResponseBack(iRequest, responsePayload);
}
use of com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException in project orientdb by orientechnologies.
the class OStorageRemote method baseNetworkOperation.
public <T> T baseNetworkOperation(final OStorageRemoteOperation<T> operation, final String errorMessage, int retry) {
OStorageRemoteSession session = getCurrentSession();
if (session.commandExecuting)
throw new ODatabaseException("Cannot execute the request because an asynchronous operation is in progress. Please use a different connection");
String serverUrl = null;
do {
OChannelBinaryAsynchClient network = null;
if (serverUrl == null)
serverUrl = getNextAvailableServerURL(false, session);
do {
try {
network = getNetwork(serverUrl);
} catch (OException e) {
serverUrl = useNewServerURL(serverUrl);
if (serverUrl == null)
throw e;
}
} while (network == null);
try {
// In case i do not have a token or i'm switching between server i've to execute a open operation.
OStorageRemoteNodeSession nodeSession = session.getServerSession(network.getServerURL());
if (nodeSession == null || !nodeSession.isValid()) {
openRemoteDatabase(network);
if (!network.tryLock()) {
connectionManager.release(network);
continue;
}
}
return operation.execute(network, session);
} catch (ODistributedRedirectException e) {
connectionManager.release(network);
OLogManager.instance().debug(this, "Redirecting the request from server '%s' to the server '%s' because %s", e.getFromServer(), e.toString(), e.getMessage());
// RECONNECT TO THE SERVER SUGGESTED IN THE EXCEPTION
serverUrl = e.getToServerAddress();
} catch (OModificationOperationProhibitedException mope) {
connectionManager.release(network);
handleDBFreeze();
serverUrl = null;
} catch (OTokenException e) {
connectionManager.release(network);
session.removeServerSession(network.getServerURL());
if (--retry <= 0)
throw OException.wrapException(new OStorageException(errorMessage), e);
serverUrl = null;
} catch (OTokenSecurityException e) {
connectionManager.release(network);
session.removeServerSession(network.getServerURL());
if (--retry <= 0)
throw OException.wrapException(new OStorageException(errorMessage), e);
serverUrl = null;
} catch (OOfflineNodeException e) {
connectionManager.release(network);
// Remove the current url because the node is offline
synchronized (serverURLs) {
serverURLs.remove(serverUrl);
}
for (OStorageRemoteSession activeSession : sessions) {
// Not thread Safe ...
activeSession.removeServerSession(serverUrl);
}
serverUrl = null;
} catch (IOException e) {
connectionManager.release(network);
retry = handleIOException(retry, network, e);
serverUrl = null;
} catch (OIOException e) {
connectionManager.release(network);
retry = handleIOException(retry, network, e);
serverUrl = null;
} catch (OException e) {
connectionManager.release(network);
throw e;
} catch (Exception e) {
connectionManager.release(network);
throw OException.wrapException(new OStorageException(errorMessage), e);
}
} while (true);
}
use of com.orientechnologies.common.concur.lock.OModificationOperationProhibitedException in project orientdb by orientechnologies.
the class OServerAdmin method dropDatabase.
/**
* Drops a database from a remote server instance.
*
* @param iDatabaseName The database name
* @param storageType Storage type between "plocal" or "memory".
* @return The instance itself. Useful to execute method in chain
* @throws IOException
*/
public synchronized OServerAdmin dropDatabase(final String iDatabaseName, final String storageType) throws IOException {
boolean retry = true;
while (retry) {
retry = networkAdminOperation(new OStorageRemoteOperation<Boolean>() {
@Override
public Boolean execute(final OChannelBinaryAsynchClient network, OStorageRemoteSession session) throws IOException {
try {
try {
storage.beginRequest(network, OChannelBinaryProtocol.REQUEST_DB_DROP, session);
network.writeString(iDatabaseName);
network.writeString(storageType);
} finally {
storage.endRequest(network);
}
storage.getResponse(network, session);
return false;
} catch (OModificationOperationProhibitedException oope) {
return handleDBFreeze();
}
}
}, "Cannot delete the remote storage: " + storage.getName());
}
final Set<OStorage> underlyingStorages = new HashSet<OStorage>();
for (OStorage s : Orient.instance().getStorages()) {
if (s.getType().equals(storage.getType()) && s.getName().equals(storage.getName())) {
underlyingStorages.add(s.getUnderlying());
}
}
for (OStorage s : underlyingStorages) {
s.close(true, true);
}
ODatabaseRecordThreadLocal.INSTANCE.remove();
return this;
}
Aggregations