public Task ProjectAsync(StreamSubscription subscription, ResolvedEvent e,
                                     CancellationToken cancellationToken)
            {
                if (!_messageTypeMapper.TryMap(e.Event.EventType, out var type))
                {
                    return(Task.CompletedTask);
                }

                var message = JsonSerializer.Deserialize(e.Event.Data.Span, type !, TransactoSerializerOptions.Events) !;

                return(Task.WhenAll(_projectors.Where(x => x.Checkpoint < e.OriginalPosition)
                                    .Select(_ => _.Projector.ProjectAsync(_streamStore,
                                                                          new Envelope(message, e.OriginalEvent.Position), cancellationToken))));
            }
示例#2
0
            public Task ProjectAsync(StreamSubscription subscription, ResolvedEvent e,
                                     CancellationToken cancellationToken)
            {
                if (!_messageTypeMapper.TryMap(e.Event.EventType, out var type))
                {
                    return(Task.CompletedTask);
                }

                var message = JsonSerializer.Deserialize(e.Event.Data.Span, type, TransactoSerializerOptions.Events) !;

                return(Task.WhenAll(_projectors.Where(projection => projection.Checkpoint < e.OriginalPosition)
                                    .Select(async projector => {
                    await using var connection = _connectionFactory();
                    await connection.OpenAsync(cancellationToken);
                    await using var transaction = await connection.BeginTransactionAsync(cancellationToken);
                    var(projection, _) = projector;
                    var sqlProjector = new AsyncSqlProjector(projector.Resolver,
                                                             new ConnectedTransactionalSqlCommandExecutor(transaction));
                    await sqlProjector.ProjectAsync(message, cancellationToken);
                    await projection.WriteCheckpoint(transaction, e.Event.Position, cancellationToken);
                    await transaction.CommitAsync(cancellationToken);
                })));
            }
        private async Task Subscribe(CancellationToken cancellationToken)
        {
            if (Interlocked.CompareExchange(ref _subscribed, 1, 0) == 1)
            {
                return;
            }

            var registration = _stoppedRegistration;

            if (registration != null)
            {
                await registration.Value.DisposeAsync();
            }

            Interlocked.Exchange(ref _subscription, await _eventStore.SubscribeToAllAsync(
                                     Position.Start,
                                     ProjectAsync,
                                     subscriptionDropped: (_, reason, ex) => {
                if (reason == SubscriptionDroppedReason.Disposed)
                {
                    return;
                }

                Log.Error(ex, "Subscription dropped: {reason}", reason);
            },
                                     filterOptions: new SubscriptionFilterOptions(EventTypeFilter.ExcludeSystemEvents()),
                                     userCredentials: new UserCredentials("admin", "changeit"),
                                     cancellationToken: _stopped.Token));

            _stoppedRegistration = _stopped.Token.Register(_subscription.Dispose);

            Task ProjectAsync(StreamSubscription s, ResolvedEvent e, CancellationToken ct) =>
            _messageTypeMapper.TryMap(e.Event.EventType, out var type)
                                        ? _projector.ProjectAsync(_target, new Envelope(JsonSerializer.Deserialize(
                                                                                            e.Event.Data.Span, type, TransactoSerializerOptions.Events) !, e.OriginalEvent.Position), ct)
                                        : Task.CompletedTask;
        }
示例#4
0
 public bool TryMap(string storageType, out Type type) => _inner.TryMap(storageType, out type);
示例#5
0
        private async Task Subscribe(CancellationToken cancellationToken)
        {
            if (Interlocked.CompareExchange(ref _subscribed, 1, 0) == 1)
            {
                return;
            }

            var registration = _stoppedRegistration;

            if (registration != null)
            {
                await registration.Value.DisposeAsync();
            }

            Interlocked.Exchange(ref _subscription, await Subscribe());

            _stoppedRegistration = _stopped.Token.Register(_subscription.Dispose);

            async Task <StreamSubscription> Subscribe()
            {
                await using var result = _eventStore.ReadStreamAsync(Direction.Backwards, _checkpointStreamName,
                                                                     StreamPosition.End, cancellationToken: cancellationToken);

                _checkpoint = await result.ReadState == ReadState.StreamNotFound
                                        ? Checkpoint.None
                                        : await result.Select(e => new Checkpoint(e.Event.Data)).FirstOrDefaultAsync(cancellationToken);

                return(await _eventStore.SubscribeToAllAsync(
                           _checkpoint.ToEventStorePosition(), HandleAsync, subscriptionDropped : (_, reason, _) => {
                    if (reason == SubscriptionDroppedReason.Disposed)
                    {
                        return;
                    }

                    //Log.Error(ex, "Subscription dropped: {reason}", reason);
                },
                           filterOptions : new SubscriptionFilterOptions(EventTypeFilter.ExcludeSystemEvents()),
                           userCredentials : new UserCredentials("admin", "changeit"),
                           cancellationToken : _stopped.Token));
            }

            async Task HandleAsync(StreamSubscription s, ResolvedEvent e, CancellationToken ct)
            {
                if (!_messageTypeMapper.TryMap(e.Event.EventType, out var type))
                {
                    return;
                }

                var message = JsonSerializer.Deserialize(e.Event.Data.Span, type, TransactoSerializerOptions.Events) !;

                _checkpoint = await _dispatcher.Handle(message, ct);

                if (_checkpoint == Checkpoint.None)
                {
                    return;
                }

                await _eventStore.AppendToStreamAsync(_checkpointStreamName, StreamState.Any, new[] {
                    new EventData(Uuid.NewUuid(), "checkpoint", _checkpoint.Memory,
                                  contentType: "application/octet-stream")
                }, cancellationToken : ct);
            }
        }
示例#6
0
 public void TryMapTypeReturnsExpectedResult()
 {
     Assert.True(_sut.TryMap(typeof(SomeEvent), out var storageType));
     Assert.Equal(nameof(SomeEvent), storageType);
 }