예제 #1
0
        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);
        }
예제 #2
0
 public TenantSliceRange(DocumentStore store, AggregationRuntime <TDoc, TId> runtime, EventRange range,
                         IReadOnlyList <TenantSliceGroup <TDoc, TId> > groups, CancellationToken projectionCancellation) : base(range, projectionCancellation)
 {
     _store   = store;
     _runtime = runtime;
     Groups   = groups;
 }
예제 #3
0
        internal void Start(IShardAgent shardAgent, ActionBlock <IStorageOperation> queue,
                            AggregationRuntime <TDoc, TId> runtime,
                            IDocumentStore store, EventRangeGroup parent)
        {
            _builder = new TransformBlock <EventSlice <TDoc, TId>, IStorageOperation>(async slice =>
            {
                if (parent.Cancellation.IsCancellationRequested)
                {
                    return(null);
                }

                IStorageOperation operation = null;

                await shardAgent.TryAction(async() =>
                {
                    using var session = (DocumentSessionBase)store.LightweightSession(slice.Tenant.TenantId);

                    operation = await runtime.DetermineOperation(session, slice, parent.Cancellation, ProjectionLifecycle.Async);
                }, parent.Cancellation, group: parent, logException: (l, e) =>
                {
                    l.LogError(e, "Failure trying to build a storage operation to update {DocumentType} with {Id}", typeof(TDoc).FullNameInCode(), slice.Id);
                }, actionMode: GroupActionMode.Child);

                return(operation);
            }, new ExecutionDataflowBlockOptions
            {
                CancellationToken = parent.Cancellation,
            });

            _builder.LinkTo(queue, x => x != null);

            _application = Task.Factory.StartNew(() =>
                                                 processEventSlices(shardAgent, runtime, store, parent.Cancellation)
                                                 , parent.Cancellation);
        }
예제 #4
0
 public AggregationShard(ShardName identifier, ISqlFragment[] eventFilters,
                         AggregationRuntime <TDoc, TId> runtime, DocumentStore store, AsyncOptions options) : base(identifier,
                                                                                                                   eventFilters, store, options)
 {
     _runtime = runtime;
     _tenancy = store.Tenancy;
 }
예제 #5
0
        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);
            }
        }
예제 #6
0
 public AggregationShard(string projectionOrShardName, ISqlFragment[] eventFilters,
                         AggregationRuntime <TDoc, TId> runtime, DocumentStore store, AsyncOptions options) : base(projectionOrShardName, eventFilters, store, options)
 {
     _runtime = runtime;
     _tenancy = store.Tenancy;
 }
예제 #7
0
        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);
        }