class AsyncBatchPayloadPublisher implements BatchPayloadPublisher {

    @Override
    public void publishPayload(EncodedPayload payload, List<PublicKey> recipientKeys) {
        if (recipientKeys.size() == 0) {
            return;
        }

        final CancellableCountDownLatch latch = countDownLatchFactory.create(recipientKeys.size());

        recipientKeys.forEach(
                recipient ->
                        executor.execute(
                                () -> {
                                    try {
                                        final EncodedPayload outgoing = encoder.forRecipient(payload, recipient);
                                        publisher.publishPayload(outgoing, recipient);
                                        latch.countDown();
                                    } catch (RuntimeException e) {
                                        LOGGER.info("unable to publish payload in batch: {}", e.getMessage());
                                        latch.cancelWithException(e);
                                    }
                                }));

        try {
            latch.await();
        } catch (InterruptedException e) {
            throw new BatchPublishPayloadException(e);
        }
    }

    public  AsyncBatchPayloadPublisher(
            ExecutorFactory executorFactory,
            CancellableCountDownLatchFactory countDownLatchFactory,
            PayloadPublisher publisher,
            PayloadEncoder encoder);

}