//
        // Event data
        //

        internal static EventData GetAreaEventData(
            this EventStoreContext context,
            Event e,
            TimelinePosition cause,
            DateTimeOffset when,
            DateTimeOffset?whenOccurs,
            Id eventId,
            Id commandId,
            Id userId,
            FlowKey topic,
            Many <FlowKey> routes)
        {
            var type = context.GetEventType(e);

            var metadata = new AreaEventMetadata
            {
                Cause      = cause,
                When       = when,
                WhenOccurs = whenOccurs,
                CommandId  = commandId,
                UserId     = userId,
                Topic      = topic
            };

            metadata.ApplyRoutes(type, routes);

            return(new EventData(
                       eventId.IsUnassigned ? Guid.NewGuid() : Guid.Parse(eventId.ToString()),
                       type.ToString(),
                       isJson: true,
                       data: context.ToJson(e),
                       metadata: context.ToJson(metadata)));
        }
Пример #2
0
        internal async Task <TimelinePoint> WriteFromApp(Event e)
        {
            var eventType = _area.Events[e.GetType()];

            _queryType.ExpectObserves(eventType);

            _currentPosition = _currentPosition.Next();

            var point = new TimelinePoint(
                _currentPosition,
                TimelinePosition.None,
                eventType,
                e.When,
                Event.Traits.WhenOccurs.Get(e),
                Event.Traits.EventId.Get(e),
                Event.Traits.CommandId.Get(e),
                Event.Traits.UserId.Get(e),
                null,
                eventType.GetRoutes(e, Event.IsScheduled(e)).ToMany(),
                () => e);

            await _observer.OnNext(point);

            return(point);
        }
Пример #3
0
        bool TryGetImmediateGiven(Event e, TimelinePosition position, out FlowCall.Given given)
        {
            given = null;

            if (TryGetObservation(e, out var observation))
            {
                var routes = observation.EventType.GetRoutes(e).ToMany();

                if (routes.Contains(Key))
                {
                    var point = new TimelinePoint(
                        position,
                        Point.Position,
                        observation.EventType,
                        e.When,
                        Event.Traits.WhenOccurs.Get(e),
                        Event.Traits.EventId.Get(e),
                        Event.Traits.CommandId.Get(e),
                        Event.Traits.UserId.Get(e),
                        Key,
                        routes,
                        () => e);

                    given = new FlowCall.Given(point, observation);
                }
            }

            return(given != null);
        }
Пример #4
0
 public ResumeInfo(TimelinePosition checkpoint, Many <FlowKey> routes, Many <TimelinePoint> schedule, IConnectable subscription)
 {
     Checkpoint   = checkpoint;
     Routes       = routes;
     Schedule     = schedule;
     Subscription = subscription;
 }
Пример #5
0
 internal void OnAppended(TimelinePosition position)
 {
     lock (_updateLock)
     {
         _latestAppended = position;
     }
 }
Пример #6
0
        public async Task WriteCheckpoint(Flow flow)
        {
            var result = await _context.Connection.AppendToStreamAsync(
                flow.Context.Key.GetCheckpointStream(),
                ExpectedVersion.Any,
                _context.GetCheckpointEventData(flow));

            if (flow is Query query)
            {
                try
                {
                    var checkpoint = new TimelinePosition(result.NextExpectedVersion);
                    var etag       = QueryETag.From(query.Context.Key, checkpoint).ToString();

                    await _context.Connection.AppendToStreamAsync(
                        TimelineStreams.ChangedQueries,
                        ExpectedVersion.Any,
                        _context.GetQueryChangedEventData(new QueryChanged(etag)));
                }
                catch (Exception error)
                {
                    Log.Error(error, "Failed to write QueryChanged for {Query} - subscribers will not be aware of the change until the query observes another event.", query);
                }
            }
        }
Пример #7
0
        public async Task <QueryState> ReadState(QueryETag etag)
        {
            var stream = etag.Key.GetCheckpointStream();

            var result = await _context.Connection.ReadEventAsync(stream, StreamPosition.End, resolveLinkTos : false);

            switch (result.Status)
            {
            case EventReadStatus.NoStream:
            case EventReadStatus.NotFound:
                return(new QueryState(etag.WithoutCheckpoint(), GetDefaultData(etag)));

            case EventReadStatus.Success:
                var number = result.Event?.Event.EventNumber;
                var data   = result.Event?.Event.Data;

                var checkpoint = new TimelinePosition(number);

                return(checkpoint == etag.Checkpoint
            ? new QueryState(etag)
            : new QueryState(etag.WithCheckpoint(checkpoint), new MemoryStream(data)));

            default:
                throw new Exception($"Unexpected result when reading {stream}: {result.Status}");
            }
        }
Пример #8
0
        void BindFlow(TimelinePosition position)
        {
            _flow = ReadData();

            FlowContext.Bind(_flow, _key, position, TimelinePosition.None);

            _areaCheckpoint = position.ToInt64();
        }
Пример #9
0
        public async Task <TimelinePosition> WriteNewEvents(TimelinePosition cause, FlowKey topicKey, Many <Event> newEvents)
        {
            var data = _context.GetNewEventData(cause, topicKey, newEvents);

            var result = await _context.AppendToTimeline(data);

            return(new TimelinePosition(result.NextExpectedVersion - newEvents.Count + 1));
        }
        async Task WriteNewEvents()
        {
            // EventStore was not happy when the enumerator failed - eagerly evaluate the event data

            var result = await _context.Connection.AppendToStreamAsync(
                TimelineStreams.Timeline,
                ExpectedVersion.Any,
                _context.GetNewEventData(_cause, _topicKey, _newEvents).ToMany());

            _newPosition = new TimelinePosition(result.NextExpectedVersion - _newEvents.Count + 1);
        }
Пример #11
0
        internal void ResumeWith(Many <TimelinePoint> points)
        {
            HasPoint = points.Count > 0;

            foreach (var point in points)
            {
                _resumeQueue.Enqueue(point);

                _resumeCheckpoint = point.Position;
            }
        }
Пример #12
0
 public TimelineSubscription(
     EventStoreContext context,
     CatchUpSubscriptionSettings settings,
     TimelinePosition checkpoint,
     ITimelineObserver observer)
 {
     _context    = context;
     _settings   = settings;
     _checkpoint = checkpoint;
     _observer   = observer;
 }
Пример #13
0
        IEnumerable <FlowCall.Given> GetImmediateGivens(Many <Event> newEvents, TimelinePosition newPosition)
        {
            foreach (var e in newEvents)
            {
                if (TryGetImmediateGiven(e, newPosition, out var given))
                {
                    yield return(given);
                }

                newPosition = newPosition.Next();
            }
        }
Пример #14
0
        internal void OnChanged(TimelinePosition position)
        {
            lock (_updateLock)
            {
                _checkpoint = position;

                if (IsLatest)
                {
                    _latestWait?.OnOccurred();
                }
            }
        }
Пример #15
0
 private TimelinePosition ConvertTimelinePosition(TimelinePosition timelineMode)
 {
     if (TimelineOrientation == TimelineOrientation.Vertical)
     {
         return(timelineMode switch
         {
             TimelinePosition.Left => RightToLeft ? TimelinePosition.End : TimelinePosition.Start,
             TimelinePosition.Right => RightToLeft ? TimelinePosition.Start : TimelinePosition.End,
             TimelinePosition.Top => TimelinePosition.Alternate,
             TimelinePosition.Bottom => TimelinePosition.Alternate,
             _ => timelineMode
         });
        internal WriteNewEventsCommand(
            EventStoreContext context,
            TimelinePosition cause,
            FlowKey topicKey,
            Many <Event> newEvents)
        {
            _context   = context;
            _cause     = cause;
            _topicKey  = topicKey;
            _newEvents = newEvents;

            _newEventTypes = _newEvents.ToMany(e => _context.GetEventType(e));
        }
Пример #17
0
        void Resume(FlowResumeInfo.Loaded info)
        {
            Flow = (T)info.Flow;

            lock (_queue)
            {
                foreach (var point in info.Points)
                {
                    _resumeQueue.Enqueue(point);

                    _resumeCheckpoint = point.Position;
                }
            }
        }
        IEnumerable <FlowCall.Given> ReadImmediateGivenCalls()
        {
            for (var i = 0; i < _newEvents.Count; i++)
            {
                var e    = _newEvents[i];
                var type = _newEventTypes[i];

                if (TryReadImmediateGiven(e, type, out var call))
                {
                    yield return(call);
                }

                _newPosition = _newPosition.Next();
            }
        }
Пример #19
0
        QueryContent GetCheckpointContent(QueryETag etag, ResolvedEvent e)
        {
            var metadata = _context.ReadCheckpointMetadata(e);

            if (metadata.ErrorPosition.IsSome)
            {
                throw new Exception($"Query is stopped at {metadata.ErrorPosition} with the following error: {metadata.ErrorMessage}");
            }

            var checkpoint = new TimelinePosition(e.Event.EventNumber);

            return(checkpoint == etag.Checkpoint
        ? new QueryContent(etag)
        : new QueryContent(etag.WithCheckpoint(checkpoint), new MemoryStream(e.Event.Data)));
        }
        internal static IEnumerable <EventData> GetNewEventData(
            this EventStoreContext context,
            TimelinePosition cause,
            FlowKey topic,
            Many <Event> newEvents) =>

        from e in newEvents
        select context.GetAreaEventData(
            e,
            cause,
            e.When,
            Event.Traits.WhenOccurs.Get(e),
            Event.Traits.EventId.Get(e),
            Event.Traits.CommandId.Get(e),
            Event.Traits.UserId.Get(e),
            topic,
            context.GetEventType(e).GetRoutes(e).ToMany());
Пример #21
0
        public void TimelineTest_Position(TimelineOrientation orientation, TimelinePosition position, bool rtl, string[] expectedClass)
        {
            var comp = Context.RenderComponent <TimelineTest>(p => p.AddCascadingValue(rtl));
            //Console.WriteLine(comp.Markup);

            var timeline = comp.FindComponent <MudTimeline>();

            timeline.SetParametersAndRender(p =>
            {
                p.Add(x => x.TimelineOrientation, orientation);
                p.Add(x => x.TimelinePosition, position);
            });


            timeline.Nodes.Should().ContainSingle();
            timeline.Nodes[0].Should().BeAssignableTo <IHtmlDivElement>();

            (timeline.Nodes[0] as IHtmlDivElement).ClassList.Should().Contain(expectedClass);
        }
Пример #22
0
        public async Task <TimelinePosition> WriteNewEvents(TimelinePosition cause, FlowKey topicKey, Many <Event> newEvents)
        {
            foreach (var newEvent in newEvents)
            {
                var(copy, type) = CopyEvent(newEvent);

                await OnNext(new TimelinePoint(
                                 AdvancePosition(),
                                 cause,
                                 type,
                                 copy.When,
                                 Event.Traits.WhenOccurs.Get(copy),
                                 Event.Traits.EventId.Get(copy),
                                 Event.Traits.CommandId.Get(copy),
                                 Event.Traits.UserId.Get(copy),
                                 topicKey,
                                 type.GetRoutes(copy).ToMany(),
                                 () => copy));
            }

            return(new TimelinePosition(_currentPosition.ToInt64() - newEvents.Count));
        }
Пример #23
0
 public Task <ImmediateGivens> WriteNewEvents(TimelinePosition cause, FlowKey topicKey, Many <Event> newEvents) =>
 new WriteNewEventsCommand(_context, cause, topicKey, newEvents).Execute();
Пример #24
0
 public Task <TimelinePosition> WriteNewEvents(TimelinePosition cause, FlowKey topicKey, Many <Event> newEvents) =>
 throw new InvalidOperationException("New events do not occur during query tests");
Пример #25
0
 bool IsAfterCheckpoint(TimelinePosition position) =>
 (_resumeCheckpoint.IsNone || position > _resumeCheckpoint) &&
 (Flow == null || position > Flow.Context.CheckpointPosition);
Пример #26
0
 public Stopped(TimelinePosition position)
 {
     Position = position;
 }
Пример #27
0
 public Stopped(TimelinePosition position, string error)
 {
     Position = position;
     Error    = error;
 }
Пример #28
0
 public static QueryETag From(FlowKey key, TimelinePosition checkpoint) =>
 new QueryETag(key, checkpoint);
Пример #29
0
 public QueryETag WithCheckpoint(TimelinePosition checkpoint) =>
 new QueryETag(Key, checkpoint);
Пример #30
0
 QueryETag(FlowKey key, TimelinePosition checkpoint)
 {
     Key        = key;
     Checkpoint = checkpoint;
 }