3080 moved shutDownTaskExecutor to new ThreadUtils class

This commit is contained in:
William Schaefer 2017-10-25 14:31:45 -04:00
parent 2fb71f2ff0
commit 02cdf53d74
4 changed files with 77 additions and 46 deletions

View File

@ -85,12 +85,12 @@ import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.core.UserPreferencesException; import org.sleuthkit.autopsy.core.UserPreferencesException;
import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl; import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
import org.sleuthkit.autopsy.coreutils.DriveUtils; import org.sleuthkit.autopsy.coreutils.DriveUtils;
import org.sleuthkit.autopsy.coreutils.ExecUtil;
import org.sleuthkit.autopsy.coreutils.FileUtil; import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.NetworkUtils; import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.ThreadUtils;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEvent;
@ -129,7 +129,6 @@ public class Case {
private static final String REPORTS_FOLDER = "Reports"; //NON-NLS private static final String REPORTS_FOLDER = "Reports"; //NON-NLS
private static final String TEMP_FOLDER = "Temp"; //NON-NLS private static final String TEMP_FOLDER = "Temp"; //NON-NLS
private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS
private static final long EXECUTOR_AWAIT_TIMEOUT_SECS = 5;
private static final String CASE_ACTION_THREAD_NAME = "%s-case-action"; private static final String CASE_ACTION_THREAD_NAME = "%s-case-action";
private static final String CASE_RESOURCES_THREAD_NAME = "%s-manage-case-resources"; private static final String CASE_RESOURCES_THREAD_NAME = "%s-manage-case-resources";
private static final Logger logger = Logger.getLogger(Case.class.getName()); private static final Logger logger = Logger.getLogger(Case.class.getName());
@ -1646,7 +1645,7 @@ public class Case {
} else { } else {
future.cancel(true); future.cancel(true);
} }
ExecUtil.shutDownTaskExecutor(caseLockingExecutor); ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
} catch (CancellationException discarded) { } catch (CancellationException discarded) {
/* /*
* The create/open task has been cancelled. Wait for it to finish, * The create/open task has been cancelled. Wait for it to finish,
@ -1655,7 +1654,7 @@ public class Case {
* will have been closed and the case directory lock released will * will have been closed and the case directory lock released will
* have been released. * have been released.
*/ */
ExecUtil.shutDownTaskExecutor(caseLockingExecutor); ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelledByUser()); throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelledByUser());
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
/* /*
@ -1665,7 +1664,7 @@ public class Case {
* case will have been closed and the case directory lock released * case will have been closed and the case directory lock released
* will have been released. * will have been released.
*/ */
ExecUtil.shutDownTaskExecutor(caseLockingExecutor); ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex); throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
} finally { } finally {
progressIndicator.finish(); progressIndicator.finish();
@ -1993,7 +1992,7 @@ public class Case {
* would be possible to start the next task before the current * would be possible to start the next task before the current
* task responded to a cancellation request. * task responded to a cancellation request.
*/ */
ExecUtil.shutDownTaskExecutor(executor); ThreadUtils.shutDownTaskExecutor(executor);
progressIndicator.finish(); progressIndicator.finish();
} }
@ -2064,7 +2063,7 @@ public class Case {
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex); throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
} finally { } finally {
ExecUtil.shutDownTaskExecutor(caseLockingExecutor); ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
progressIndicator.finish(); progressIndicator.finish();
} }
} }
@ -2175,7 +2174,7 @@ public class Case {
Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage()))); Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
} }
} finally { } finally {
ExecUtil.shutDownTaskExecutor(executor); ThreadUtils.shutDownTaskExecutor(executor);
progressIndicator.finish(); progressIndicator.finish();
} }
} }

View File

@ -42,7 +42,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization; import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
import org.sleuthkit.autopsy.coreutils.ExecUtil; import org.sleuthkit.autopsy.coreutils.ThreadUtils;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.BlackboardArtifactTag;
@ -68,7 +68,7 @@ final class CaseEventListener implements PropertyChangeListener {
} }
void shutdown() { void shutdown() {
ExecUtil.shutDownTaskExecutor(jobProcessingExecutor); ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor);
} }
@Override @Override

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2016 Basis Technology Corp. * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -26,7 +26,6 @@ import java.io.InputStreamReader;
import java.io.Writer; import java.io.Writer;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferences;
@ -213,40 +212,6 @@ public final class ExecUtil {
} }
} }
/**
* Shuts down a task executor service, waiting until all tasks are
* terminated. The current policy is to wait for the tasks to finish so that
* the case for which the executor is running can be left in a consistent
* state.
*
* @param executor The executor.
*/
public static void shutDownTaskExecutor(ExecutorService executor) {
executor.shutdown();
boolean taskCompleted = false;
while (!taskCompleted) {
try {
taskCompleted = executor.awaitTermination(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNITS);
} catch (InterruptedException ignored) {
/*
* The current policy is to wait for the task to finish so that
* the case can be left in a consistent state.
*
* For a specific example of the motivation for this policy,
* note that a application service (Solr search service)
* experienced an error condition when opening case resources
* that left the service blocked uninterruptibly on a socket
* read. This eventually led to a mysterious "freeze" as the
* user-cancelled service task continued to run holdiong a lock
* that a UI thread soon tried to acquire. Thus it has been
* deemed better to make the "freeze" happen in a more
* informative way, i.e., with the progress indicator for the
* unfinished task on the screen, if a similar error condition
* arises again.
*/
}
}
}
/** /**
* EVERYTHING FOLLOWING THIS LINE IS DEPRECATED AND SLATED FOR REMOVAL * EVERYTHING FOLLOWING THIS LINE IS DEPRECATED AND SLATED FOR REMOVAL
*/ */

View File

@ -0,0 +1,67 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.coreutils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
/*
* General purpose actions which can be performed on Threads.
*/
final public class ThreadUtils {
private static final long DEFAULT_TIMEOUT = 5;
private static final TimeUnit DEFAULT_TIMEOUT_UNITS = TimeUnit.SECONDS;
/**
* Shuts down a task executor service, waiting until all tasks are
* terminated.
*
* @param executor The executor.
*/
public static void shutDownTaskExecutor(ExecutorService executor) {
executor.shutdown();
boolean taskCompleted = false;
while (!taskCompleted) {
try {
taskCompleted = executor.awaitTermination(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNITS);
} catch (InterruptedException ignored) {
/*
* The current policy is to wait for the task to finish so that
* the case can be left in a consistent state.
*
* For a specific example of the motivation for this policy,
* note that a application service (Solr search service)
* experienced an error condition when opening case resources
* that left the service blocked uninterruptibly on a socket
* read. This eventually led to a mysterious "freeze" as the
* user-cancelled service task continued to run holdiong a lock
* that a UI thread soon tried to acquire. Thus it has been
* deemed better to make the "freeze" happen in a more
* informative way, i.e., with the progress indicator for the
* unfinished task on the screen, if a similar error condition
* arises again.
*/
}
}
}
private ThreadUtils() {
}
}