private IReadOnlyDictionary <string, IStatefulProjection> CreateParallelGroup( SearchProjector <string, SearchDocument> searchProjector) => new Dictionary <string, IStatefulProjection> { { "main", WrapLocalProjection("main", ProjectionHelpers.Combine( ProjectionHelpers.Bind( () => CachingRepositoryHelper.CreateSession(Repository, searchProjector), repo => ProjectionHelpers.Bind( () => CachingRepositoryHelper.CreateSession(ParentLookup), parentLookup => (message, ct) => { Handle(repo, parentLookup, message); return(Task.CompletedTask); } ) ), (message) => _writeLine($"Projected {message.Checkpoint}: {message.Payload?.GetType().Name}"), () => { searchProjector.Commit(); _writeLine($"Committed"); } )) } };
public Fixture(Action <string> writeLine) { _writeLine = writeLine ?? (_ => {}); _baseDirectory = Path.Combine(Path.GetTempPath(), "local_projections", Guid.NewGuid().ToString("N")); Directory.CreateDirectory(_baseDirectory); EventStore = new SimpleEventStore(_baseDirectory); CheckpointsGroup = new LocalCheckpointGroup(Path.Combine(_baseDirectory, "checkpoint")); var searchDir = Path.Combine(_baseDirectory, "search"); Directory.CreateDirectory(searchDir); Index = new Index(searchDir, new[] { new Field("name"), new Field("value", true), new Field("parent"), new Field("child"), }); IEnumerable <P> ExtractDocument(string key, SearchDocument doc) { _writeLine($"Extracting {doc.Name}"); yield return(new P("name", doc.Name)); yield return(new P("value", doc.Value)); foreach (var c in doc.Children ?? new string[0]) { yield return(new P("child", c)); } foreach (var p in doc.Parents ?? new string[0]) { yield return(new P("parent", p)); } } var searchProjector = new SearchProjector <string, SearchDocument>( Index, "name", ExtractDocument, d => d.Value != null); var mainProjectionDir = Path.Combine(_baseDirectory, "main"); Directory.CreateDirectory(mainProjectionDir); Repository = new ObjectRepository <string, SearchDocument>( new DefaultObjectRepositorySettings <SearchDocument>(mainProjectionDir)); var parentLookupDir = Path.Combine(_baseDirectory, "parent_lookup"); Directory.CreateDirectory(parentLookupDir); ParentLookup = new ObjectRepository <string, List <string> >( new DefaultObjectRepositorySettings <List <string> >(parentLookupDir)); Notifier = new PollingNotifier(EventStore.ReadHead, (ex, p) => { _writeLine($"Error reading head ({p}): {ex}"); return(Task.CompletedTask); }); Subscription = new RecoverableSubscriptionAdapter( CreateSubscription, () => ParallelGroupHelper.CreateObservableParallelGroup( () => Task.FromResult(CreateParallelGroup(searchProjector)), Observer, () => Subscription.Restart()), () => Observer.Min); }