private long performAction(final List<IndexShard> ownedShards, final IndexShardAction action) {
        final AtomicLong shardCount = new AtomicLong();
        if (!ownedShards.isEmpty()) {
            taskContextFactory.context(
                    "Index Shard Manager",
                    TerminateHandlerFactory.NOOP_FACTORY,
                    parentTaskContext -> {
                        parentTaskContext.info(() -> action.getActivity() + " index shards");

                        // Create an atomic integer to count the number of index shard writers yet to complete the
                        // specified action.
                        final AtomicInteger remaining = new AtomicInteger(ownedShards.size());

                        // Create a scheduled executor for us to continually log index shard writer action progress.
                        try (final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor()) {
                            // Start logging action progress.
                            executor.scheduleAtFixedRate(
                                    () -> LOGGER.info(() ->
                                            "Waiting for " + remaining.get() + " index shards to " + action.getName()),
                                    10,
                                    10,
                                    TimeUnit.SECONDS);

                            // Perform action on all of the index shard writers in parallel.
                            ownedShards.parallelStream().forEach(shard -> {
                                try {
                                    // We use a child tak context here to create child messages in the UI but also to
                                    // ensure the task is performed in the context of the parent user.
                                    taskContextFactory.childContext(parentTaskContext,
                                            "Index Shard Manager",
                                            TerminateHandlerFactory.NOOP_FACTORY,
                                            taskContext -> {
                                                taskContext.info(() -> action.getActivity() +
                                                                       " index shard: " +
                                                                       shard.getId());
                                                switch (action) {
                                                    case FLUSH:
                                                        shardCount.incrementAndGet();
                                                        flush(shard);
                                                        break;
                                                    case DELETE:
                                                        shardCount.incrementAndGet();
                                                        delete(shard);
                                                        break;
                                                }
                                            }).run();
                                } catch (final RuntimeException e) {
                                    LOGGER.error(e::getMessage, e);
                                }

                                remaining.getAndDecrement();
                            });

                            // Shut down the progress logging executor.
                            executor.shutdown();
                        }

                        LOGGER.info(() -> "Finished " +
                                          action.getActivity().toLowerCase(Locale.ROOT) +
                                          " index shards");
                    }).run();
        }

        return shardCount.get();
    }
Delete anything that has been marked to delete
stroom-index/stroom-index-impl/src/main/java/stroom/index/impl/IndexShardManager.java