Example #1
0
        public void BuildIndexFromGraphs(CloudTableClient cloudTableClient)
        {
            //Let the background thread claim the wait handle.
            ThreadPool.QueueUserWorkItem(
                state =>
                    {
                        var registeredGraphs = registeredIndexer.GraphsIndexed;
                        var session = new InternalSession(registeredIndexer.Registry, backingStore);

                        //We use the session to manage to loading and deserialisation of graphs that contribute to the index...
                        session
                            .GetEntireStash()
                            .Matching(
                                _ =>
                                _.Where<StashTypeHierarchy>().AnyOf(registeredGraphs.Select(rg => StashTypeHierarchy.GetConcreteTypeValue(rg.GraphType))))
                            .Materialize();

                        //...but we then use the enrolled persistence events directly to yield the keys for this new index.
                        var graphProjections =
                            session
                                .EnrolledPersistenceEvents
                                .SelectMany(
                                    trackedGraph => registeredIndexer.GetUntypedProjections(trackedGraph.UntypedGraph),
                                    (graph, projection) => new {Projection = (ProjectedIndex)projection, graph.InternalId});

                        backingStore.InTransactionDo(
                            work =>
                                {
                                    foreach(var projection in graphProjections)
                                    {
                                        try
                                        {
                                            Insert(projection.Projection.UntypedKey, projection.InternalId, ((AzureStorageWork)work).ServiceContext);
                                        }
                                        catch(InvalidOperationException ioEx)
                                        {
                                            var storageEx = ioEx.TranslateDataServiceClientException();
                                            if (storageEx.ExtendedErrorInformation.ErrorCode != TableErrorCodeStrings.EntityAlreadyExists)
                                                throw storageEx;
                                            //This is acceptable, as it is possible for another session to insert the key
                                            //before we match it. We carry on.
                                        }
                                    }
                                });

                        session.Abandon();

                        indexCompiled.Set();
                    });
        }