use of com.linkedin.pinot.transport.common.KeyedFuture in project pinot by linkedin.
the class ScatterGatherImpl method sendRequest.
/**
*
* Helper Function to send scatter-request. This method should be called after the servers are selected
*
* @param ctxt Scatter-Gather Request context with selected servers for each request.
* @param scatterGatherStats scatter-gather statistics.
* @param isOfflineTable whether the scatter-gather target is an OFFLINE table.
* @param brokerMetrics broker metrics to track execution statistics.
* @return a composite future representing the gather process.
* @throws InterruptedException
*/
protected CompositeFuture<ServerInstance, ByteBuf> sendRequest(ScatterGatherRequestContext ctxt, ScatterGatherStats scatterGatherStats, Boolean isOfflineTable, BrokerMetrics brokerMetrics) throws InterruptedException {
TimerContext t = MetricsHelper.startTimer();
// Servers are expected to be selected at this stage
Map<ServerInstance, SegmentIdSet> mp = ctxt.getSelectedServers();
CountDownLatch requestDispatchLatch = new CountDownLatch(mp.size());
// async checkout of connections and then dispatch of request
List<SingleRequestHandler> handlers = new ArrayList<SingleRequestHandler>(mp.size());
for (Entry<ServerInstance, SegmentIdSet> e : mp.entrySet()) {
ServerInstance server = e.getKey();
String serverName = server.toString();
if (isOfflineTable != null) {
if (isOfflineTable) {
serverName += ScatterGatherStats.OFFLINE_TABLE_SUFFIX;
} else {
serverName += ScatterGatherStats.REALTIME_TABLE_SUFFIX;
}
}
scatterGatherStats.initServer(serverName);
SingleRequestHandler handler = new SingleRequestHandler(_connPool, server, ctxt.getRequest(), e.getValue(), ctxt.getTimeRemaining(), requestDispatchLatch, brokerMetrics);
// Submit to thread-pool for checking-out and sending request
_executorService.submit(handler);
handlers.add(handler);
}
// Create the composite future for returning
CompositeFuture<ServerInstance, ByteBuf> response = new CompositeFuture<ServerInstance, ByteBuf>("scatterRequest", GatherModeOnError.SHORTCIRCUIT_AND);
// Wait for requests to be sent
long timeRemaining = ctxt.getTimeRemaining();
boolean sentSuccessfully = requestDispatchLatch.await(timeRemaining, TimeUnit.MILLISECONDS);
if (sentSuccessfully) {
List<KeyedFuture<ServerInstance, ByteBuf>> responseFutures = new ArrayList<KeyedFuture<ServerInstance, ByteBuf>>();
for (SingleRequestHandler h : handlers) {
responseFutures.add(h.getResponseFuture());
String serverName = h.getServer().toString();
if (isOfflineTable != null) {
if (isOfflineTable) {
serverName += ScatterGatherStats.OFFLINE_TABLE_SUFFIX;
} else {
serverName += ScatterGatherStats.REALTIME_TABLE_SUFFIX;
}
}
scatterGatherStats.setSendStartTimeMillis(serverName, h.getConnStartTimeMillis());
scatterGatherStats.setConnStartTimeMillis(serverName, h.getStartDelayMillis());
scatterGatherStats.setSendCompletionTimeMillis(serverName, h.getSendCompletionTimeMillis());
}
response.start(responseFutures);
} else {
LOGGER.error("Request (" + ctxt.getRequest().getRequestId() + ") not sent completely within time (" + timeRemaining + " ms) !! Cancelling !!. NumSentFailed:" + requestDispatchLatch.getCount());
response.start(null);
// and so we cancel all of them here
for (SingleRequestHandler h : handlers) {
LOGGER.info("Request to {} was sent successfully:{}, cancelling.", h.getServer(), h.isSent());
h.cancel();
}
}
t.stop();
_latency.update(t.getLatencyMs());
return response;
}
Aggregations