コード例 #1
0
ファイル: Observer.cs プロジェクト: jinaga/jinaga.net
        public async Task FactsAdded(ImmutableList <Fact> added, FactGraph graph, CancellationToken cancellationToken)
        {
            if (initialize == null)
            {
                return;
            }
            await initialize;

            var productsAdded   = ImmutableList <(Product product, Inverse inverse)> .Empty;
            var productsRemoved = ImmutableList <Product> .Empty;
            var startReferences = added.Select(a => a.Reference).ToImmutableList();

            foreach (var inverse in inverses)
            {
                var inversePipeline    = inverse.InversePipeline;
                var matchingReferences = startReferences
                                         .Where(r => inversePipeline.Starts.Any(start => r.Type == start.Type))
                                         .ToImmutableList();
                if (matchingReferences.Any())
                {
                    var products = inversePipeline.CanRunOnGraph
                        ? inversePipeline.Execute(startReferences, graph)
                        : await factManager.Query(
                        startReferences,
                        new Specification(inversePipeline, specification.Projection),
                        cancellationToken);

                    foreach (var product in products)
                    {
                        var initialProduct     = inverse.InitialSubset.Of(product);
                        var identifyingProduct = inverse.FinalSubset.Of(product);
                        if (initialProduct.Equals(this.initialAnchor))
                        {
                            if (inverse.Operation == Operation.Add)
                            {
                                productsAdded = productsAdded.Add((identifyingProduct, inverse));
                            }
                            else if (inverse.Operation == Operation.Remove)
                            {
                                productsRemoved = productsRemoved.Add(identifyingProduct);
                            }
                        }
                    }
                }
            }
            if (productsAdded.Any())
            {
                var products   = productsAdded.Select(p => p.product).ToImmutableList();
                var addedGraph = await factManager.LoadProducts(products, cancellationToken);

                var productAnchorProjections = DeserializeAllProducts(graph, productsAdded);
                var removals = await observation.NotifyAdded(productAnchorProjections);

                lock (this)
                {
                    removalsByProduct = removalsByProduct.AddRange(removals);
                }
            }
            if (productsRemoved.Any())
            {
                var removals = productsRemoved
                               .Select(product => removalsByProduct.GetValueOrDefault(product) !)
                               .Where(identity => identity != null)
                               .ToImmutableList();
                foreach (var removal in removals)
                {
                    await removal();
                }
                lock (this)
                {
                    removalsByProduct = removalsByProduct.RemoveRange(productsRemoved);
                }
            }
        }