use of org.apache.drill.exec.ops.QueryCancelledException in project drill by apache.
the class FragmentExecutor method run.
@Override
public void run() {
final Thread myThread = Thread.currentThread();
if (!myThreadRef.compareAndSet(null, myThread)) {
return;
}
final String originalThreadName = myThread.getName();
final FragmentHandle fragmentHandle = fragmentContext.getHandle();
final ClusterCoordinator clusterCoordinator = fragmentContext.getClusterCoordinator();
final DrillbitStatusListener drillbitStatusListener = new FragmentDrillbitStatusListener();
final String newThreadName = QueryIdHelper.getExecutorThreadName(fragmentHandle);
try {
myThread.setName(newThreadName);
// if we didn't get the root operator when the executor was created, create it now.
final FragmentRoot rootOperator = this.rootOperator != null ? this.rootOperator : fragmentContext.getPlanReader().readFragmentRoot(fragment.getFragmentJson());
root = ImplCreator.getExec(fragmentContext, rootOperator);
if (root == null) {
return;
}
clusterCoordinator.addDrillbitStatusListener(drillbitStatusListener);
updateState(FragmentState.RUNNING);
eventProcessor.start();
injector.injectPause(fragmentContext.getExecutionControls(), "fragment-running", logger);
final DrillbitEndpoint endpoint = fragmentContext.getEndpoint();
logger.debug("Starting fragment {}:{} on {}:{}", fragmentHandle.getMajorFragmentId(), fragmentHandle.getMinorFragmentId(), endpoint.getAddress(), endpoint.getUserPort());
final UserGroupInformation queryUserUgi = fragmentContext.isImpersonationEnabled() ? ImpersonationUtil.createProxyUgi(fragmentContext.getQueryUserName()) : ImpersonationUtil.getProcessUserUGI();
queryUserUgi.doAs((PrivilegedExceptionAction<Void>) () -> {
injector.injectChecked(fragmentContext.getExecutionControls(), "fragment-execution", IOException.class);
while (shouldContinue()) {
for (FragmentHandle fragmentHandle1; (fragmentHandle1 = receiverFinishedQueue.poll()) != null; ) {
// See if we have any finished requests. If so execute them.
root.receivingFragmentFinished(fragmentHandle1);
}
if (!root.next()) {
// Fragment has processed all of its data
break;
}
}
return null;
});
} catch (QueryCancelledException e) {
// Ignore: indicates query cancelled by this executor
} catch (OutOfMemoryError | OutOfMemoryException e) {
if (FailureUtils.isDirectMemoryOOM(e)) {
root.dumpBatches(e);
fail(UserException.memoryError(e).build(logger));
} else {
// we have a heap out of memory error. The JVM is unstable, exit.
FailureUtils.unrecoverableFailure(e, "Unable to handle out of memory condition in FragmentExecutor.", EXIT_CODE_HEAP_OOM);
}
} catch (InterruptedException e) {
// Swallow interrupted exceptions since we intentionally interrupt the root when cancelling a query
logger.trace("Interrupted root: {}", root, e);
} catch (Throwable t) {
if (root != null) {
root.dumpBatches(t);
}
fail(t);
} finally {
// Don't process any more termination requests, we are done.
eventProcessor.terminate();
// Clear the interrupt flag if it is set.
Thread.interrupted();
// here we could be in FAILED, RUNNING, or CANCELLATION_REQUESTED
// FAILED state will be because of any Exception in execution loop root.next()
// CANCELLATION_REQUESTED because of a CANCEL request received by Foreman.
// ELSE will be in FINISHED state.
cleanup(FragmentState.FINISHED);
clusterCoordinator.removeDrillbitStatusListener(drillbitStatusListener);
myThread.setName(originalThreadName);
}
}
use of org.apache.drill.exec.ops.QueryCancelledException in project drill by apache.
the class MergingRecordBatch method getNext.
private RawFragmentBatch getNext(final int providerIndex) {
stats.startWait();
final RawFragmentBatchProvider provider = fragProviders[providerIndex];
try {
injector.injectInterruptiblePause(context.getExecutionControls(), "waiting-for-data", logger);
RawFragmentBatch b;
try {
b = provider.getNext();
} catch (IOException e) {
// TODO: Better to handle inside getNext() to provide a better error message
throw UserException.dataReadError(e).addContext("Failed to read incoming merge batch").build(logger);
}
if (b != null) {
stats.addLongStat(Metric.BYTES_RECEIVED, b.getByteCount());
stats.batchReceived(0, b.getHeader().getDef().getRecordCount(), false);
inputCounts[providerIndex] += b.getHeader().getDef().getRecordCount();
}
return b;
} catch (final InterruptedException e) {
// Preserve evidence that the interruption occurred so that code higher up on the call stack can learn of the
// interruption and respond to it if it wants to.
Thread.currentThread().interrupt();
throw new QueryCancelledException();
} finally {
stats.stopWait();
}
}
use of org.apache.drill.exec.ops.QueryCancelledException in project drill by apache.
the class PartitionerDecorator method executeMethodLogic.
/**
* Helper to execute the different methods wrapped into same logic
* @param iface
* @throws ExecutionException
*/
@VisibleForTesting
void executeMethodLogic(final GeneralExecuteIface iface) throws ExecutionException {
// interrupts waiting threads. This makes sure that we are actually interrupting the blocked partitioner threads.
try (CountDownLatchInjection testCountDownLatch = injector.getLatch(context.getExecutionControls(), "partitioner-sender-latch")) {
testCountDownLatch.initialize(1);
final AtomicInteger count = new AtomicInteger();
List<PartitionerTask> partitionerTasks = new ArrayList<>(partitioners.size());
ExecutionException executionException = null;
// start waiting on main stats to adjust by sum(max(processing)) at the end
startWait();
try {
partitioners.forEach(partitioner -> createAndExecute(iface, testCountDownLatch, count, partitionerTasks, partitioner));
// Wait for main fragment interruption.
injector.injectInterruptiblePause(context.getExecutionControls(), "wait-for-fragment-interrupt", logger);
testCountDownLatch.countDown();
} catch (InterruptedException e) {
logger.warn("fragment thread interrupted", e);
throw new QueryCancelledException();
} catch (RejectedExecutionException e) {
logger.warn("Failed to execute partitioner tasks. Execution service down?", e);
executionException = new ExecutionException(e);
} finally {
await(count, partitionerTasks);
stopWait();
processPartitionerTasks(partitionerTasks, executionException);
}
}
}
use of org.apache.drill.exec.ops.QueryCancelledException in project drill by apache.
the class ProducerConsumerBatch method innerNext.
@Override
public IterOutcome innerNext() {
if (!running) {
producer.start();
running = true;
}
RecordBatchDataWrapper wrapper;
try {
stats.startWait();
wrapper = queue.take();
logger.debug("Got batch from queue");
} catch (final InterruptedException e) {
throw new QueryCancelledException();
} finally {
stats.stopWait();
}
if (wrapper.finished) {
return IterOutcome.NONE;
}
recordCount = wrapper.batch.getRecordCount();
final boolean newSchema = load(wrapper.batch);
return newSchema ? IterOutcome.OK_NEW_SCHEMA : IterOutcome.OK;
}
use of org.apache.drill.exec.ops.QueryCancelledException in project drill by apache.
the class ProducerConsumerBatch method close.
@Override
public void close() {
producer.interrupt();
try {
producer.join();
} catch (final InterruptedException e) {
logger.warn("Interrupted while waiting for producer thread");
// TODO InterruptedException
}
try {
cleanUpLatch.await();
} catch (final InterruptedException e) {
logger.warn("Interrupted while waiting for producer to clean up first. I will try to clean up now...", e);
// TODO we should retry to wait for the latch
throw new QueryCancelledException();
} finally {
super.close();
clearQueue();
}
}
Aggregations