/// <summary> /// Runs the health check, returning the status of the component being checked. /// </summary> /// <param name="context">A context object associated with the current execution.</param> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> that can be used to cancel the health check.</param> /// <returns> /// A <see cref="T:System.Threading.Tasks.Task`1" /> that completes when the health check has finished, yielding the status of the component being checked. /// </returns> /// <exception cref="Exception">$all stream not found</exception> public async Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { try { EventStoreClient client = new EventStoreClient(this.EventStoreClientSettings); EventStoreClient.ReadStreamResult readResult = client.ReadStreamAsync(Direction.Forwards, "$all", StreamPosition.Start, userCredentials: this.UserCredentials, resolveLinkTos: true, cancellationToken: cancellationToken); ReadState readState = await readResult.ReadState; if (readState == ReadState.StreamNotFound) { throw new Exception("$all stream not found"); } return(HealthCheckResult.Healthy()); } catch (Exception ex) { return(new HealthCheckResult(context.Registration.FailureStatus, exception: ex)); } }
private async Task <TAggregate> GetByIdOrDefaultAsync <TAggregate>(string aggregateId, int version) where TAggregate : class, IAggregateRoot, new() { if (version <= 0) { throw new InvalidOperationException("Cannot get version <= 0"); } var streamName = $"{typeof(TAggregate).Name}:{aggregateId}"; TAggregate aggregate = new TAggregate { Version = -1 }; RedisValue value = await Policies.RedisValueFallbackPolicy.ExecuteAsync(() => _cache.StringGetAsync(streamName)); if (value.HasValue) { aggregate = JsonSerializer.Deserialize <TAggregate>(value); } long sliceStart = aggregate.Version + 1; EventStoreClient.ReadStreamResult stream = _eventStoreClient.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.FromInt64(sliceStart)); if (await stream.ReadState == ReadState.StreamNotFound) { return(null); } await foreach (var @event in stream) { object eventObject = DeserializeEvent(@event.Event.Metadata, @event.Event.Data); Type applyType = typeof(IApply <>).MakeGenericType(eventObject.GetType()); var isAssignableFrom = applyType.IsAssignableFrom(aggregate.GetType()); if (isAssignableFrom) { ((dynamic)aggregate).Apply((dynamic)eventObject); } aggregate.Version++; } aggregate.Context = _context; return(aggregate); }
/// <summary> /// Gets the events backwards asynchronous. /// </summary> /// <param name="streamName">Name of the stream.</param> /// <param name="maxNumberOfEventsToRetrieve">The maximum number of events to retrieve.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns></returns> public async Task <IList <ResolvedEvent> > GetEventsBackwardAsync(String streamName, Int32 maxNumberOfEventsToRetrieve, CancellationToken cancellationToken) { List <ResolvedEvent> resolvedEvents = new(); EventStoreClient.ReadStreamResult response = this.EventStoreClient.ReadStreamAsync(Direction.Backwards, streamName, StreamPosition.End, maxNumberOfEventsToRetrieve, resolveLinkTos: true, cancellationToken: cancellationToken); if (await response.ReadState == ReadState.StreamNotFound) { return(resolvedEvents); } List <ResolvedEvent> events = await response.ToListAsync(cancellationToken); resolvedEvents.AddRange(events); return(resolvedEvents); }