Beispiel #1
0
        public async Task StartShard(IAsyncProjectionShard shard, CancellationToken cancellationToken)
        {
            if (!_hasStarted)
            {
                StartNode();
            }

            // Don't duplicate the shard
            if (_agents.ContainsKey(shard.Name.Identity))
            {
                return;
            }

            await TryAction(null, async() =>
            {
                try
                {
                    var agent    = new ProjectionAgent(_store, shard, _logger, cancellationToken);
                    var position = await agent.Start(this);

                    Tracker.Publish(new ShardState(shard.Name, position)
                    {
                        Action = ShardAction.Started
                    });

                    _agents[shard.Name.Identity] = agent;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Error when trying to start projection shard '{ShardName}'", shard.Name.Identity);
                    throw new ShardStartException(shard.Name, e);
                }
            }, cancellationToken);
        }
Beispiel #2
0
        public async Task StartShard(IAsyncProjectionShard shard)
        {
            if (!_hasStarted)
            {
                StartNode();
            }

            // TODO -- log the start, or error if it fails
            var agent    = new ProjectionAgent(_store, shard, _logger);
            var position = await agent.Start(Tracker);

            Tracker.Publish(new ShardState(shard.ProjectionOrShardName, position)
            {
                Action = ShardAction.Started
            });

            _agents[shard.ProjectionOrShardName] = agent;
        }
Beispiel #3
0
        internal async Task TryAction(ProjectionAgent projection, Func <Task> action, CancellationToken token, int attempts = 0, TimeSpan delay = default)
        {
            if (delay != default)
            {
                await Task.Delay(delay, token);
            }

            if (token.IsCancellationRequested)
            {
                return;
            }

            try
            {
                await action();
            }
            catch (Exception ex)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }

                var continuation = Settings.DetermineContinuation(ex, attempts);
                switch (continuation)
                {
                case RetryLater r:
                    await TryAction(projection, action, token, attempts + 1, r.Delay);

                    break;

                case StopProjection:
                    if (projection != null)
                    {
                        await StopShard(projection.ShardName.Identity, ex);
                    }
                    break;

                case StopAllProjections:
                    var tasks = _agents.Keys.ToArray().Select(name =>
                    {
                        return(Task.Run(async() =>
                        {
                            await StopShard(name, ex);
                        }, _cancellation.Token));
                    });

                    await Task.WhenAll(tasks);

                    Tracker.Publish(new ShardState(ShardName.All, Tracker.HighWaterMark)
                    {
                        Action = ShardAction.Stopped, Exception = ex
                    });
                    break;

                case PauseProjection pause:
                    if (projection != null)
                    {
                        await projection.Pause(pause.Delay);
                    }
                    break;

                case PauseAllProjections pauseAll:
                    var tasks2 = _agents.Values.ToArray().Select(agent =>
                    {
                        return(Task.Run(async() =>
                        {
                            await agent.Pause(pauseAll.Delay);
                        }, _cancellation.Token));
                    });

                    await Task.WhenAll(tasks2);

                    break;

                case DoNothing:
                    // Don't do anything.
                    break;
                }
            }
        }