private Action <EventStoreCatchUpSubscription, SubscriptionDropReason, Exception> SubscriptionDropped(Projection projection)
        => (subscription, reason, ex) =>
        {
            // TODO: Reevaluate stopping subscriptions when issues with reconnect get fixed.
            // https://github.com/EventStore/EventStore/issues/1127
            // https://groups.google.com/d/msg/event-store/AdKzv8TxabM/VR7UDIRxCgAJ

            subscription.Stop();

            switch (reason)
            {
            case SubscriptionDropReason.UserInitiated:
                Log.Debug("{projection} projection stopped gracefully.", projection);
                break;

            case SubscriptionDropReason.SubscribingError:
            case SubscriptionDropReason.ServerError:
            case SubscriptionDropReason.ConnectionClosed:
            case SubscriptionDropReason.CatchUpError:
            case SubscriptionDropReason.ProcessingQueueOverflow:
            case SubscriptionDropReason.EventHandlerException:
                Log.ErrorException(
                    "{projection} projection stopped because of a transient error ({reason}). " +
                    "Attempting to restart...",
                    ex, projection, reason);
                Task.Run(() => StartProjection(projection));
                break;

            default:
                Log.FatalException(
                    "{projection} projection stopped because of an internal error ({reason}). " +
                    "Please check your logs for details.",
                    ex, projection, reason);
                break;
            }
        };
 private static Action <EventStoreCatchUpSubscription> LiveProcessingStarted(Projection projection)
 => _ => Log.Debug("{projection} projection has caught up, now processing live!", projection);