Пример #1
0
        private void initializeDataflowBlocks(ProjectionDaemon daemon)
        {
            var singleFileOptions = new ExecutionDataflowBlockOptions
            {
                EnsureOrdered          = true,
                MaxDegreeOfParallelism = 1,
                CancellationToken      = _cancellation,
            };

            _commandBlock = new ActionBlock <Command>(command => command.Apply(_controller), singleFileOptions);
            _loader       = new TransformBlock <EventRange, EventRange>(loadEvents, singleFileOptions);

            _tracker = daemon.Tracker;
            _daemon  = daemon;

            _fetcher  = new EventFetcher(_store, _daemon.Database, _projectionShard.EventFilters);
            _grouping = new TransformBlock <EventRange, EventRangeGroup>(groupEventRange, singleFileOptions);

            _building = new ActionBlock <EventRangeGroup>(processRange, singleFileOptions);

            _grouping.LinkTo(_building);

            // The filter is important. You may need to allow an empty page to go through
            // just to keep tracking correct
            _loader.LinkTo(_grouping, e => e.Events != null);
        }
Пример #2
0
        public async Task <long> Start(ProjectionDaemon daemon)
        {
            _logger.LogInformation("Starting projection agent for '{ShardName}'", _projectionShard.Name);

            var singleFile = new ExecutionDataflowBlockOptions
            {
                EnsureOrdered          = true,
                MaxDegreeOfParallelism = 1,
                CancellationToken      = _cancellation,
            };

            _commandBlock = new ActionBlock <Command>(processCommand, singleFile);
            _loader       = new TransformBlock <EventRange, EventRange>(loadEvents, singleFile);

            _tracker = daemon.Tracker;
            _daemon  = daemon;


            _fetcher = new EventFetcher(_store, _projectionShard.EventFilters);
            _hopper  = _projectionShard.Start(this, _logger, _cancellation);
            _loader.LinkTo(_hopper, e => e.Events.Any());

            var lastCommitted = await _store.Advanced.ProjectionProgressFor(_projectionShard.Name, _cancellation);

            _commandBlock.Post(Command.Started(_tracker.HighWaterMark, lastCommitted));

            _subscription = _tracker.Subscribe(this);

            _logger.LogInformation("Projection agent for '{ShardName}' has started from sequence {LastCommitted} and a high water mark of {HighWaterMark}", _projectionShard.Name, lastCommitted, _tracker.HighWaterMark);

            Status = AgentStatus.Running;

            Position = lastCommitted;
            return(lastCommitted);
        }
Пример #3
0
        // ReSharper disable once ContextualLoggerProblem
        public NodeAgent(DocumentStore store, ILogger <IProjection> logger)
        {
            _cancellation = new CancellationTokenSource();
            _store        = store;
            _logger       = logger;
            var detector = new HighWaterDetector(store.Tenancy.Default, store.Events);

            Tracker    = new ShardStateTracker();
            _highWater = new HighWaterAgent(detector, Tracker, logger, store.Events.Daemon, _cancellation.Token);
        }
Пример #4
0
        public ShardStatusWatcher(ShardStateTracker tracker, ShardState expected, TimeSpan timeout)
        {
            _expected   = expected;
            _completion = new TaskCompletionSource <ShardState>();


            _timeout = new CancellationTokenSource(timeout);
            _timeout.Token.Register(() =>
            {
                _completion.TrySetException(new TimeoutException(
                                                $"Shard {_expected.ShardName} did not reach sequence number {_expected.Sequence} in the time allowed"));
            });

            _unsubscribe = tracker.Subscribe(this);
        }
Пример #5
0
        public async Task<long> Start(ProjectionDaemon daemon)
        {
            _logger.LogInformation("Starting projection agent for '{ShardName}'", _projectionShard.Name);

            var singleFileOptions = new ExecutionDataflowBlockOptions
            {
                EnsureOrdered = true,
                MaxDegreeOfParallelism = 1,
                CancellationToken = _cancellation,
            };

            _commandBlock = new ActionBlock<Command>(processCommand, singleFileOptions);
            _loader = new TransformBlock<EventRange, EventRange>(loadEvents, singleFileOptions);

            _tracker = daemon.Tracker;
            _daemon = daemon;


            _fetcher = new EventFetcher(_store, _projectionShard.EventFilters);
            _grouping = new TransformBlock<EventRange, EventRangeGroup>(groupEventRange, singleFileOptions);


            _building = new ActionBlock<EventRangeGroup>(processRange, singleFileOptions);

            _grouping.LinkTo(_building);

            // The filter is important. You may need to allow an empty page to go through
            // just to keep tracking correct
            _loader.LinkTo(_grouping, e => e.Events != null);

            var lastCommitted = await _store.Advanced.ProjectionProgressFor(_projectionShard.Name, _cancellation);

            foreach (var storageType in _source.Options.StorageTypes)
            {
                await _store.Tenancy.Default.EnsureStorageExistsAsync(storageType, _cancellation);
            }

            _commandBlock.Post(Command.Started(_tracker.HighWaterMark, lastCommitted));

            _subscription = _tracker.Subscribe(this);

            _logger.LogInformation("Projection agent for '{ShardName}' has started from sequence {LastCommitted} and a high water mark of {HighWaterMark}", _projectionShard.Name, lastCommitted, _tracker.HighWaterMark);

            Status = AgentStatus.Running;

            Position = lastCommitted;
            return lastCommitted;
        }
Пример #6
0
        public ShardStatusWatcher(ShardStateTracker tracker, ShardState expected, TimeSpan timeout)
        {
            _condition  = x => x.Equals(expected);
            _completion = new TaskCompletionSource <ShardState>(TaskCreationOptions.RunContinuationsAsynchronously);


            var timeout1 = new CancellationTokenSource(timeout);

            timeout1.Token.Register(() =>
            {
                _completion.TrySetException(new TimeoutException(
                                                $"Shard {expected.ShardName} did not reach sequence number {expected.Sequence} in the time allowed"));
            });

            _unsubscribe = tracker.Subscribe(this);
        }
Пример #7
0
        public async Task <long> Start(ProjectionDaemon daemon)
        {
            _logger.LogInformation("Starting projection agent for '{ShardName}'", _projectionShard.Name);

            var singleFileOptions = new ExecutionDataflowBlockOptions
            {
                EnsureOrdered          = true,
                MaxDegreeOfParallelism = 1,
                CancellationToken      = _cancellation,
            };

            _commandBlock = new ActionBlock <Command>(processCommand, singleFileOptions);
            _loader       = new TransformBlock <EventRange, EventRange>(loadEvents, singleFileOptions);

            _tracker = daemon.Tracker;
            _daemon  = daemon;


            _fetcher  = new EventFetcher(_store, _projectionShard.EventFilters);
            _grouping = new TransformBlock <EventRange, EventRangeGroup>(groupEventRange, singleFileOptions);


            _building = new ActionBlock <EventRangeGroup>(processRange, singleFileOptions);

            _grouping.LinkTo(_building);
            _loader.LinkTo(_grouping, e => e.Events.Any());

            var lastCommitted = await _store.Advanced.ProjectionProgressFor(_projectionShard.Name, _cancellation);

            foreach (var storageType in _source.Options.StorageTypes)
            {
                // TODO -- this will have to get fancier when we do multi-tenancy by database
                _store.Tenancy.Default.EnsureStorageExists(storageType);
            }

            _commandBlock.Post(Command.Started(_tracker.HighWaterMark, lastCommitted));

            _subscription = _tracker.Subscribe(this);

            _logger.LogInformation("Projection agent for '{ShardName}' has started from sequence {LastCommitted} and a high water mark of {HighWaterMark}", _projectionShard.Name, lastCommitted, _tracker.HighWaterMark);

            Status = AgentStatus.Running;

            Position = lastCommitted;
            return(lastCommitted);
        }
Пример #8
0
        public async Task <long> Start(ShardStateTracker tracker)
        {
            _logger.LogInformation($"Starting projection agent for '{_projectionShard.ProjectionOrShardName}'");

            _tracker = tracker;


            _fetcher = new EventFetcher(_store, _projectionShard.EventFilters);
            _hopper  = _projectionShard.Start(this, _logger, _cancellationSource.Token);
            _loader.LinkTo(_hopper);

            var lastCommitted = await _store.Events.ProjectionProgressFor(_projectionShard.ProjectionOrShardName);

            _commandBlock.Post(Command.Started(tracker.HighWaterMark, lastCommitted));

            _subscription = _tracker.Subscribe(this);

            _logger.LogInformation($"Projection agent for '{_projectionShard.ProjectionOrShardName}' has started from sequence {lastCommitted} and a high water mark of {tracker.HighWaterMark}");

            Status = AgentStatus.Running;

            Position = lastCommitted;
            return(lastCommitted);
        }
Пример #9
0
 public Unsubscriber(ShardStateTracker tracker, IObserver <ShardState> observer)
 {
     _tracker  = tracker;
     _observer = observer;
 }
Пример #10
0
        public ShardStatusWatcher(string description, Func <ShardState, bool> condition, ShardStateTracker tracker, TimeSpan timeout)
        {
            _condition  = condition;
            _completion = new TaskCompletionSource <ShardState>();


            var timeout1 = new CancellationTokenSource(timeout);

            timeout1.Token.Register(() =>
            {
                _completion.TrySetException(new TimeoutException(
                                                $"{description} was not detected in the time allowed"));
            });

            _unsubscribe = tracker.Subscribe(this);
        }