}
@Override
public void handleMessage(ByteBuffer buf, Connection c) {
long nowNanos = System.nanoTime();
ClientResponseImpl response = new ClientResponseImpl();
try {
response.initFromBuffer(buf);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// track the timestamp of the most recent read on this connection
m_lastResponseTimeNanos = nowNanos;
final long handle = response.getClientHandle();
// handle ping response and get out
if (handle == PING_HANDLE) {
m_outstandingPing = false;
return;
} else if (handle == ASYNC_TOPO_HANDLE) {
/*
* Really didn't want to add this block because it is not DRY
* for the exception handling, but trying to set + reset the async topo callback
* turned out to be pretty challenging
*/
ProcedureCallback cb = new TopoUpdateCallback();
try {
cb.clientCallback(response);
} catch (Exception e) {
uncaughtException(cb, response, e);
}
return;
}
//Race with expiration thread to be the first to remove the callback
//from the map and process it
final CallbackBookeeping stuff = m_callbacks.remove(response.getClientHandle());
// presumably (hopefully) this is a response for a timed-out message
if (stuff == null) {
// also ignore internal (topology and procedure) calls
if (handle >= 0) {
// notify any listeners of the late response
for (ClientStatusListenerExt listener : m_listeners) {
listener.lateProcedureResponse(
response,
m_connection.getHostnameOrIP(),
m_connection.getRemotePort());
}
}
}
// handle a proper callback
else {
final long callTimeNanos = stuff.timestampNanos;
final long deltaNanos = Math.max(1, nowNanos - callTimeNanos);
final ProcedureCallback cb = stuff.callback;
assert(cb != null);
final byte status = response.getStatus();
boolean abort = false;
boolean error = false;
if (status == ClientResponse.USER_ABORT || status == ClientResponse.GRACEFUL_FAILURE) {
abort = true;
} else if (status != ClientResponse.SUCCESS) {
error = true;
}
int clusterRoundTrip = response.getClusterRoundtrip();
m_rateLimiter.transactionResponseReceived(nowNanos, clusterRoundTrip, stuff.ignoreBackpressure);
updateStats(stuff.name, deltaNanos, clusterRoundTrip, abort, error, false);
response.setClientRoundtrip(deltaNanos);
assert(response.getHash() == null); // make sure it didn't sneak into wire protocol
try {
cb.clientCallback(response);
} catch (Exception e) {
uncaughtException(cb, response, e);
}