コード例 #1
0
            private async Task DoPoll()
            {
                if (Interlocked.CompareExchange(ref _isPolling, 1, 0) == 0)
                {
                    try
                    {
                        var commits = _bucketId == null?
                                      _persistStreams.GetFrom(_checkpointToken) :
                                          _persistStreams.GetFrom(_bucketId, _checkpointToken);

                        await commits.ForEach(context =>
                        {
                            var commit = context.Item;
                            if (_stopRequested.IsCancellationRequested)
                            {
                                _subject.OnCompleted();
                                context.Break();
                            }
                            else
                            {
                                _subject.OnNext(commit);
                                _checkpointToken = commit.CheckpointToken;
                            }
                            return(Task.FromResult(false));
                        });
                    }
                    catch (Exception ex)
                    {
                        // These exceptions are expected to be transient
                        Logger.Error(ex.ToString());
                    }
                    Interlocked.Exchange(ref _isPolling, 0);
                }
            }
コード例 #2
0
ファイル: PollingClient.cs プロジェクト: zokiz/NEventStore
            private void DoPoll()
            {
                if (Interlocked.CompareExchange(ref _isPolling, 1, 0) == 0)
                {
                    try
                    {
                        var commits = _bucketId == null?
                                      _persistStreams.GetFrom(_checkpointToken) :
                                          _persistStreams.GetFrom(_bucketId, _checkpointToken);

                        foreach (var commit in commits)
                        {
                            if (_stopRequested.IsCancellationRequested)
                            {
                                _subject.OnCompleted();
                                return;
                            }
                            _subject.OnNext(commit);
                            _checkpointToken = commit.CheckpointToken;
                        }
                    }
                    catch (Exception ex)
                    {
                        // These exceptions are expected to be transient
                        Logger.Error(ex.ToString());
                    }
                    Interlocked.Exchange(ref _isPolling, 0);
                }
            }
コード例 #3
0
            public void Then_it_should_wait_for_the_polling_interval_to_retry()
            {
                A.CallTo(() => eventStore.GetFrom(A <string> .Ignored)).MustHaveHappened(Repeated.Exactly.Once);

                utcNow = utcNow.Add(1.Seconds());

                A.CallTo(() => eventStore.GetFrom(A <string> .Ignored)).MustHaveHappened(Repeated.Exactly.Once);
            }
コード例 #4
0
 public void ConfigurePollingFunction(string bucketId = null)
 {
     if (bucketId == null)
     {
         _pollingFunc = () => _persistStreams.GetFrom(_checkpointToken);
     }
     else
     {
         _pollingFunc = () => _persistStreams.GetFrom(bucketId, _checkpointToken);
     }
 }
コード例 #5
0
 public void should_not_affect_the_stream_from_the_other_partition()
 {
     Commit[] stream = _persistence1.GetFrom(StreamId, 0, int.MaxValue).ToArray();
     stream.ShouldNotBeNull();
     stream.Count().ShouldBe(1);
     stream.First().CommitStamp.ShouldBe(_attempt1.CommitStamp);
 }
コード例 #6
0
 /// <summary>
 ///     Gets all commits after from start checkpoint.
 /// </summary>
 /// <param name="persistStreams">The IPersistStreams instance.</param>
 public static IEnumerable <ICommit> GetFromStart(this IPersistStreams persistStreams)
 {
     if (persistStreams == null)
     {
         throw new ArgumentNullException(nameof(persistStreams));
     }
     return(persistStreams.GetFrom(0));
 }
コード例 #7
0
 public static IEnumerable <ICommit> GetFrom(this IPersistStreams persistStreams, DateTime start)
 {
     if (persistStreams == null)
     {
         throw new ArgumentNullException(nameof(persistStreams));
     }
     return(persistStreams.GetFrom(Bucket.Default, start));
 }
コード例 #8
0
 /// <summary>
 ///     Gets all commits after from start checkpoint.
 /// </summary>
 /// <param name="persistStreams">The IPersistStreams instance.</param>
 public static IEnumerable <ICommit> GetFromStart(this IPersistStreams persistStreams)
 {
     if (persistStreams == null)
     {
         throw new ArgumentException("persistStreams is null");
     }
     return(persistStreams.GetFrom(null));
 }
コード例 #9
0
        private IEnumerable <ICommit> GetCommitsFromPersistentStore(SendCommitAfterCurrentHeadCheckpointMessage msg)
        {
            IEnumerable <ICommit> commits = _persistStreams.GetFrom(msg.CurrentHeadCheckpoint.GetOrElse(() => 0)); //load all commits after checkpoint from db

            if (!msg.NumberOfCommitsToSend.HasValue)
            {
                return(commits);
            }

            return(commits.Take(msg.NumberOfCommitsToSend.Get()));
        }
コード例 #10
0
            public When_a_subscription_starts_after_zero_checkpoint_and_another_subscription_starts_after_null_checkpoint_while_the_first_subscription_is_loading_the_first_page_from_the_event_store()
            {
                Given(() =>
                {
                    eventStore = A.Fake <IPersistStreams>();
                    A.CallTo(() => eventStore.GetFrom(A <string> .Ignored)).ReturnsLazily(call =>
                    {
                        string checkpointString = call.GetArgument <string>(0);

                        long checkpoint = string.IsNullOrEmpty(checkpointString)
                            ? 0 :
                                          long.Parse(checkpointString, CultureInfo.InvariantCulture);

                        aSubscriptionStartedLoading.Set();

                        if (!secondSubscriptionCreated.Wait(TimeSpan.FromSeconds(10)))
                        {
                            throw new InvalidOperationException("The second subscription has not been created in 10 seconds.");
                        }

                        // Give the second subscription enough time to access the cache.
                        Thread.Sleep(TimeSpan.FromSeconds(1));

                        return(checkpoint > 0
                            ? new ICommit[0]
                            : new ICommit[] { new CommitBuilder().WithCheckpoint("1").Build() });
                    });

                    WithSubject(_ => new NEventStoreAdapter(eventStore, 100, pollingInterval, 100, () => utcNow));
                });

                When(() =>
                {
                    Subject.Subscribe(0, transactions => Task.FromResult(0));

                    if (!aSubscriptionStartedLoading.Wait(TimeSpan.FromSeconds(10)))
                    {
                        throw new InvalidOperationException("The first subscription has not started loading in 10 seconds.");
                    }

                    Subject.Subscribe(
                        null,
                        transactions =>
                    {
                        secondSubscriptionReceivedTheTransaction.Set();
                        return(Task.FromResult(0));
                    });

                    secondSubscriptionCreated.Set();
                });
            }
コード例 #11
0
            public When_disposing_subscription()
            {
                Given(() =>
                {
                    eventStore = A.Fake <IPersistStreams>();
                    A.CallTo(() => eventStore.GetFrom(A <string> .Ignored)).Returns(new ICommit[0]);

                    WithSubject(_ => new NEventStoreAdapter(eventStore, 11, pollingInterval, 100, () => utcNow));

                    subscription = Subject.Subscribe(1000, transactions => Task.FromResult(0));
                });

                When(() => subscription.Dispose(), deferedExecution: true);
            }
コード例 #12
0
            private void GetNextCommits(CancellationToken cancellationToken)
            {
                IEnumerable <ICommit> commits = _persistStreams.GetFrom(_checkpointToken);

                foreach (var commit in commits)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        _subject.OnCompleted();
                        return;
                    }
                    _subject.OnNext(commit);
                    _checkpointToken = commit.CheckpointToken;
                }
            }
コード例 #13
0
        public void Unwind()
        {
            var lastEvent = _unwindedEventCollection
                            .Find(Builders <UnwindedDomainEvent> .Filter.Empty)
                            .Sort(Builders <UnwindedDomainEvent> .Sort.Descending(e => e.CheckpointToken))
                            .Limit(1)
                            .SingleOrDefault();
            Int64 startToken = 0;

            if (lastEvent != null)
            {
                startToken = lastEvent.CheckpointToken;
            }

            _logger.InfoFormat("Unwind events starting from commit {0}", startToken);

            //Since we could have crashed during unwind of last commit, we want to reunwind again last commit
            Int64 checkpointToken = startToken - 1;

            _unwindedEventCollection.DeleteMany(Builders <UnwindedDomainEvent> .Filter.Gte(e => e.CheckpointToken, startToken));

            Int64 count = 0;
            List <UnwindedDomainEvent> batchEventUnwind = new List <UnwindedDomainEvent>(550);

            foreach (var commit in _persistStream.GetFrom(checkpointToken))
            {
                foreach (var evt in UnwindCommit(commit))
                {
                    batchEventUnwind.Add(evt);
                    if (batchEventUnwind.Count > 500)
                    {
                        _unwindedEventCollection.InsertMany(batchEventUnwind);
                        batchEventUnwind.Clear();
                    }
                }
                checkpointToken = commit.CheckpointToken;
                if (++count % 10000 == 0)
                {
                    _logger.InfoFormat("Unwinded block of 10000 commit, now we are at checkpoint {0}", checkpointToken);
                }
            }
            if (batchEventUnwind.Count > 0)
            {
                _unwindedEventCollection.InsertMany(batchEventUnwind);
            }

            _logger.InfoFormat("Unwind events ends, started from commit {0} and ended with commit {1}", startToken, checkpointToken);
        }
コード例 #14
0
        /// <summary>
        /// Catches-up the projector if it has fallen behind the head
        /// </summary>
        protected virtual void Catchup()
        {
            var comparer = new CheckpointComparer();
            IEnumerable <ICommit> commits = _persistStreams.GetFrom(Checkpoint.GetOrElse(() => 0)); //load all commits after our current checkpoint from db

            foreach (var commit in commits)
            {
                Project(commit);
                if (comparer.Compare(Checkpoint, commit.CheckpointToken.ToSome()) != 0)
                {
                    //something went wrong, we couldn't project
                    Context.GetLogger().Warning("Stopped catchup! was unable to project the commit at checkpoint {0}", commit.CheckpointToken);
                    break;
                }
            }
        }
コード例 #15
0
        public virtual IEnumerable <ICommit> GetFrom(string bucketId, string streamId, int minRevision, int maxRevision)
        {
            foreach (var commit in _persistence.GetFrom(bucketId, streamId, minRevision, maxRevision))
            {
                ICommit filtered = commit;
                foreach (var hook in _pipelineHooks.Where(x => (filtered = x.Select(filtered)) == null))
                {
                    Logger.Info(Resources.PipelineHookSkippedCommit, hook.GetType(), commit.CommitId);
                    break;
                }

                if (filtered == null)
                {
                    Logger.Info(Resources.PipelineHookFilteredCommit);
                }
                else
                {
                    yield return(filtered);
                }
            }
        }
コード例 #16
0
            public When_there_are_no_more_commits()
            {
                Given(() =>
                {
                    eventStore = A.Fake <IPersistStreams>();
                    A.CallTo(() => eventStore.GetFrom(A <string> .Ignored))
                    .Invokes(_ =>
                    {
                        eventStoreQueriedSource.SetResult(null);
                    })
                    .Returns(new ICommit[0]);

                    WithSubject(_ => new NEventStoreAdapter(eventStore, 11, pollingInterval, 100, () => utcNow));

                    Subject.Subscribe(1000, transactions => Task.FromResult(0));
                });

                When(async() =>
                {
                    await eventStoreQueriedSource.Task;
                });
            }
 public IEnumerable <ICommit> GetFrom(string bucketId, string streamId, int minRevision, int maxRevision)
 {
     return(underlying.GetFrom(bucketId, streamId, minRevision, maxRevision));
 }
コード例 #18
0
 public IEnumerable <ICommit> GetFrom(string bucketId, string streamId, int minRevision, int maxRevision)
 {
     return(ExecuteHooks(_original.GetFrom(bucketId, streamId, minRevision, maxRevision)));
 }
コード例 #19
0
 public virtual IEnumerable <Commit> GetFrom(string bucketId, string streamId, int minRevision, int maxRevision)
 {
     return(_persistence.GetFrom(bucketId, streamId, minRevision, maxRevision));
 }
コード例 #20
0
 public IEnumerable <Commit> GetFrom(Guid streamId, int minRevision, int maxRevision)
 {
     return(original.GetFrom(streamId, minRevision, maxRevision));
 }
コード例 #21
0
            private void DoPoll()
            {
                if (_persistStreams.IsDisposed)
                {
                    return;                             //no need to poll, someone disposed NEventStore wihout sh
                }
                if (Interlocked.CompareExchange(ref _isPolling, 1, 0) == 0)
                {
                    Int32 exceptionCount = 0;
                    do
                    {
                        try
                        {
                            skippedPoolCount = 0;
                            IEnumerable <ICommit> commits = _persistStreams.GetFrom(_checkpointToken);
                            Int64 i = 0;
                            foreach (var commit in commits)
                            {
                                if (_stopRequested.IsCancellationRequested)
                                {
                                    _subject.OnCompleted();
                                    return;
                                }

                                _enhancer.Enhance(commit);

                                _subject.OnNext(commit);
                                i++;
                                if (i % 1000 == 0)
                                {
                                    var minCheckpoint    = _tracker.GetMinCheckpoint();
                                    var actualCheckpoint = Int64.Parse(commit.CheckpointToken);
                                    while (actualCheckpoint > minCheckpoint + 1000)
                                    {
                                        Thread.Sleep(500);
                                        minCheckpoint = _tracker.GetMinCheckpoint();
                                    }
                                }
                                _checkpointToken = commit.CheckpointToken;
                            }
                        }
                        catch (Exception ex)
                        {
                            // These exceptions are expected to be transient
                            Logger.Error(ex.ToString());
                            exceptionCount++;
                            if (_persistStreams.IsDisposed || exceptionCount > 5)
                            {
                                //eventstore is stopped or too many exception, need to exit poll cycle.
                                skippedPoolCount = 0;
                            }
                            else
                            {
                                //conceptually if we have an exception and we are in manual poll we
                                //are potentially skipping some commit so we need to reschedule a poll
                                Interlocked.Increment(ref skippedPoolCount);
                            }
                        }
                    } while (skippedPoolCount > 0);
                    Interlocked.Exchange(ref _isPolling, 0);
                }
                else
                {
                    Interlocked.Increment(ref skippedPoolCount);
                    Logger.Debug("Poll skipped, count " + skippedPoolCount);
                }
            }
コード例 #22
0
        private async Task <Page> TryLoadNextPage(long previousCheckpoint, string subscriptionId)
        {
            // Maybe it's just loaded to cache.
            try
            {
                Page cachedPage = TryGetNextPageFromCache(previousCheckpoint, subscriptionId);
                if (cachedPage.Transactions.Count > 0)
                {
#if DEBUG
                    LogProvider.GetCurrentClassLogger()
                    .Debug(() =>
                           $"Loader for subscription {subscriptionId ?? "without ID"} has found a page in the cache.");
#endif
                    return(cachedPage);
                }
            }
            catch (Exception exception)
            {
                LogProvider.GetLogger(typeof(NEventStoreAdapter))
                .ErrorException(
                    $"Failed getting transactions after checkpoint {previousCheckpoint} from the cache.",
                    exception);
            }

            DateTime           timeOfRequestUtc = getUtcNow();
            List <Transaction> transactions;

            try
            {
                transactions = await Task
                               .Run(() => eventStore
                                    .GetFrom(previousCheckpoint.ToString())
                                    .Take(maxPageSize)
                                    .Select(ToTransaction)
                                    .ToList())
                               .ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                LogProvider.GetLogger(typeof(NEventStoreAdapter))
                .ErrorException(
                    $"Failed loading transactions after checkpoint {previousCheckpoint} from NEventStore",
                    exception);

                return(new Page(previousCheckpoint, new List <Transaction>()));
            }

            if (transactions.Count > 0)
            {
#if DEBUG
                LogProvider.GetCurrentClassLogger().Debug(() =>
                                                          $"Loader for subscription {subscriptionId ?? "without ID"} has loaded {transactions.Count} transactions " +
                                                          $"from checkpoint {transactions.First().Checkpoint} to checkpoint {transactions.Last().Checkpoint}.");
#endif

                /* Add to cache in reverse order to prevent other projectors
                 *  from requesting already loaded transactions which are not added to cache yet. */
                for (int index = transactions.Count - 1; index > 0; index--)
                {
                    transactionCacheByPreviousCheckpoint.Set(transactions[index - 1].Checkpoint, transactions[index]);
                }

                transactionCacheByPreviousCheckpoint.Set(previousCheckpoint, transactions[0]);

#if DEBUG
                LogProvider.GetCurrentClassLogger().Debug(() =>
                                                          $"Loader for subscription {subscriptionId ?? "without ID"} has cached {transactions.Count} transactions " +
                                                          $"from checkpoint {transactions.First().Checkpoint} to checkpoint {transactions.Last().Checkpoint}.");
#endif
            }
            else
            {
#if DEBUG
                LogProvider.GetCurrentClassLogger().Debug(() =>
                                                          $"Loader for subscription {subscriptionId ?? "without ID"} has discovered " +
                                                          $"that there are no new transactions yet. Next request for the new transactions will be delayed.");
#endif

                Volatile.Write(
                    ref lastExistingCheckpointRequest,
                    new CheckpointRequestTimestamp(previousCheckpoint, timeOfRequestUtc));
            }

            return(new Page(previousCheckpoint, transactions));
        }
コード例 #23
0
 protected override void Because()
 {
     committed1 = persistence1.GetFrom(now).ToArray();
 }
コード例 #24
0
 public void should_purge_all_commits_stored()
 {
     persistence1.GetFrom(DateTime.MinValue).Count().ShouldBe(0);
 }
 public IEnumerable <Transaction> GetFrom(long?checkpoint)
 {
     return(streamPersister
            .GetFrom((!checkpoint.HasValue || checkpoint == 0) ? null : checkpoint.ToString())
            .Select(ToTransaction));
 }
コード例 #26
0
            private void DoPoll()
            {
                if (_persistStreams.IsDisposed)
                {
                    return;                             //no need to poll, someone disposed NEventStore wihout sh
                }
                if (Interlocked.CompareExchange(ref _isPolling, 1, 0) == 0)
                {
                    Int32 exceptionCount = 0;
                    do
                    {
                        try
                        {
                            skippedPoolCount = 0;
                            IEnumerable <ICommit> commits = _persistStreams.GetFrom(_checkpointToken);
                            foreach (var commit in commits)
                            {
                                if (_stopRequested.IsCancellationRequested)
                                {
                                    _buffer.Complete();
                                    return;
                                }

                                _enhancer.Enhance(commit);

                                while (!_buffer.SendAsync(commit).Wait(2000))
                                {
                                    //maybe the mesh is full, but check for completion
                                    if (_stopRequested.IsCancellationRequested)
                                    {
                                        _buffer.Complete();
                                        return;
                                    }
                                }
                                ;
                                _checkpointToken = commit.CheckpointToken;
                            }
                        }
                        catch (Exception ex)
                        {
                            // These exceptions are expected to be transient
                            Logger.Error(ex.ToString());
                            exceptionCount++;
                            if (_persistStreams.IsDisposed || exceptionCount > 5)
                            {
                                //eventstore is stopped or too many exception, need to exit poll cycle.
                                skippedPoolCount = 0;
                            }
                            else
                            {
                                //conceptually if we have an exception and we are in manual poll we
                                //are potentially skipping some commit so we need to reschedule a poll
                                Interlocked.Increment(ref skippedPoolCount);
                            }
                        }
                    } while (skippedPoolCount > 0);
                    Interlocked.Exchange(ref _isPolling, 0);
                }
                else
                {
                    Interlocked.Increment(ref skippedPoolCount);
                    Logger.Debug("Poll skipped, count " + skippedPoolCount);
                }
            }