private async Task <IStatefulProjection> CreateParallelGroup() { var host = await ParallelGroupHelper.CreateObservableParallelGroup( async() => { await RavenCheckpointGroup.LoadCheckpoints(SessionFactory, Observer, new[] { "main" }) .ConfigureAwait(false); _writeLine("Loaded checkpoints"); return(new Dictionary <string, IStatefulProjection> { { "main", RavenCheckpointGroup.Wrap(Observer, "main", new DelegateProjection((e, ct) => Handle(e))) } }); }, Observer, () => { _writeLine("Restarting subscription"); Subscription.Restart(); } ).ConfigureAwait(false); _writeLine("Created parallel host"); return(new StatefulProjectionBuilder(host) .Use(commitMidfunc: downstream => async ct => { _writeLine("Downstream commit"); await downstream(ct).ConfigureAwait(false); _writeLine("Going to commit checkpoints"); await RavenCheckpointGroup.CommitActiveCheckpoints(SessionFactory, Observer, ct) .ConfigureAwait(false); }) .UseCommitEvery(maxBatchSize: 100) .Build()); }
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); }