public static boolean boundedShutdown(List<Runnable> shutdownTasks, String message, long timeoutMs) {
    ExecutorService shutdownExecutorService = Executors.newCachedThreadPool(
        new ThreadFactoryBuilder().setNameFormat(message + "-%d").setDaemon(true).build());
    shutdownTasks.forEach(shutdownExecutorService::submit);
    shutdownExecutorService.shutdown();
    try {
      shutdownExecutorService.awaitTermination(timeoutMs, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      LOG.error("Shutdown was interrupted for " + message, e);
    }

    if (shutdownExecutorService.isTerminated()) {
      LOG.info("Shutdown complete for {}", message);
      return true;
    } else {
      LOG.error("Shutdown function for {} remains unfinished after timeout ({} ms) or interruption", message, timeoutMs);
      ThreadUtil.logThreadDump(message);
      shutdownExecutorService.shutdownNow();
      return false;
    }
  }
A helper to facilitate shutting down a set of resources in parallel to enforce a bounded shutdown time.
The helper function instantiates an {@link ExecutorService} to execute a list of shutdown tasks, and will
await the termination for given timeout. If shutdown remains unfinished in the end, the whole thread dump
will be printed to help debugging.

The shutdown is performed with best-effort. Depending on the implementation of the shutdown function, resource
leak might be possible.

@param shutdownTasks the list of shutdown tasks that need to be executed in parallel
@param message message that will show in the thread name and the thread dump
@param timeoutMs timeout in ms
@return true if all tasks terminate in the end
samza-core/src/main/java/org/apache/samza/util/ShutdownUtil.java