final String databaseName = iRequest.getDatabaseName();
if (iNodes.isEmpty()) {
ODistributedServerLog.error(this, getLocalNodeName(), 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);
// TODO: REALLY STILL MATTERS THE NUMBER OF THE QUEUES?
final IQueue<ODistributedRequest>[] reqQueues = getRequestQueues(databaseName, iNodes, iRequest.getTask());
iRequest.setSenderNodeName(getLocalNodeName());
int availableNodes;
if (iRequest.getTask().isRequireNodeOnline()) {
// CHECK THE ONLINE NODES
availableNodes = 0;
int i = 0;
for (String node : iNodes) {
if (reqQueues[i] != null && manager.isNodeAvailable(node, databaseName))
availableNodes++;
else {
if (ODistributedServerLog.isDebugEnabled())
ODistributedServerLog.debug(this, getLocalNodeName(), node, DIRECTION.OUT,
"skip expected response from node '%s' for request %s because it's not online (queue=%s)", node, iRequest,
reqQueues[i] != null);
}
++i;
}
} else {
// EXPECT ANSWER FROM ALL NODES WITH A QUEUE
availableNodes = 0;
for (IQueue<ODistributedRequest> q : reqQueues)
if (q != null)
availableNodes++;
}
final int quorum = calculateQuorum(iRequest, iClusterNames, cfg, availableNodes, iExecutionMode);
final int queueSize = iNodes.size();
int expectedSynchronousResponses = availableNodes;
final boolean groupByResponse;
if (iRequest.getTask().getResultStrategy() == OAbstractRemoteTask.RESULT_STRATEGY.UNION) {
expectedSynchronousResponses = availableNodes;
groupByResponse = false;
} else {
groupByResponse = true;
}
final boolean waitLocalNode = waitForLocalNode(cfg, iClusterNames, iNodes);
// CREATE THE RESPONSE MANAGER
final ODistributedResponseManager currentResponseMgr = new ODistributedResponseManager(manager, iRequest, iNodes,
expectedSynchronousResponses, quorum, waitLocalNode,
iRequest.getTask().getSynchronousTimeout(expectedSynchronousResponses), iRequest.getTask().getTotalTimeout(queueSize),
groupByResponse);
final long timeout = OGlobalConfiguration.DISTRIBUTED_QUEUE_TIMEOUT.getValueAsLong();
// try {
// requestLock.lock();
try {
// LOCK = ASSURE MESSAGES IN THE QUEUE ARE INSERTED SEQUENTIALLY AT CLUSTER LEVEL
// BROADCAST THE REQUEST TO ALL THE NODE QUEUES
// TODO: CAN I MOVE THIS OUTSIDE?
iRequest.setId(msgService.getMessageIdCounter().getAndIncrement());
if (ODistributedServerLog.isDebugEnabled())
ODistributedServerLog.debug(this, getLocalNodeName(), iNodes.toString(), DIRECTION.OUT, "sending request %s", iRequest);
// TODO: CAN I MOVE THIS OUTSIDE?
msgService.registerRequest(iRequest.getId(), currentResponseMgr);
for (IQueue<ODistributedRequest> queue : reqQueues) {
if (queue != null)
queue.offer(iRequest, timeout, TimeUnit.MILLISECONDS);
}
// } finally {
// requestLock.unlock();
// }
if (ODistributedServerLog.isDebugEnabled())
ODistributedServerLog.debug(this, getLocalNodeName(), iNodes.toString(), DIRECTION.OUT, "sent request %s", iRequest);
Orient
.instance()
.getProfiler()
.updateCounter("distributed.db." + databaseName + ".msgSent", "Number of replication messages sent from current node",
+1, "distributed.db.*.msgSent");
return waitForResponse(iRequest, currentResponseMgr);
} catch (Throwable e) {
throw new ODistributedException("Error on executing distributed request (" + iRequest + ") against database '" + databaseName
+ (iClusterNames != null ? "." + iClusterNames : "") + "' to nodes " + iNodes, e);
}
}