Esempio n. 1
0
        public async Task Start(CancellationToken cancellationToken)
        {
            foreach (var projection in _registeredProjections.Projections)
            {
                await projection.UpdateUserDesiredState(UserDesiredState.Started, cancellationToken);
            }

            _commandBus.Queue <StartAll>();
        }
Esempio n. 2
0
        private Task OnStreamMessageReceived(
            IAllStreamSubscription subscription,
            StreamMessage message,
            CancellationToken cancellationToken)
        {
            _commandBus.Queue(new ProcessStreamEvent(message, cancellationToken));

            return(Task.CompletedTask);
        }
Esempio n. 3
0
        private void CatchUpStopped(CatchUpStopReason reason)
        {
            var message = "Stopping catch up {RunnerName}: {Reason}";

            if (reason == CatchUpStopReason.Error)
            {
                _logger.LogWarning(message, _runnerName, reason);
            }
            else
            {
                _logger.LogInformation(message, _runnerName, reason);
            }

            _commandBus.Queue(new RemoveStoppedCatchUp(_runnerName));
            if (CatchUpStopReason.Finished == reason)
            {
                _commandBus.Queue(new Subscribe(_runnerName));
            }
        }
Esempio n. 4
0
        private async Task StartStream()
        {
            if (_streamsStoreSubscription.StreamIsRunning)
            {
                return;
            }

            if (_handlers.Count > 0)
            {
                var staleSubscriptions = _handlers.Keys.ToReadOnlyList();
                _logger.LogInformation("Remove stale subscriptions before starting stream: {subscriptions}", staleSubscriptions.ToString(", "));
                _handlers.Clear();

                foreach (var name in staleSubscriptions)
                {
                    _commandBus.Queue(new Start(name));
                }
            }

            _lastProcessedMessagePosition = await _streamsStoreSubscription.Start();
        }
        public async Task Handle(ConnectedProjectionCommand?command)
        {
            if (command == null)
            {
                _logger.LogWarning("Skipping null Command");
                return;
            }

            switch (command)
            {
            case SubscriptionCommand subscriptionCommand:
                await _subscriptionRunner.HandleSubscriptionCommand(subscriptionCommand);

                return;

            case CatchUpCommand catchUpCommand:
                _catchUpRunner.HandleCatchUpCommand(catchUpCommand);
                return;
            }

            _logger.LogTrace("Handling {Command}", command);
            switch (command)
            {
            case Start start:
                _commandBus.Queue(new Subscribe(start.Projection));
                break;

            case StartAll _:
                _commandBus.Queue <SubscribeAll>();
                break;

            case Stop stop:
                _commandBus.Queue(new StopCatchUp(stop.Projection));
                _commandBus.Queue(new Unsubscribe(stop.Projection));
                break;

            case StopAll _:
                _commandBus.Queue <StopAllCatchUps>();
                _commandBus.Queue <UnsubscribeAll>();
                break;

            case Restart restart:
                await Task.Delay(restart.After);

                _commandBus.Queue(new Start(restart.Projection));
                break;

            default:
                _logger.LogError("No handler defined for {Command}", command);
                break;
            }
        }
        public async Task Handle(ConnectedProjectionCommand command)
        {
            switch (command)
            {
            case SubscriptionCommand subscriptionCommand:
                await _subscriptionRunner.HandleSubscriptionCommand(subscriptionCommand);

                return;

            case CatchUpCommand catchUpCommand:
                _catchUpRunner.HandleCatchUpCommand(catchUpCommand);
                return;
            }

            _logger.LogTrace("Handling {Command}", command);
            switch (command)
            {
            case Start start:
                _commandBus.Queue(new Subscribe(start.ProjectionName));
                break;

            case StartAll _:
                _commandBus.Queue <SubscribeAll>();
                break;

            case Stop stop:
                _commandBus.Queue(new StopCatchUp(stop.ProjectionName));
                _commandBus.Queue(new Unsubscribe(stop.ProjectionName));
                break;

            case StopAll _:
                _commandBus.Queue <StopAllCatchUps>();
                _commandBus.Queue <UnsubscribeAll>();
                break;

            default:
                _logger.LogError("No handler defined for {Command}", command);
                break;
            }
        }
 public static void Queue <TCommand>(this IConnectedProjectionsCommandBus commandBus)
     where TCommand : ConnectedProjectionCommand, new()
 => commandBus?.Queue(new TCommand());
Esempio n. 8
0
 public void Start() => _commandBus.Queue <StartAll>();
        public async Task CatchUpAsync(CancellationToken cancellationToken)
        {
            cancellationToken.Register(() => CatchUpStopped(CatchUpStopReason.Aborted));

            try
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                _logger.LogDebug(
                    "Started catch up with paging (CatchUpPageSize: {CatchUpPageSize})",
                    _settings.CatchUpPageSize);

                long?position;
                using (var context = _projection.ContextFactory())
                    position = await context.Value.GetProjectionPosition(_projection.Id, cancellationToken);

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                _logger.LogInformation(
                    "Start catch up {Projection} at {Position}",
                    _projection.Id,
                    position);

                var page = await ReadPages(_streamStore, position, cancellationToken);

                var continueProcessing = cancellationToken.IsCancellationRequested == false;
                while (continueProcessing)
                {
                    _logger.LogDebug(
                        "Processing page of {PageSize} starting at POS {FromPosition}",
                        page.Messages.Length,
                        page.FromPosition);

                    await _projection
                    .ConnectedProjectionMessageHandler
                    .HandleAsync(
                        page.Messages,
                        _catchUpStreamGapStrategy,
                        cancellationToken);

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    if (page.IsEnd)
                    {
                        continueProcessing = false;
                    }
                    else
                    {
                        page = await page.ReadNext(cancellationToken);
                    }
                }

                CatchUpStopped(CatchUpStopReason.Finished);
            }
            catch (TaskCanceledException) { }
            catch (ConnectedProjectionMessageHandlingException e)
                when(e.InnerException is StreamGapDetectedException)
                {
                    var projection     = e.Projection;
                    var delayInSeconds = _catchUpStreamGapStrategy.Settings.RetryDelayInSeconds;

                    _logger.LogWarning(
                        "Detected gap in the message stream for catching up projection. Aborted projection {Projection} and queued restart in {GapStrategySettings.RetryDelayInSeconds} seconds.",
                        projection,
                        delayInSeconds);

                    CatchUpStopped(CatchUpStopReason.Aborted);

                    _commandBus.Queue(
                        new Restart(
                            projection,
                            TimeSpan.FromSeconds(delayInSeconds)));
                }
            catch (ConnectedProjectionMessageHandlingException exception)
            {
                _logger.LogError(
                    exception.InnerException,
                    "{Projection} catching up failed because an exception was thrown when handling the message at {Position}.",
                    exception.Projection,
                    exception.RunnerPosition);

                CatchUpStopped(CatchUpStopReason.Error);
            }
            catch (Exception exception)
            {
                _logger.LogError(
                    exception,
                    "{Projection} catching up failed because an exception was thrown",
                    _projection.Id);

                CatchUpStopped(CatchUpStopReason.Error);
            }
        }