* API method for querying a tablespace when you already know the partition Id. Can be used for multi-querying.
*/
public QueryStatus query(String tablespaceName, String sql, int partitionId) throws JSONSerDeException {
Long version = context.getCurrentVersionsMap().get(tablespaceName);
if(version == null) {
return new ErrorQueryStatus("Unknown tablespace! (" + tablespaceName + ")");
}
Tablespace tablespace = context.getTablespaceVersionsMap().get(
new TablespaceVersion(tablespaceName, version));
if(tablespace == null) {
return new ErrorQueryStatus("Unknown tablespace! (" + tablespaceName + ")");
}
ReplicationMap replicationMap = tablespace.getReplicationMap();
ReplicationEntry repEntry = null;
for(ReplicationEntry rEntry : replicationMap.getReplicationEntries()) {
if(rEntry.getShard() == partitionId) {
repEntry = rEntry;
}
}
if(repEntry == null) {
return new ErrorQueryStatus("Incomplete Tablespace information for tablespace (" + tablespaceName
+ ") Maybe let the Splout warmup a little bit and try later?");
}
if(repEntry.getNodes().size() == 0) { // No one alive for serving the query!
return new ErrorQueryStatus("No alive DNodes for " + tablespace);
}
String electedNode;
int tried = 0;
for(;;) { // Fail-over loop
electedNode = null;
Integer lastNode = partitionRoundRobin.get().get(partitionId);
if(lastNode == null) {
lastNode = -1;
}
lastNode++;
tried++;
int index = lastNode % repEntry.getNodes().size();
electedNode = repEntry.getNodes().get(index);
partitionRoundRobin.get().put(partitionId, index);
// Perform query
QueryStatus qStatus = new QueryStatus();
long start = System.currentTimeMillis();
DNodeService.Client client = null;
boolean renew = false;
try {
client = context.getDNodeClientFromPool(electedNode);
String r;
try {
r = client.sqlQuery(tablespaceName, version, partitionId, sql);
} catch(TTransportException e) {
renew = true;
throw e;
}
qStatus.setResult(JSONSerDe.deSer(r, ArrayList.class));
long end = System.currentTimeMillis();
// Report the time of the query
qStatus.setMillis((end - start));
// ... and the shard hit.
qStatus.setShard(partitionId);
return qStatus;
} catch(DNodeException e) {
log.error("Exception in Querier", e);
if(tried == repEntry.getNodes().size()) {
return new ErrorQueryStatus("DNode exception (" + e.getMsg() + ") from " + electedNode);
}
} catch(TException e) {
log.error("Exception in Querier", e);
if(tried == repEntry.getNodes().size()) {
return new ErrorQueryStatus("Error connecting to client " + electedNode);
}
} finally {
if(client != null) {
context.returnDNodeClientToPool(electedNode, client, renew);
}