ProjectionStream LoadProjectionStream(Type projectionType, ProjectionVersion projectionVersion, IBlobId projectionId, ISnapshot snapshot) { if (ReferenceEquals(null, projectionVersion)) { throw new ArgumentNullException(nameof(projectionVersion)); } if (ReferenceEquals(null, projectionId)) { throw new ArgumentNullException(nameof(projectionId)); } if (ReferenceEquals(null, snapshot)) { throw new ArgumentNullException(nameof(snapshot)); } ISnapshot currentSnapshot = snapshot; string contractId = projectionVersion.ProjectionName; List <ProjectionCommit> projectionCommits = new List <ProjectionCommit>(); int snapshotMarker = snapshot.Revision; while (true) { snapshotMarker++; var loadedCommits = projectionStore.Load(projectionVersion, projectionId, snapshotMarker).ToList(); projectionCommits.AddRange(loadedCommits); bool isSnapshotable = typeof(IAmNotSnapshotable).IsAssignableFrom(projectionType) == false; if (isSnapshotable && snapshotStrategy.ShouldCreateSnapshot(projectionCommits, snapshot.Revision)) { ProjectionStream checkpointStream = new ProjectionStream(projectionId, projectionCommits, currentSnapshot); var projectionState = checkpointStream.RestoreFromHistory(projectionType).Projection.State; ISnapshot newSnapshot = new Snapshot(projectionId, contractId, projectionState, snapshot.Revision + 1); snapshotStore.Save(newSnapshot, projectionVersion); currentSnapshot = newSnapshot; projectionCommits.Clear(); log.Debug(() => $"Snapshot created for projection `{contractId}` with id={projectionId} where ({loadedCommits.Count}) were zipped. Snapshot: `{snapshot.GetType().Name}`"); } else if (loadedCommits.Count() < snapshotStrategy.EventsInSnapshot) { break; } else { log.Warn($"Potential memory leak. The system will be down fairly soon. The projection `{contractId}` with id={projectionId} loads a lot of projection commits ({loadedCommits.Count}) and snapshot `{snapshot.GetType().Name}` which puts a lot of CPU and RAM pressure. You can resolve this by configuring the snapshot settings`."); } } ProjectionStream stream = new ProjectionStream(projectionId, projectionCommits, currentSnapshot); return(stream); }
ProjectionStream LoadProjectionStream(Type projectionType, ProjectionVersion version, IBlobId projectionId, ISnapshot snapshot) { Func <ISnapshot> loadSnapshot = () => snapshot; List <ProjectionCommit> projectionCommits = new List <ProjectionCommit>(); int snapshotMarker = snapshot.Revision; while (true) { snapshotMarker++; var loadedCommits = projectionStore.Load(version, projectionId, snapshotMarker).ToList(); projectionCommits.AddRange(loadedCommits); if (projectionType.IsSnapshotable() && snapshotStrategy.ShouldCreateSnapshot(projectionCommits, snapshot.Revision)) { ProjectionStream checkpointStream = new ProjectionStream(projectionId, projectionCommits, loadSnapshot); var projectionState = checkpointStream.RestoreFromHistory(projectionType).State; ISnapshot newSnapshot = new Snapshot(projectionId, version.ProjectionName, projectionState, snapshot.Revision + 1); snapshotStore.Save(newSnapshot, version); loadSnapshot = () => newSnapshot; projectionCommits.Clear(); log.Debug(() => $"Snapshot created for projection `{version.ProjectionName}` with id={projectionId} where ({loadedCommits.Count}) were zipped. Snapshot: `{snapshot.GetType().Name}`"); } if (loadedCommits.Count < snapshotStrategy.EventsInSnapshot) { break; } if (loadedCommits.Count > snapshotStrategy.EventsInSnapshot * 1.5) { log.Warn(() => $"Potential memory leak. The system will be down fairly soon. The projection `{version.ProjectionName}` with id={projectionId} loads a lot of projection commits ({loadedCommits.Count}) and snapshot `{snapshot.GetType().Name}` which puts a lot of CPU and RAM pressure. You can resolve this by configuring the snapshot settings`."); } } ProjectionStream stream = new ProjectionStream(projectionId, projectionCommits, loadSnapshot); return(stream); }
ProjectionStream LoadProjectionStream(Type projectionType, ProjectionVersion projectionVersion, IBlobId projectionId, ISnapshot snapshot) { ISnapshot currentSnapshot = snapshot; string contractId = projectionVersion.ProjectionContractId; List <ProjectionCommit> projectionCommits = new List <ProjectionCommit>(); int snapshotMarker = snapshot.Revision; while (true) { snapshotMarker++; var loadedCommits = projectionStore.Load(projectionVersion, projectionId, snapshotMarker).ToList(); if (loadedCommits.Count > 1000) { log.Warn($"Potential memory leak. The system will be down fairly soon. The projection `{contractId}` for id={projectionId} loads a lot of projection commits ({loadedCommits.Count}) and snapshot `{snapshot.GetType().Name}` which puts a lot of CPU and RAM pressure. You can resolve this by enabling the Snapshots feature in the host which handles projection WRITES and READS using `.UseSnapshots(...)`."); } projectionCommits.AddRange(loadedCommits); bool isSnapshotable = typeof(IAmNotSnapshotable).IsAssignableFrom(projectionType) == false; if (isSnapshotable && snapshotStrategy.ShouldCreateSnapshot(projectionCommits, snapshot.Revision)) { ProjectionStream checkpointStream = new ProjectionStream(projectionId, projectionCommits, currentSnapshot); var projectionState = checkpointStream.RestoreFromHistory(projectionType).Projection.State; ISnapshot newSnapshot = new Snapshot(projectionId, contractId, projectionState, snapshot.Revision + 1); snapshotStore.Save(newSnapshot, projectionVersion); currentSnapshot = newSnapshot; projectionCommits.Clear(); } else if (loadedCommits.Count() < snapshotStrategy.EventsInSnapshot) { break; } } ProjectionStream stream = new ProjectionStream(projectionId, projectionCommits, currentSnapshot); return(stream); }