Example #1
0
        /// <summary>
        /// Create a poller, start the poller and return starting position of the poller.
        /// </summary>
        /// <param name="poller"></param>
        /// <param name="pollerId"></param>
        /// <returns></returns>
        private Int64 CreatePollerAndStart(ref PollingClient poller, Int32 pollerId, Func <AtomicDispatchChunk, Task <Boolean> > dispatchToTplFunction)
        {
            if (poller != null)
            {
                poller.Stop();
            }
            var startingPosition = TryGetStartingPoint(pollerId);

            Logger.InfoFormat("AtomicProjectionEngine: Starting poller id {0} from position {1}", pollerId, startingPosition);
            var subscription = new JarvisFrameworkLambdaSubscription(c => dispatchToTplFunction(new AtomicDispatchChunk(pollerId, c)));

            poller = new PollingClient(_persistence, startingPosition, subscription, _nStoreLoggerFactory);
            poller.Start();
            return(startingPosition);
        }
Example #2
0
        /// <summary>
        /// Create a poller, start the poller and return starting position of the poller.
        /// </summary>
        /// <param name="poller"></param>
        /// <param name="pollerId"></param>
        /// <returns></returns>
        private Int64 CreatePollerAndStart(ref PollingClient poller, Int32 pollerId, Func <AtomicDispatchChunk, Task <Boolean> > dispatchToTplFunction)
        {
            if (poller != null)
            {
                poller.Stop();
            }
            //The default value to start is zero, it is a situation that should never happen, if it happens this poller has no projection to dispatch.
            var startingPosition = TryGetStartingPoint(pollerId, 0);

            Logger.InfoFormat("AtomicProjectionEngine: Starting poller id {0} from position {1}", pollerId, startingPosition);
            var subscription = new JarvisFrameworkLambdaSubscription(c => dispatchToTplFunction(new AtomicDispatchChunk(pollerId, c)));

            poller = new PollingClient(_persistence, startingPosition, subscription, _nStoreLoggerFactory);
            poller.Start();
            return(startingPosition);
        }
Example #3
0
        public void Configure(
            Int64 checkpointTokenFrom,
            Int32 bufferSize)
        {
            _logger.InfoFormat("CommitPollingClient {0}: Configured starting from {1} buffer {2}", _id, checkpointTokenFrom, bufferSize);
            _bufferSize             = bufferSize;
            _lastDispatchedPosition = checkpointTokenFrom - 1;
            LastException           = null;
            //prepare single poller thread.
            CreateTplChain();

            _innerSubscription = new JarvisFrameworkLambdaSubscription(DispatchChunk);

            _innerClient = new PollingClient(
                _persistence,
                checkpointTokenFrom,
                _innerSubscription,
                _factory);

            RegisterHealthChecks(_id);
        }
        public async Task UnwindAsync()
        {
            var lastEvent = _unwindedEventCollection
                            .Find(Builders <UnwindedDomainEvent> .Filter.Empty)
                            .Sort(Builders <UnwindedDomainEvent> .Sort.Descending(e => e.CheckpointToken))
                            .Limit(1)
                            .SingleOrDefault();
            Int64 startToken = 1; //remember with NStore is inclusive

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

            //we want to avoid holes up to the maximum committed tokens, holes are only when we are
            //in high concurrency.
            var lastCommittedToken = await _persistence.ReadLastPositionAsync().ConfigureAwait(false);

            lastCommittedToken = Math.Max(0, lastCommittedToken - 10); //we choose an arbitrary offset to avoid problem in high concurrency

            _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;

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

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

            var subscription = new JarvisFrameworkLambdaSubscription(async data =>
            {
                foreach (var evt in UnwindChunk(data))
                {
                    batchEventUnwind.Add(evt);
                    if (batchEventUnwind.Count > 500)
                    {
                        await _unwindedEventCollection.InsertManyAsync(batchEventUnwind).ConfigureAwait(false);
                        batchEventUnwind.Clear();
                    }
                }
                checkpointToken = data.Position;
                if (++count % 10000 == 0)
                {
                    _logger.InfoFormat("Unwinded block of 10000 commit, now we are at checkpoint {0}", checkpointToken);
                }

                return(true);
            }, "unwinder");

            var sequencer = new NStoreSequencer(
                startToken - 1,
                subscription,
                timeToWaitInMilliseconds: 0,
                maximumWaitCountForSingleHole: 5,
                safePosition: lastCommittedToken,
                logger: _logger);

            //Need to cycle until the sequencer skipped an hole, to be sure to unwind all events.
            do
            {
                //Reload from the last position where the sequencer stopped.
                await _persistence.ReadAllAsync(sequencer.Position + 1, sequencer).ConfigureAwait(false);
            } while (sequencer.RetriesOnHole > 0);

            if (subscription.Failed)
            {
                throw new JarvisFrameworkEngineException("Error unwinding commits", subscription.LastException);
            }

            //Flush last batch.
            if (batchEventUnwind.Count > 0)
            {
                _unwindedEventCollection.InsertMany(batchEventUnwind);
            }
            _logger.InfoFormat("Unwind events ends, started from commit {0} and ended with commit {1}", startToken, checkpointToken);
        }