Exemple #1
0
        public DIIgniteServers()
        {
            // Create a set of mocked configurations for caches the servers was want
            var mockedConfigs = new List <CacheConfiguration>
            {
                new CacheConfiguration(TRexCaches.MutableNonSpatialCacheName()),
                new CacheConfiguration(TRexCaches.SpatialSubGridDirectoryCacheName(StorageMutability.Mutable)),
                new CacheConfiguration(TRexCaches.SpatialSubGridDirectoryCacheName(StorageMutability.Immutable)),
                new CacheConfiguration(TRexCaches.SpatialSubGridSegmentCacheName(StorageMutability.Mutable)),
                new CacheConfiguration(TRexCaches.SpatialSubGridSegmentCacheName(StorageMutability.Immutable)),
                new CacheConfiguration(TRexCaches.ImmutableNonSpatialCacheName()),
                new CacheConfiguration(TRexCaches.SiteModelMetadataCacheName()),
                new CacheConfiguration(TRexCaches.DesignTopologyExistenceMapsCacheName()),
                new CacheConfiguration(TRexCaches.TAGFileBufferQueueCacheName()),
                new CacheConfiguration(TRexCaches.SegmentRetirementQueueCacheName()),
                new CacheConfiguration(TRexCaches.SiteModelChangeBufferQueueCacheName()),
                new CacheConfiguration(TRexCaches.ProductionDataExistenceMapCacheName(StorageMutability.Mutable)),
                new CacheConfiguration(TRexCaches.ProductionDataExistenceMapCacheName(StorageMutability.Mutable))
            };

            var igniteConfiguration = new IgniteConfiguration
            {
                CacheConfiguration = mockedConfigs
            };

            // Get the mocked Ignite instance and add the configuration to it
            IgniteMock.Immutable.mockIgnite.Setup(x => x.GetConfiguration()).Returns(igniteConfiguration);
            IgniteMock.Mutable.mockIgnite.Setup(x => x.GetConfiguration()).Returns(igniteConfiguration);
        }
Exemple #2
0
        /// <summary>
        /// Creates or obtains a reference to an already created change map file buffer queue
        /// </summary>
        private void InstantiateCache()
        {
            var ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Immutable) ??
                         Ignition.GetIgnite(TRexGrids.ImmutableGridName());

            _queueCache = ignite?.GetCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(
                TRexCaches.SiteModelChangeBufferQueueCacheName());

            if (_queueCache == null)
            {
                Log.LogInformation($"Failed to get Ignite cache {TRexCaches.SiteModelChangeBufferQueueCacheName()}");
                throw new TRexException("Ignite cache not available");
            }
        }
Exemple #3
0
        /// <summary>
        /// Create the cache that holds the per project, per machine, change maps driven by TAG file ingest
        /// Note: This machine based information is distinguished from that in the non-spatial cache in that
        /// it is partitioned, rather than replicated.
        /// </summary>
        private void InstantiateSiteModelChangeBufferQueueCacheReference()
        {
            immutableTRexGrid.GetOrCreateCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(new CacheConfiguration
            {
                Name = TRexCaches.SiteModelChangeBufferQueueCacheName(),
                KeepBinaryInStore = true,
                CacheMode         = CacheMode.Partitioned,

                // TODO: No backups for now
                Backups        = 0,
                DataRegionName = DataRegions.IMMUTABLE_NONSPATIAL_DATA_REGION,

                // Configure the function that maps the change maps to nodes in the grid
                // Note: This cache uses an affinity function that assigns data for a site model onto a single node.
                // For the purposes of the immutable grid, it is helpful for a node to contain all change maps for a single
                // site model as this simplifies the process of updating those change maps in response to messages from production data ingest
                AffinityFunction = new ProjectBasedSpatialAffinityFunction(),
            });
        }
Exemple #4
0
        /// <summary>
        /// Add the factories for the storage proxy caches, both standard and transacted, for spatial and non spatial caches in TRex
        /// </summary>
        private static void AddDIEntries()
        {
            DIBuilder.Continue()

            //***********************************************
            // Injected factories for non-transacted proxies
            // **********************************************

            // Add the singleton reference to the non-transacted site model change map cache
            .Add(x => x.AddSingleton <Func <IStorageProxyCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> > >(
                     () => new StorageProxyCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(DIContext.Obtain <ITRexGridFactory>()
                                                                                                                   .Grid(StorageMutability.Immutable)?
                                                                                                                   .GetCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(TRexCaches.SiteModelChangeBufferQueueCacheName())))
                 )

            //******************************************
            // Injected factories for transacted proxies
            // *****************************************

            // Add the singleton reference to the transacted site model change map cache
            .Add(x => x.AddSingleton <Func <IStorageProxyCacheTransacted <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> > >(
                     () => new StorageProxyCacheTransacted <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(DIContext.Obtain <ITRexGridFactory>()
                                                                                                                             .Grid(StorageMutability.Immutable)?
                                                                                                                             .GetCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(TRexCaches.SiteModelChangeBufferQueueCacheName()), new SiteModelChangeBufferQueueKeyEqualityComparer())
                     ));
        }
Exemple #5
0
        private void AddChangeMapQueueCacheToDI()
        {
            var transactedProxy = new StorageProxyCacheTransacted_TestHarness <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>
                                      (DIContext.Obtain <ITRexGridFactory>().Grid(StorageMutability.Immutable)?.GetCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(TRexCaches.SiteModelChangeBufferQueueCacheName()), new SiteModelChangeBufferQueueKeyEqualityComparer());

            var nonTransactedProxy = new StorageProxyCacheTransacted_TestHarness <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>
                                         (DIContext.Obtain <ITRexGridFactory>().Grid(StorageMutability.Immutable)?.GetCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(TRexCaches.SiteModelChangeBufferQueueCacheName()), new SiteModelChangeBufferQueueKeyEqualityComparer());

            DIBuilder
            .Continue()

            // Add the factories for the storage proxy caches, both standard and transacted, for spatial and non spatial caches in TRex

            ////////////////////////////////////////////////////
            // Injected standard storage proxy cache
            ////////////////////////////////////////////////////

            // Add the singleton reference to the non-transacted site model change map cache
            .Add(x => x.AddSingleton <Func <IStorageProxyCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> > >(() => nonTransactedProxy))

            /////////////////////////////////////////////////////
            // Injected transacted storage proxy cache factories
            /////////////////////////////////////////////////////

            // Add the singleton reference to the transacted site model change map cache
            .Add(x => x.AddSingleton <Func <IStorageProxyCacheTransacted <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> > >(() => transactedProxy))

            .Build()
            .Add(x => x.AddSingleton <ISiteModelChangeMapDeltaNotifier>(new SiteModelChangeMapDeltaNotifier()))

            .Build();
        }
Exemple #6
0
        /// <summary>
        /// Executes the life cycle of the service until it is aborted
        /// </summary>
        public void Execute(IServiceContext context)
        {
            try
            {
                if (_log == null)
                {
                    Console.WriteLine($"Error: Null logger present in {nameof(SiteModelChangeProcessorService)}.{nameof(Execute)}");
                }

                _log.LogInformation($"{context.Name} starting executing");
                Aborted     = false;
                _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);

                // Get the ignite grid and cache references

                var ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Immutable) ??
                             Ignition.GetIgnite(TRexGrids.ImmutableGridName());

                if (ignite == null)
                {
                    _log.LogError("Ignite reference in service is null - aborting service execution");
                    return;
                }

                // Don't start operations until the local (immutable) grid is confirmed as active
                DIContext.ObtainRequired <IActivatePersistentGridServer>().WaitUntilGridActive(TRexGrids.ImmutableGridName());

                // Once active, delay start of operations for a time to ensure everything is up and running
                var delay = DIContext.ObtainRequired <IConfigurationStore>().GetValueInt("TREX_SITE_MODEL_CHANGE_MAP_SERVICE_OPERATION_START_DELAY_SECONDS", 120);
                _log.LogInformation($"Delaying start of operations for {delay} seconds");
                Thread.Sleep(delay * 1000);

                _log.LogInformation("Obtaining queue cache reference");

                var queueCache = ignite.GetCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(TRexCaches.SiteModelChangeBufferQueueCacheName());

                _log.LogInformation($"Obtained queue cache for SiteModelChangeBufferQueueKey: {queueCache}");

                var handler  = new SiteModelChangeProcessorItemHandler();
                var listener = new LocalSiteModelChangeListener(handler);

                // Obtain the query handle for the continuous query from the DI context, or if not available create it directly
                // Construct the continuous query machinery
                // Set the initial query to return all elements in the cache
                // Instantiate the queryHandle and start the continuous query on the remote nodes
                // Note: Only cache items held on this local node will be handled here
                var queryHandleFactory = DIContext.Obtain <Func <LocalSiteModelChangeListener, IContinuousQueryHandle <ICacheEntry <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> > > >();

                if (queryHandleFactory != null)
                {
                    _log.LogInformation("Obtaining query handle from DI factory");
                    _queryHandle = queryHandleFactory(listener);
                }

                while (_queryHandle == null && !Aborted)
                {
                    _log.LogInformation("Obtaining query handle from QueryContinuous() API");

                    try
                    {
                        _queryHandle = queueCache.QueryContinuous
                                           (qry: new ContinuousQuery <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(listener)
                        {
                            Local = true
                        },
                                           initialQry: new ScanQuery <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> {
                            Local = true
                        });
                    }
                    catch (Exception e)
                    {
                        _log.LogError(e, "Exception while constructing continuous query, will sleep and retry");
                        Thread.Sleep(5000);
                    }
                }

                if (_queryHandle == null || Aborted)
                {
                    _log.LogInformation("No query handle available, or aborting");
                    return;
                }

                using (_queryHandle)
                {
                    _log.LogInformation("Performing initial continuous query cursor scan of items to process");

                    // Perform the initial query to grab all existing elements and process them. Make sure to sort them in time order first
                    _queryHandle.GetInitialQueryCursor().OrderBy(x => x.Key.InsertUTCTicks).ForEach(handler.Add);

                    while (!Aborted)
                    {
                        try
                        {
                            {
                                // Cycle looking for new work to do as items arrive until aborted...
                                _log.LogInformation("Entering steady state continuous query scan of items to process");

                                // Activate the handler with the inject initial continuous query and move into steady state processing

                                InSteadyState = true;
                                handler.Activate();
                                do
                                {
                                    _waitHandle.WaitOne(_serviceCheckIntervalMs);
                                } while (!Aborted);
                            }
                        }
                        catch (Exception e)
                        {
                            _log.LogError(e, "Site model change processor service unhandled exception, waiting and trying again");

                            // Sleep for 5 seconds to see if things come right and then try again
                            Thread.Sleep(5000);
                        }
                    }
                }

                handler.Cancel();
            }
            catch (Exception e)
            {
                _log.LogError(e, "Exception occurred performing initial set up of continuous query and scan of existing items");
            }
            finally
            {
                _log.LogInformation($"{context.Name} completed executing");
            }
        }