internal void Start(ActionBlock <IStorageOperation> queue, AggregationRuntime <TDoc, TId> runtime, IDocumentStore store, CancellationToken token) { _session = (DocumentSessionBase)store.LightweightSession(Tenant.TenantId); _builder = new TransformBlock <EventSlice <TDoc, TId>, IStorageOperation>(slice => { try { return(runtime.DetermineOperation(_session, slice, token)); } catch (Exception e) { Debug.WriteLine(e); throw; } }, new ExecutionDataflowBlockOptions { CancellationToken = token }); _builder.LinkTo(queue); _application = Task.Factory.StartNew(async() => { var beingFetched = new List <EventSlice <TDoc, TId> >(); foreach (var slice in Slices) { if (runtime.Projection.MatchesAnyDeleteType(slice)) { var deletion = runtime.Storage.DeleteForId(slice.Id, Tenant); queue.Post(deletion); } else if (runtime.IsNew(slice)) { _builder.Post(slice); } else { beingFetched.Add(slice); } } var ids = beingFetched.Select(x => x.Id).ToArray(); var aggregates = await runtime.Storage .LoadManyAsync(ids, _session, token); var dict = aggregates.ToDictionary(x => runtime.Storage.Identity(x)); foreach (var slice in Slices) { if (dict.TryGetValue(slice.Id, out var aggregate)) { slice.Aggregate = aggregate; } _builder.Post(slice); } }, token); }
private async Task processEventSlices(IShardAgent shardAgent, AggregationRuntime <TDoc, TId> runtime, IDocumentStore store, CancellationToken token) { var beingFetched = new List <EventSlice <TDoc, TId> >(); foreach (var slice in Slices) { if (token.IsCancellationRequested) { _builder.Complete(); break; } if (runtime.IsNew(slice)) { _builder.Post(slice); } else { beingFetched.Add(slice); } } if (token.IsCancellationRequested) { return; } var ids = beingFetched.Select(x => x.Id).ToArray(); IReadOnlyList <TDoc> aggregates = null; await shardAgent.TryAction(async() => { using (var session = (IMartenSession)store.LightweightSession(Tenant.TenantId)) { aggregates = await runtime.Storage .LoadManyAsync(ids, session, token); } }, token); if (token.IsCancellationRequested || aggregates == null) { return; } var dict = aggregates.ToDictionary(x => runtime.Storage.Identity(x)); foreach (var slice in Slices) { if (dict.TryGetValue(slice.Id, out var aggregate)) { slice.Aggregate = aggregate; } _builder.Post(slice); } }
internal void Start(ActionBlock <IStorageOperation> queue, AggregationRuntime <TDoc, TId> runtime, IDocumentStore store, CancellationToken token) { _builder = new TransformBlock <EventSlice <TDoc, TId>, IStorageOperation>(slice => { if (token.IsCancellationRequested) { return(null); } using var session = store.LightweightSession(slice.Tenant.TenantId); try { return(runtime.DetermineOperation((DocumentSessionBase)session, slice, token, ProjectionLifecycle.Async)); } catch (Exception e) { // TODO -- throw a specific error so you can capture the event information // to detect poison pill messages Debug.WriteLine(e); throw; } }, new ExecutionDataflowBlockOptions { CancellationToken = token, }); _builder.LinkTo(queue, x => x != null); _application = Task.Factory.StartNew(async() => { var beingFetched = new List <EventSlice <TDoc, TId> >(); foreach (var slice in Slices) { if (token.IsCancellationRequested) { _builder.Complete(); break; } if (runtime.IsNew(slice)) { _builder.Post(slice); } else { beingFetched.Add(slice); } } if (token.IsCancellationRequested) { return; } var ids = beingFetched.Select(x => x.Id).ToArray(); IReadOnlyList <TDoc> aggregates = null; using (var session = (IMartenSession)store.LightweightSession(Tenant.TenantId)) { aggregates = await runtime.Storage .LoadManyAsync(ids, session, token); } if (token.IsCancellationRequested) { return; } var dict = aggregates.ToDictionary(x => runtime.Storage.Identity(x)); foreach (var slice in Slices) { if (dict.TryGetValue(slice.Id, out var aggregate)) { slice.Aggregate = aggregate; } _builder.Post(slice); } }, token); }