private static void runDbStateChange(Function<String, Runnable> runnableFunction) { Logs.extreme().info("DB STATE CHANGE: " + runnableFunction); try { Logs.extreme().info("Attempting to acquire db state lock: " + runnableFunction); if (canHas.writeLock().tryLock(5, TimeUnit.MINUTES)) { try { Logs.extreme().info("Acquired db state lock: " + runnableFunction); Map<Runnable, Future<Runnable>> runnables = Maps.newHashMap(); for (final String ctx : listDatabases()) { Runnable run = runnableFunction.apply(ctx); runnables.put(run, ExecuteRunnable.INSTANCE.apply(run)); } Map<Runnable, Future<Runnable>> succeeded = Futures.waitAll(runnables); MapDifference<Runnable, Future<Runnable>> failed = Maps.difference(runnables, succeeded); StringBuilder builder = new StringBuilder(); builder.append(Joiner.on("\nSUCCESS: ").join(succeeded.keySet())); builder.append(Joiner.on("\nFAILED: ").join(failed.entriesOnlyOnLeft().keySet())); Logs.extreme().debug(builder.toString()); if (!failed.entriesOnlyOnLeft().isEmpty()) { throw Exceptions.toUndeclared(builder.toString()); } } finally { canHas.writeLock().unlock(); } } else { throw new LockTimeoutException( "DB STATE CHANGE ABORTED (failed to get lock): " + runnableFunction); } } catch (RuntimeException ex) { LOG.error(ex); Logs.extreme().error(ex, ex); throw ex; } catch (InterruptedException ex) { Exceptions.maybeInterrupted(ex); throw Exceptions.toUndeclared(ex); } }