public async Task <IStreamSubscription> SubscribeToAllAsync(Func <IStreamSubscription, ResolvedEvent, CancellationToken, Task> eventAppeared,
                                                                    bool resolveLinkTos                 = false, Action <IStreamSubscription, SubscriptionDroppedReason, Exception> subscriptionDropped = null,
                                                                    FilterOptions filterOptions         = null, Action <EventStoreClientOperationOptions> configureOperationOptions                     = null, UserCredentials userCredentials = null,
                                                                    CancellationToken cancellationToken = new CancellationToken())
        {
            HttpStreamSubscription subscription = new HttpStreamSubscription();

            return(subscription.WriteThough(await Client.SubscribeToAllAsync(async(s, r, c) => eventAppeared?.Invoke(subscription.WriteThough(s), r, c),
                                                                             resolveLinkTos,
                                                                             (s, r, e) => subscriptionDropped?.Invoke(subscription.WriteThough(s), r, e),
                                                                             filterOptions, configureOperationOptions, userCredentials, cancellationToken)));
        }
        private async Task SubscribeToAll()
        {
            var checkpoint = checkpointProvider.Get();
            var position   = checkpoint.HasValue ? new Position(checkpoint.Value, checkpoint.Value) : Position.Start;

            subscription = await client.SubscribeToAllAsync(position, OnEvent, subscriptionDropped : OnSubscriptionDropped);
        }
예제 #3
0
        protected override async Task <EventSubscription> Subscribe(
            Checkpoint checkpoint,
            CancellationToken cancellationToken)
        {
            var filterOptions = new SubscriptionFilterOptions(
                EventTypeFilter.ExcludeSystemEvents(),
                10,
                (_, p, ct) =>
                StoreCheckpoint(
                    new EventPosition(p.CommitPosition, DateTime.UtcNow),
                    ct));

            var(_, position) = checkpoint;
            var subscribeTask = position != null
                ? EventStoreClient.SubscribeToAllAsync(
                new Position(
                    position.Value,
                    position.Value),
                TransactionalHandler,
                false,
                HandleDrop,
                filterOptions,
                cancellationToken : cancellationToken)
                : EventStoreClient.SubscribeToAllAsync(
                TransactionalHandler,
                false,
                HandleDrop,
                filterOptions,
                cancellationToken: cancellationToken);

            var sub = await subscribeTask.NoContext();

            return(new EventSubscription(SubscriptionId,
                                         new Stoppable(() => sub.Dispose())));
        }
예제 #4
0
        static async Task Main(string[] args)
        {
            // run against
            // .\EventStore-OSS-Windows-2019-v20.6.1\EventStore.ClusterNode.exe --insecure
            // make sure http://localhost:2113 works
            var connectionString = "esdb://*****:*****@localhost:2113/?TlsVerifyCert=false&Tls=false";

            // run against
            // .\EventStore-OSS-Windows-2019-v20.6.0\EventStore.ClusterNode.exe --dev
            // make sure https://localhost:2113 works
            //var connectionString = "esdb://*****:*****@localhost:2113/?TlsVerifyCert=false";

            var settings = EventStoreClientSettings.Create(connectionString);
            var client   = new EventStoreClient(settings);

            await client.SubscribeToAllAsync(EventAppeared);

            Console.WriteLine("Subscribed to all events.");

            var data      = Encoding.UTF8.GetBytes("{}");
            var eventData = new EventData(Uuid.NewUuid(), "test-event", data);
            await client.AppendToStreamAsync("test-events", StreamState.Any, new[] { eventData });

            Console.WriteLine("Keypress to exit.");
            Console.ReadKey();
        }
    public async Task Start()
    {
        var position = await _checkpointStore.GetCheckpoint();

        _subscription = _isAllStream
            ? await _client.SubscribeToAllAsync(
            GetAllStreamPosition(),
            EventAppeared,
            subscriptionDropped : SubscriptionDropped)
            : await _client.SubscribeToStreamAsync(
            _streamName,
            GetStreamPosition(),
            EventAppeared
            );

        FromAll GetAllStreamPosition()
        => position.HasValue
                ? FromAll.After(new Position(position.Value, position.Value))
                : FromAll.Start;

        FromStream GetStreamPosition()
        => position.HasValue
                ? FromStream.After(position.Value)
                : FromStream.Start;
    }
예제 #6
0
        private static async Task SubscribeToAll(EventStoreClient client)
        {
            #region subscribe-to-all
            await client.SubscribeToAllAsync(
                async (subscription, evnt, cancellationToken) => {
                Console.WriteLine($"Received event {evnt.OriginalEventNumber}@{evnt.OriginalStreamId}");
                await HandleEvent(evnt);
            });

            #endregion subscribe-to-all

            #region subscribe-to-all-from-position
            await client.SubscribeToAllAsync(
                new Position(1056, 1056),
                EventAppeared);

            #endregion subscribe-to-all-from-position

            #region subscribe-to-all-live
            await client.SubscribeToAllAsync(
                Position.End,
                EventAppeared);

            #endregion subscribe-to-all-live

            #region subscribe-to-all-subscription-dropped

            var checkpoint = Position.Start;
            await client.SubscribeToAllAsync(
                checkpoint,
                eventAppeared : async(subscription, evnt, cancellationToken) => {
                await HandleEvent(evnt);
                checkpoint = evnt.OriginalPosition.Value;
            },
                subscriptionDropped : ((subscription, reason, exception) => {
                Console.WriteLine($"Subscription was dropped due to {reason}. {exception}");
                if (reason != SubscriptionDroppedReason.Disposed)
                {
                    // Resubscribe if the client didn't stop the subscription
                    Resubscribe(checkpoint);
                }
            }));

            #endregion subscribe-to-all-subscription-dropped
        }
예제 #7
0
        private static async Task OverridingUserCredentials(EventStoreClient client)
        {
            #region overriding-user-credentials
            await client.SubscribeToAllAsync(
                EventAppeared,
                userCredentials : new UserCredentials("admin", "changeit"));

            #endregion overriding-user-credentials
        }
        /// <summary>
        /// Start the subscription to EventStoreDB
        /// </summary>
        /// <param name="cancellationToken"></param>
        public async Task Start(CancellationToken cancellationToken)
        {
            var filter = new SubscriptionFilterOptions(EventTypeFilter.ExcludeSystemEvents());

            _subscription = await _client.SubscribeToAllAsync(Position.Start,
                                                              EventAppeared,
                                                              subscriptionDropped : SubscriptionDropped,
                                                              filterOptions : filter,
                                                              resolveLinkTos : true,
                                                              cancellationToken : cancellationToken);
        }
예제 #9
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();
            }

            var projectors = await ReadCheckpoints();

            var projector  = new CheckpointAwareProjector(_connectionFactory, _messageTypeMap, projectors);
            var checkpoint = projectors.Select(p => p.Checkpoint).Min();

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

                if (Interlocked.Increment(ref _retryCount) == 5)
                {
                    Log.Error(ex, "Subscription dropped: {reason}", reason);
                    return;
                }

                Log.Warning(ex, "Subscription dropped: {reason}; resubscribing...", reason);
                Interlocked.Exchange(ref _subscribed, 0);
                Task.Run(() => Subscribe(cancellationToken), cancellationToken);
            },
                                                                                          filterOptions: new SubscriptionFilterOptions(EventTypeFilter.ExcludeSystemEvents()),
                                                                                          userCredentials: new UserCredentials("admin", "changeit"),
                                                                                          cancellationToken: _stopped.Token));

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

            async ValueTask <Projector[]> ReadCheckpoints()
            {
                await using var connection = _connectionFactory();
                await connection.OpenAsync(cancellationToken);

                return(await Task.WhenAll(Array.ConvertAll(_projections,
                                                           async projection => new Projector(projection,
                                                                                             await projection.ReadCheckpoint(connection, cancellationToken)))));
            }
        }
예제 #10
0
 public async Task Start()
 {
     _subscription = _isAllStream
         ? await _client.SubscribeToAllAsync(
         FromAll.Start,
         EventAppeared)
         : await _client.SubscribeToStreamAsync(
         _streamName,
         FromStream.Start,
         EventAppeared
         );
 }
예제 #11
0
        public Task Start()
        {
            if (_started)
            {
                return(Task.CompletedTask);
            }

            _started = true;
            return(_client.SubscribeToAllAsync(
                       (_, evt, _) => HandleEvent(evt),
                       subscriptionDropped: HandleDrop
                       ));
        }
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _checkpoint = await _checkpointStore.GetLastCheckpoint(_checkpointId, cancellationToken);

            var position = _checkpoint.Position != null
                ? new Position((ulong)_checkpoint.Position.Value, (ulong)_checkpoint.Position.Value)
                : Position.Start;

            _subscription = await _eventStoreClient.SubscribeToAllAsync(
                position,
                Handler,
                cancellationToken : cancellationToken
                );
        }
예제 #13
0
        private static async Task SubscribeToFiltered(EventStoreClient client)
        {
            #region stream-prefix-filtered-subscription
            var prefixStreamFilter = new SubscriptionFilterOptions(StreamFilter.Prefix("test-", "other-"));
            await client.SubscribeToAllAsync(
                EventAppeared,
                filterOptions : prefixStreamFilter);

            #endregion stream-prefix-filtered-subscription

            #region stream-regex-filtered-subscription
            var regexStreamFilter = StreamFilter.RegularExpression(@"/invoice-\d\d\d/g");
            #endregion stream-regex-filtered-subscription
        }
예제 #14
0
        private static async Task ExcludeSystemEvents(EventStoreClient client)
        {
            #region exclude-system
            await client.SubscribeToAllAsync(Position.Start,
                                             (s, e, c) => {
                Console.WriteLine(
                    $"{e.Event.EventType} @ {e.Event.Position.PreparePosition}");
                return(Task.CompletedTask);
            },
                                             filterOptions : new SubscriptionFilterOptions(
                                                 EventTypeFilter.ExcludeSystemEvents())
                                             );

            #endregion exclude-system
        }
예제 #15
0
    async Task StartProjectionAsync(IProjection projection, CancellationToken ct)
    {
        var checkpoint = await GetPositionAsync(projection.GetType(), ct);

        if (checkpoint.HasValue)
        {
            await _eventStore.SubscribeToAllAsync(
                checkpoint.Value,
                EventAppeared(projection),
                false,
                ConnectionDropped(projection) !,
                cancellationToken : ct
                );
        }
        else
        {
            await _eventStore.SubscribeToAllAsync(
                EventAppeared(projection),
                false,
                ConnectionDropped(projection) !,
                cancellationToken : ct
                );
        }
    }
        public static async Task WhenFruitAdded()
        {
            await _client.SubscribeToAllAsync(Position.End,
                                              async (subscription, evnt, cancellationToken) =>
            {
                try
                {
                    dynamic e = evnt.Event.EventType switch
                    {
                        "AppleAddedEvent" => JsonConvert.DeserializeObject <AppleAddedEvent>(Encoding.UTF8.GetString(evnt.Event.Data.Span)),
                        "PearAddedEvent" => JsonConvert.DeserializeObject <PearAddedEvent>(Encoding.UTF8.GetString(evnt.Event.Data.Span)),
                        _ => null
                    };

                    Console.WriteLine($"{evnt.Event.EventNumber}");

                    await new SummonFruitCommandHandler().Handle(e.Id, e.Weight, e.FruitCondition, TypeOfFruit.Apple);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error in subscr. " + e.Message);
                }
            }, resolveLinkTos : true, filterOptions : new SubscriptionFilterOptions(EventTypeFilter.RegularExpression("AppleAddedEvent|PearAddedEvent")));
        }
 public async Task Subscribe(CancellationToken stoppingToken)
 {
     await _eventStoreClient.SubscribeToAllAsync(
         await _streamManager.GetPosition(),
         async (subscription, @event, cancellationToken) =>
     {
         _logger.LogInformation("EventAppeared at position: {arg2}", @event.OriginalPosition?.CommitPosition);
         await _streamHandler.Handle(@event.Event);
         await _streamManager.SetPosition(@event.Event.Position);
     },
         filterOptions : new SubscriptionFilterOptions(
             StreamFilter.Prefix("Identity")
             ),
         cancellationToken : stoppingToken
         );
 }
예제 #18
0
        private static async Task EventTypePrefix(EventStoreClient client)
        {
            #region event-type-prefix
            var filter = new SubscriptionFilterOptions(
                EventTypeFilter.Prefix("customer-"));
            #endregion event-type-prefix

            await client.SubscribeToAllAsync(Position.Start,
                                             (s, e, c) => {
                Console.WriteLine(
                    $"{e.Event.EventType} @ {e.Event.Position.PreparePosition}");
                return(Task.CompletedTask);
            },
                                             filterOptions : filter
                                             );
        }
예제 #19
0
        private static async Task EventTypeRegex(EventStoreClient client)
        {
            #region event-type-regex
            var filter = new SubscriptionFilterOptions(
                EventTypeFilter.RegularExpression("^user|^company"));
            #endregion event-type-regex

            await client.SubscribeToAllAsync(Position.Start,
                                             (s, e, c) => {
                Console.WriteLine(
                    $"{e.Event.EventType} @ {e.Event.Position.PreparePosition}");
                return(Task.CompletedTask);
            },
                                             filterOptions : filter
                                             );
        }
예제 #20
0
        private static async Task StreamRegex(EventStoreClient client)
        {
            #region stream-regex
            var filter = new SubscriptionFilterOptions(
                StreamFilter.RegularExpression("^account|^savings"));
            #endregion stream-regex

            await client.SubscribeToAllAsync(Position.Start,
                                             (s, e, c) => {
                Console.WriteLine(
                    $"{e.Event.EventType} @ {e.Event.Position.PreparePosition}");
                return(Task.CompletedTask);
            },
                                             filterOptions : filter
                                             );
        }
예제 #21
0
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            using (var scope = _serviceProvider.CreateScope())
            {
                _checkpoint = await scope.ServiceProvider.GetRequiredService <ICheckpointProvider>()
                              .GetCheckpoint(_checkpointId, cancellationToken);

                var position = _checkpoint.Position != null
                    ? new Position((ulong)_checkpoint.Position, (ulong)_checkpoint.Position)
                    : Position.Start;

                _subscription = await _eventStoreClient.SubscribeToAllAsync(
                    position,
                    HandleEvent,
                    cancellationToken : cancellationToken);
            }
        }
예제 #22
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 _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)
            {
                var type = _messageTypeMapper.Map(e.Event.EventType);

                if (type == null)
                {
                    return(Task.CompletedTask);
                }
                var message = JsonSerializer.Deserialize(
                    e.Event.Data.Span, type, TransactoSerializerOptions.Events);

                return(_projector.ProjectAsync(_target, Envelope.Create(message, e.OriginalEvent.Position), ct));
            }
        }
예제 #23
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();
            }

            var projections = await ReadCheckpoints();

            var projector  = new CheckpointAwareProjector(_streamStore, _messageTypeMap, projections);
            var checkpoint = projections.Select(x => x.checkpoint).Min();

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

                if (Interlocked.Increment(ref _retryCount) == 5)
                {
                    Log.Error(ex, "Subscription dropped: {reason}", reason);
                    return;
                }

                Log.Warning(ex, "Subscription dropped: {reason}; resubscribing...", reason);
                Interlocked.Exchange(ref _subscribed, 0);
                Task.Run(() => Subscribe(cancellationToken), cancellationToken);
            },
                                                                                          filterOptions: new SubscriptionFilterOptions(EventTypeFilter.ExcludeSystemEvents()),
                                                                                          userCredentials: new UserCredentials("admin", "changeit"),
                                                                                          cancellationToken: _stopped.Token));

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

            Task <(Projection <IStreamStore> projection, Position checkpoint)[]> ReadCheckpoints() =>
예제 #24
0
        static async Task Main()
        {
            using var client = new EventStoreClient(
                      EventStoreClientSettings.Create("esdb://*****:*****@ {e.Event.Position.PreparePosition}");
                return(Task.CompletedTask);
            },
                                             filterOptions : new SubscriptionFilterOptions(
                                                 EventTypeFilter.Prefix("some-"),
                                                 1,
                                                 (s, p, c) => {
                Console.WriteLine($"checkpoint taken at {p.PreparePosition}");
                return(Task.CompletedTask);
            })
                                             );

            Thread.Sleep(2000);

            for (var i = 0; i < 100; i++)
            {
                var eventData = new EventData(
                    Uuid.NewUuid(),
                    i % 2 == 0 ? "some-event" : "other-event",
                    Encoding.UTF8.GetBytes("{\"id\": \"1\" \"value\": \"some value\"}")
                    );

                await client.AppendToStreamAsync(
                    Guid.NewGuid().ToString("N"),
                    StreamRevision.None,
                    new List <EventData> {
                    eventData
                }
                    );
            }

            Console.ReadLine();
        }
예제 #25
0
        private static async Task CheckpointCallback(EventStoreClient client)
        {
            #region checkpoint
            var filter = new SubscriptionFilterOptions(
                EventTypeFilter.ExcludeSystemEvents(),
                checkpointReached: (s, p, c) =>
            {
                Console.WriteLine($"checkpoint taken at {p.PreparePosition}");
                return(Task.CompletedTask);
            });
            #endregion checkpoint

            await client.SubscribeToAllAsync(Position.Start,
                                             (s, e, c) => {
                Console.WriteLine(
                    $"{e.Event.EventType} @ {e.Event.Position.PreparePosition}");
                return(Task.CompletedTask);
            },
                                             filterOptions : filter
                                             );
        }
예제 #26
0
    protected override async ValueTask Subscribe(CancellationToken cancellationToken)
    {
        var filterOptions = new SubscriptionFilterOptions(
            Options.EventFilter ?? EventTypeFilter.ExcludeSystemEvents(),
            Options.CheckpointInterval,
            async(_, p, ct) => {
            // This doesn't allow to report tie time gap
            LastProcessed = new EventPosition(p.CommitPosition, DateTime.Now);
            await StoreCheckpoint(LastProcessed, ct).NoContext();
        }
            );

        var(_, position) = await GetCheckpoint(cancellationToken).NoContext();

        var fromAll = position == null ? FromAll.Start : FromAll.After(new Position(position.Value, position.Value));

        Subscription = await EventStoreClient.SubscribeToAllAsync(
            fromAll,
            HandleEvent,
            Options.ResolveLinkTos,
            HandleDrop,
            filterOptions,
            Options.Credentials,
            cancellationToken
            ).NoContext();

        async Task HandleEvent(
            global::EventStore.Client.StreamSubscription _,
            ResolvedEvent re,
            CancellationToken ct
            )
        => await HandleInternal(CreateContext(re, ct)).NoContext();

        void HandleDrop(
            global::EventStore.Client.StreamSubscription _,
            SubscriptionDroppedReason reason,
            Exception?ex
            )
        => Dropped(EsdbMappings.AsDropReason(reason), ex);
    }
예제 #27
0
        protected override async Task <EventSubscription> Subscribe(
            Checkpoint checkpoint,
            CancellationToken cancellationToken
            )
        {
            var filterOptions = new SubscriptionFilterOptions(
                _eventFilter,
                10,
                (_, p, ct) => StoreCheckpoint(new EventPosition(p.CommitPosition, DateTime.Now), ct)
                );

            var subTask = checkpoint.Position != null
                ? EventStoreClient.SubscribeToAllAsync(
                new Position(checkpoint.Position.Value, checkpoint.Position.Value),
                HandleEvent,
                false,
                HandleDrop,
                filterOptions,
                _options.ConfigureOperation,
                _options.Credentials,
                cancellationToken
                )
                : EventStoreClient.SubscribeToAllAsync(
                HandleEvent,
                false,
                HandleDrop,
                filterOptions,
                _options.ConfigureOperation,
                _options.Credentials,
                cancellationToken
                );

            var sub = await subTask.Ignore();

            return(new EventSubscription(SubscriptionId, new Stoppable(() => sub.Dispose())));

            Task HandleEvent(EventStore.Client.StreamSubscription _, ResolvedEvent re, CancellationToken ct)
            => Handler(AsReceivedEvent(re), ct);

            void HandleDrop(EventStore.Client.StreamSubscription _, SubscriptionDroppedReason reason, Exception?ex)
            => Dropped(EsdbMappings.AsDropReason(reason), ex);

            ReceivedEvent AsReceivedEvent(ResolvedEvent re)
            {
                var evt = DeserializeData(
                    re.Event.ContentType,
                    re.Event.EventType,
                    re.Event.Data,
                    re.Event.EventStreamId,
                    re.Event.EventNumber
                    );

                return(new ReceivedEvent(
                           re.Event.EventId.ToString(),
                           re.Event.EventType,
                           re.Event.ContentType,
                           re.Event.Position.CommitPosition,
                           re.Event.Position.CommitPosition,
                           re.OriginalStreamId,
                           re.Event.EventNumber,
                           re.Event.Created,
                           evt
                           // re.Event.Metadata
                           ));
            }
        }
예제 #28
0
    private static async Task <bool> TestHang(int index)
    {
        const int batchSize = 36;
        const int batches   = 40;

        var data       = Encoding.UTF8.GetBytes("{}");
        var complete   = new TaskCompletionSource <bool>();
        var streamName = $"eventstore-tests-hang-{index}-{Guid.NewGuid():n}";

        var settings = EventStoreClientSettings.Create("esdb://localhost:2113?tls=false");
//		settings.LoggerFactory = new SerilogLoggerFactory();

        var client = new EventStoreClient(settings);

        using var subscription = client.SubscribeToAllAsync(
                  Position.End, EventAppeared, subscriptionDropped: SubscriptionDropped);

        await Task.Delay(10);

        await client.AppendToStreamAsync(streamName, StreamState.NoStream,
                                         new[] { new EventData(Uuid.NewUuid(), "start", data) });

        var lastStreamRevision = new StreamRevision(0);

        for (var i = 0; i < batches; i++)
        {
            const int firstSliceCount = 10;
            await client.AppendToStreamAsync(streamName, lastStreamRevision,
                                             Enumerable.Range(0, firstSliceCount)
                                             .Select(_ => new EventData(Uuid.NewUuid(), "event", data)));

            await client.AppendToStreamAsync(streamName, lastStreamRevision + firstSliceCount,
                                             Enumerable.Range(0, batchSize - firstSliceCount)
                                             .Select(_ => new EventData(Uuid.NewUuid(), "event", data)));

            lastStreamRevision += batchSize;
        }

        await client.AppendToStreamAsync(streamName, lastStreamRevision,
                                         new[] { new EventData(Uuid.NewUuid(), "complete", data) });

        return(await complete.Task);

        Task EventAppeared(StreamSubscription _, ResolvedEvent e, CancellationToken ct)
        {
            if (e.OriginalStreamId != streamName)
            {
                return(Task.CompletedTask);
            }

            if (e.OriginalEvent.EventType != "complete")
            {
                return(Task.Delay(TimeSpan.FromMilliseconds(0.8), ct));
            }

            complete.TrySetResult(true);
            return(Task.CompletedTask);
        }

        void SubscriptionDropped(StreamSubscription subscription, SubscriptionDroppedReason reason,
                                 Exception?ex)
        {
            if (ex != null)
            {
                Log.Warning(ex, "Subscription {subscriptionId} dropped: {reason}", subscription.SubscriptionId,
                            reason);
            }
            else
            {
                Log.Warning("Subscription {subscriptionId} dropped: {reason}", subscription.SubscriptionId, reason);
            }

            complete.TrySetResult(false);
        }
    }
예제 #29
0
        public async Task SubscribeClient()
        {
            await _client.SubscribeToAllAsync(HandleNewEvent);

            _logger.LogInformation("Subscribed to events.");
        }
예제 #30
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);
            }
        }