public IDisposable Subscribe(long?lastProcessedCheckpoint, Func <IReadOnlyList <Transaction>, SubscriptionInfo, Task> handler, SubscriptionOptions options = null) { if (options == null) { options = new SubscriptionOptions(); } if (handler == null) { throw new ArgumentNullException(nameof(handler)); } return(createSubscription(lastProcessedCheckpoint, new Subscriber { HandleTransactions = async(transactions, info) => await HandleTransactions(transactions, handler, info).ConfigureAwait(false), NoSuchCheckpoint = async info => await HandleUnknownCheckpoint(info, handler, options).ConfigureAwait(false) }, options.Id)); }
private async Task HandleUnknownCheckpoint(SubscriptionInfo info, Func <IReadOnlyList <Transaction>, SubscriptionInfo, Task> handler, SubscriptionOptions options) { if (options.RestartWhenAhead) { await ExecuteWithPolicy( info, async() => { await options.BeforeRestarting().ConfigureAwait(false); Subscribe(null, handler, options); }, abort : exception => { LogProvider.GetLogger(typeof(Dispatcher)).FatalException( "Failed to restart the projector.", exception); }, ignore : () => Subscribe(null, handler, options)) .ConfigureAwait(false); // Dispose the subscription only after a new subscription is created // to support CreateSubscription delegates which wait // until the subscription detects being ahead // and until all the existing transactions are processed by the new subscription info.Subscription?.Dispose(); } }