Github user vrozov commented on a diff in the pull request:
https://github.com/apache/drill/pull/1023#discussion_r149234360
--- Diff:
exec/java-exec/src/main/java/org/apache/drill/exec/work/WorkManager.java ---
@@ -158,38 +165,49 @@ public DrillbitContext getContext() {
return dContext;
}
- private ExtendedLatch exitLatch = null; // used to wait to exit when
things are still running
-
/**
* Waits until it is safe to exit. Blocks until all currently running
fragments have completed.
- *
- * <p>This is intended to be used by {@link
org.apache.drill.exec.server.Drillbit#close()}.</p>
+ * This is intended to be used by {@link
org.apache.drill.exec.server.Drillbit#close()}.
*/
public void waitToExit() {
- synchronized(this) {
- if (queries.isEmpty() && runningFragments.isEmpty()) {
- return;
+ final long startTime = System.currentTimeMillis();
+ final long endTime = startTime + EXIT_TIMEOUT;
+
+ exitLock.lock();
+
+ try {
+ long currentTime;
+ while ((currentTime = System.currentTimeMillis()) < endTime) {
+ if (queries.isEmpty() && runningFragments.isEmpty()) {
+ break;
+ }
+
+ try {
+ if (!exitCondition.await(endTime - currentTime,
TimeUnit.MILLISECONDS)) {
+ break;
+ }
+ } catch (InterruptedException e) {
+ logger.error("Interrupted while waiting to exit");
+ }
}
- exitLatch = new ExtendedLatch();
- }
+ if (!(queries.isEmpty() && runningFragments.isEmpty())) {
+ logger.warn("Timed out after {} millis. Shutting down before all
fragments and foremen " +
+ "have completed.", EXIT_TIMEOUT);
+ }
- // Wait for at most 5 seconds or until the latch is released.
- exitLatch.awaitUninterruptibly(5000);
+ } finally {
+ exitLock.unlock();
+ }
}
/**
- * If it is safe to exit, and the exitLatch is in use, signals it so
that waitToExit() will
- * unblock.
+ * A thread calling the {@link #waitToExit()} method is notified when a
foreman is retired.
*/
private void indicateIfSafeToExit() {
- synchronized(this) {
- if (exitLatch != null) {
- if (queries.isEmpty() && runningFragments.isEmpty()) {
- exitLatch.countDown();
- }
- }
- }
+ exitLock.lock();
+ exitCondition.signal();
--- End diff --
I'd recommend adding try/finally and checking the condition before
signaling `exitCondition`. Consider renaming `exitCondition` to `isEmpty` or
`isQueriesAndFragmentsEmpty`.
---