Ejemplo n.º 1
0
        public async Task <IEventStream> GetStream <T>(string bucket, Id streamId, IEnumerable <Id> parents = null) where T : class, IEventSource
        {
            parents = parents ?? new Id[] { };

            var streamName = _streamGen(typeof(T), StreamTypes.Domain, bucket, streamId, parents);

            Logger.Write(LogLevel.Debug, () => $"Retreiving stream [{streamId}] in bucket [{bucket}] for type {typeof(T).FullName}");

            var cached = _cache.Retreive(streamName) as IImmutableEventStream;

            if (cached != null)
            {
                HitMeter.Mark();
                Logger.Write(LogLevel.Debug, () => $"Found stream [{streamName}] in cache");
                return(new EventStream <T>(cached));
            }
            MissMeter.Mark();


            while (await CheckFrozen <T>(bucket, streamId, parents).ConfigureAwait(false))
            {
                Logger.Write(LogLevel.Info, () => $"Stream [{streamId}] in bucket [{bucket}] is frozen - waiting");
                await Task.Delay(100).ConfigureAwait(false);
            }
            Logger.Write(LogLevel.Debug, () => $"Stream [{streamId}] in bucket [{bucket}] not in cache - reading from store");

            ISnapshot snapshot = null;

            if (typeof(ISnapshotting).IsAssignableFrom(typeof(T)))
            {
                snapshot = await _snapstore.GetSnapshot <T>(bucket, streamId, parents).ConfigureAwait(false);

                Logger.Write(LogLevel.Debug, () =>
                {
                    if (snapshot != null)
                    {
                        return($"Retreived snapshot for entity id [{streamId}] bucket [{bucket}] version {snapshot.Version}");
                    }
                    return($"No snapshot found for entity id [{streamId}] bucket [{bucket}]");
                });
            }

            var events = await _store.GetEvents(streamName, start : snapshot?.Version + 1).ConfigureAwait(false);

            var oobMetadata = await _store.GetMetadata(streamName, OobMetadataKey).ConfigureAwait(false);

            IEnumerable <OobDefinition> oobs = null;

            if (!string.IsNullOrEmpty(oobMetadata))
            {
                oobs = JsonConvert.DeserializeObject <IEnumerable <OobDefinition> >(oobMetadata);
            }

            var eventstream = new EventStream <T>(bucket, streamId, parents, oobs, events, snapshot);

            _cache.Cache(streamName, eventstream.Clone());

            Logger.Write(LogLevel.Debug, () => $"Stream [{streamId}] in bucket [{bucket}] read - version is {eventstream.CommitVersion}");
            return(eventstream);
        }