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); }
public void NonSpatialCacheName() { TRexCaches.NonSpatialCacheName(StorageMutability.Mutable, FileSystemStreamType.Events).Should().Be(TRexCaches.kNonSpatialMutable); TRexCaches.NonSpatialCacheName(StorageMutability.Immutable, FileSystemStreamType.Events).Should().Be(TRexCaches.kNonSpatialImmutable); TRexCaches.NonSpatialCacheName(StorageMutability.Immutable, FileSystemStreamType.SiteModelMachineElevationChangeMap).Should().Be(TRexCaches.kSiteModelChangeMapsCacheName); TRexCaches.NonSpatialCacheName(StorageMutability.Immutable, FileSystemStreamType.SiteModelMachineElevationChangeMap).Should().Be(TRexCaches.kSiteModelChangeMapsCacheName); }
public void SpatialCacheName() { TRexCaches.SpatialCacheName(StorageMutability.Mutable, FileSystemStreamType.SubGridDirectory).Should().Be(TRexCaches.kSpatialSubGridDirectoryMutable); TRexCaches.SpatialCacheName(StorageMutability.Mutable, FileSystemStreamType.SubGridSegment).Should().Be(TRexCaches.kSpatialSubGridSegmentMutable); TRexCaches.SpatialCacheName(StorageMutability.Immutable, FileSystemStreamType.SubGridDirectory).Should().Be(TRexCaches.kSpatialSubGridDirectoryImmutable); TRexCaches.SpatialCacheName(StorageMutability.Immutable, FileSystemStreamType.SubGridSegment).Should().Be(TRexCaches.kSpatialSubGridSegmentImmutable); TRexCaches.SpatialCacheName(StorageMutability.Mutable, FileSystemStreamType.SubGridExistenceMap).Should().Be(TRexCaches.kProductionDataExistenceMapCacheMutable); TRexCaches.SpatialCacheName(StorageMutability.Immutable, FileSystemStreamType.SubGridExistenceMap).Should().Be(TRexCaches.kProductionDataExistenceMapCacheImmutable); }
/// <summary> /// Creates or obtains a reference to an already created TAG file buffer queue /// </summary> private void InstantiateCache() { var ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Mutable) ?? Ignition.GetIgnite(TRexGrids.MutableGridName()); _queueCache = ignite.GetCache <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(TRexCaches.TAGFileBufferQueueCacheName()); if (_queueCache == null) { _log.LogInformation($"Failed to get Ignite cache {TRexCaches.TAGFileBufferQueueCacheName()}"); throw new ArgumentException("Ignite cache not available"); } }
public override void ConfigureNonSpatialMutableCache(CacheConfiguration cfg) { base.ConfigureNonSpatialMutableCache(cfg); cfg.Name = TRexCaches.MutableNonSpatialCacheName(); cfg.KeepBinaryInStore = true; cfg.CacheMode = CacheMode.Partitioned; cfg.AffinityFunction = new MutableNonSpatialAffinityFunction(); cfg.Backups = 0; // cfg.CopyOnRead = false; Leave as default as should have no effect with 2.1+ without on heap caching enabled }
/// <summary> /// Constructs a site model meta data manager instance oriented to the TRex grid that is the primary grid /// referenced by the DI'd SiteModels instance /// </summary> public SiteModelMetadataManager(StorageMutability mutability) { // Obtain the ignite reference for the primary grid orientation of SiteModels var ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(mutability); metaDataCache = ignite?.GetOrCreateCache <Guid, ISiteModelMetadata>(ConfigureCache()); if (metaDataCache == null) { throw new TRexException($"Failed to get or create Ignite cache {TRexCaches.SiteModelMetadataCacheName()}, ignite reference is {ignite}"); } }
private void InstantiateSiteModelsCacheReference() { immutableTRexGrid.GetOrCreateCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(new CacheConfiguration { Name = TRexCaches.SiteModelsCacheName(StorageMutability.Immutable), KeepBinaryInStore = true, CacheMode = CacheMode.Replicated, Backups = 0, // No backups need as it is a replicated cache DataRegionName = DataRegions.IMMUTABLE_NONSPATIAL_DATA_REGION }); }
/// <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"); } }
public ICache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper> InstantiateNonSpatialCacheReference() { var cfg = new CacheConfiguration(); base.ConfigureNonSpatialMutableCache(cfg); cfg.Name = TRexCaches.MutableNonSpatialCacheName(); cfg.KeepBinaryInStore = true; cfg.CacheMode = CacheMode.Partitioned; cfg.AffinityFunction = new MutableNonSpatialAffinityFunction(); cfg.Backups = 0; return(mutableTRexGrid.GetOrCreateCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(cfg)); }
private void InstantiateSiteModelsCacheReference() { mutableTRexGrid.GetOrCreateCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(new CacheConfiguration { Name = TRexCaches.SiteModelsCacheName(StorageMutability.Mutable), KeepBinaryInStore = true, CacheMode = CacheMode.Partitioned, AffinityFunction = new MutableNonSpatialAffinityFunction(), // TODO: No backups for now Backups = 0, DataRegionName = DataRegions.MUTABLE_NONSPATIAL_DATA_REGION }); }
public void InstantiateTAGFileBufferQueueCacheReference() { var cfg = new CacheConfiguration { Name = TRexCaches.TAGFileBufferQueueCacheName(), KeepBinaryInStore = true, CacheMode = CacheMode.Partitioned, AffinityFunction = new MutableNonSpatialAffinityFunction(), DataRegionName = DataRegions.TAG_FILE_BUFFER_QUEUE_DATA_REGION, // TODO: No backups for now Backups = 0 }; mutableTRexGrid.GetOrCreateCache <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(cfg); }
/// <summary> /// Executes a request through it's generic types asynchronously /// </summary> /// <param name="arg"></param> /// <param name="key">The spatial affinity key to be used to direct this request to the node owning the partition it maps to</param> /// <returns></returns> public virtual Task <TResponse> ExecuteAsync(TArgument arg, ISubGridSpatialAffinityKey key) { if (key == null) { throw new TRexException("Affinity based result execution requires an affinity key"); } // Construct the function to be used var func = new TComputeFunc { Argument = arg }; // Send the result to the affinity bound node compute pool return(Compute != null?Compute.AffinityCallAsync(TRexCaches.SpatialSubGridDirectoryCacheName(StorageMutability.Immutable), key, func) : Task.FromResult <TResponse>(null)); }
/// <summary> /// Configure the parameters of the existence map cache /// </summary> private CacheConfiguration ConfigureCache() { return(new CacheConfiguration { Name = TRexCaches.SiteModelMetadataCacheName(), // cfg.CopyOnRead = false; Leave as default as should have no effect with 2.1+ without on heap caching enabled KeepBinaryInStore = true, // Replicate the site model metadata across nodes CacheMode = CacheMode.Replicated, Backups = 0, // No backups needed as it is a replicated cache DataRegionName = DataRegions.MUTABLE_NONSPATIAL_DATA_REGION }); }
/// <summary> /// Configure the parameters of the existence map cache /// </summary> private CacheConfiguration ConfigureDesignTopologyExistenceMapsCache() { return(new CacheConfiguration { Name = TRexCaches.DesignTopologyExistenceMapsCacheName(), // cfg.CopyOnRead = false; Leave as default as should have no effect with 2.1+ without on heap caching enabled KeepBinaryInStore = true, // Replicate the maps across nodes CacheMode = CacheMode.Partitioned, AffinityFunction = new MutableNonSpatialAffinityFunction(), Backups = 0, // No backups need as it is a replicated cache DataRegionName = DataRegions.MUTABLE_NONSPATIAL_DATA_REGION }); }
public void NonNullNames() { TRexCaches.DesignTopologyExistenceMapsCacheName().Should().NotBeNullOrWhiteSpace(); TRexCaches.ImmutableNonSpatialCacheName().Should().NotBeNullOrWhiteSpace(); TRexCaches.SpatialSubGridDirectoryCacheName(StorageMutability.Immutable).Should().NotBeNullOrWhiteSpace(); TRexCaches.SpatialSubGridDirectoryCacheName(StorageMutability.Mutable).Should().NotBeNullOrWhiteSpace(); TRexCaches.SpatialSubGridSegmentCacheName(StorageMutability.Immutable).Should().NotBeNullOrWhiteSpace(); TRexCaches.SpatialSubGridSegmentCacheName(StorageMutability.Mutable).Should().NotBeNullOrWhiteSpace(); TRexCaches.MutableNonSpatialCacheName().Should().NotBeNullOrWhiteSpace(); TRexCaches.SegmentRetirementQueueCacheName().Should().NotBeNullOrWhiteSpace(); TRexCaches.SiteModelMetadataCacheName().Should().NotBeNullOrWhiteSpace(); TRexCaches.SiteModelsCacheName(StorageMutability.Immutable).Should().NotBeNullOrWhiteSpace(); TRexCaches.SiteModelsCacheName(StorageMutability.Mutable).Should().NotBeNullOrWhiteSpace(); TRexCaches.TAGFileBufferQueueCacheName().Should().NotBeNullOrWhiteSpace(); TRexCaches.SiteModelChangeMapsCacheName().Should().NotBeNullOrWhiteSpace(); TRexCaches.ProductionDataExistenceMapCacheName(StorageMutability.Immutable).Should().NotBeNullOrWhiteSpace(); TRexCaches.ProductionDataExistenceMapCacheName(StorageMutability.Mutable).Should().NotBeNullOrWhiteSpace(); }
public ICache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper> InstantiateNonSpatialCacheReference() { var cfg = new CacheConfiguration(); base.ConfigureNonSpatialImmutableCache(cfg); cfg.Name = TRexCaches.ImmutableNonSpatialCacheName(); cfg.KeepBinaryInStore = true; // Non-spatial (event) data is replicated to all nodes for local access cfg.CacheMode = CacheMode.Replicated; cfg.Backups = 0; // No backups need as it is a replicated cache Console.WriteLine($"CacheConfig is: {cfg}"); Console.WriteLine($"immutableTRexGrid is : {immutableTRexGrid}"); return(immutableTRexGrid.GetOrCreateCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(cfg)); }
/// <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(), }); }
public ICache <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper> InstantiateSpatialSubGridSegmentCacheReference() { var cfg = new CacheConfiguration(); base.ConfigureImmutableSpatialCache(cfg); cfg.Name = TRexCaches.SpatialSubGridSegmentCacheName(StorageMutability.Immutable); cfg.KeepBinaryInStore = true; // TODO: No backups for now cfg.Backups = 0; // Spatial data is partitioned among the server grid nodes according to spatial affinity mapping cfg.CacheMode = CacheMode.Partitioned; // Configure the function that maps sub grid data into the affinity map for the nodes in the grid cfg.AffinityFunction = new SubGridBasedSpatialAffinityFunction(); return(immutableTRexGrid.GetOrCreateCache <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper>(cfg)); }
/// <summary> /// Constructs a segment retirement queue for the mutable ignite grid. /// </summary> public SegmentRetirementQueue() { var ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Mutable); if (ignite == null) { throw new TRexException("Failed to obtain mutable grid Ignite reference"); } _queueCache = ignite.GetOrCreateCache <ISegmentRetirementQueueKey, SegmentRetirementQueueItem>( new CacheConfiguration { Name = TRexCaches.SegmentRetirementQueueCacheName(), CacheMode = CacheMode.Partitioned, // TODO: No backups for now Backups = 0, KeepBinaryInStore = true }); }
/// <summary> /// Create the caches that /// </summary> private void InstantiateRebuildSiteModelCacheReferences() { mutableTRexGrid.GetOrCreateCache <INonSpatialAffinityKey, IRebuildSiteModelMetaData>(new CacheConfiguration { Name = TRexCaches.SiteModelRebuilderMetaDataCacheName(), KeepBinaryInStore = true, CacheMode = CacheMode.Partitioned, AffinityFunction = new MutableNonSpatialAffinityFunction(), Backups = 0, DataRegionName = DataRegions.MUTABLE_NONSPATIAL_DATA_REGION }); mutableTRexGrid.GetOrCreateCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(new CacheConfiguration { Name = TRexCaches.SiteModelRebuilderFileKeyCollectionsCacheName(), KeepBinaryInStore = true, CacheMode = CacheMode.Partitioned, AffinityFunction = new MutableNonSpatialAffinityFunction(), Backups = 0, DataRegionName = DataRegions.MUTABLE_NONSPATIAL_DATA_REGION }); }
/// <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(TAGFileBufferQueueService)}.{nameof(Execute)}"); } _log.LogInformation($"{nameof(TAGFileBufferQueueService)} {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.Mutable) ?? Ignition.GetIgnite(TRexGrids.MutableGridName()); if (ignite == null) { _log.LogError("Ignite reference in service is null - aborting service execution"); return; } // Don't start operations until the local (mutable) grid is confirmed as active DIContext.ObtainRequired <IActivatePersistentGridServer>().WaitUntilGridActive(TRexGrids.MutableGridName()); // Once active, delay start of operations for a time to ensure everything is up and running var delay = DIContext.ObtainRequired <IConfigurationStore>().GetValueInt("TREX_TAG_FILE_BUFFER_QUEUE_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 <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(TRexCaches.TAGFileBufferQueueCacheName()); _handler = new TAGFileBufferQueueItemHandler(); while (_queryHandle == null && !_aborted) { try { // 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 _log.LogInformation("Obtaining continuous query handle"); _queryHandle = queueCache.QueryContinuous (qry: new ContinuousQuery <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(new LocalTAGFileListener(_handler)) { Local = true }, initialQry: new ScanQuery <ITAGFileBufferQueueKey, TAGFileBufferQueueItem> { 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) { // Perform the initial query to grab all existing elements and add them to the grouper _log.LogInformation("Performing initial continuous query cursor scan of items"); _queryHandle.GetInitialQueryCursor().ForEach(item => _handler.Add(item.Key)); // Transition into steady state looking for new elements in the cache via the continuous query while (!_aborted) { try { // Cycle looking for new work to do as TAG files arrive until aborted... _log.LogInformation("Entering steady state continuous query scan of items to process in TAGFileBufferQueue"); do { _waitHandle.WaitOne(_serviceCheckIntervalMs); //Log.LogInformation("Continuous query scan of items to process in TAGFileBufferQueue still active"); } while (!_aborted); } catch (Exception e) { _log.LogError(e, "Tag file buffer 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($"{nameof(TAGFileBufferQueueService)} {context.Name} completed executing"); } }
public async void ExecuteAsync_SingleTAGFile(bool treatMachineAsJohnDoe) { var testGuid = Guid.NewGuid(); var mutableIgniteMock = IgniteMock.Mutable; AddApplicationGridRouting(); // Construct a site model from a single TAG file var tagFiles = new[] { Path.Combine(TestHelper.CommonTestDataPath, "TestTAGFile.tag") }; var siteModel = DITAGFileAndSubGridRequestsFixture.BuildModel(tagFiles, out _, true, false, treatMachineAsJohnDoe); // Push the tag file into the S3 bucket var uidForArchiveRepresentation = treatMachineAsJohnDoe ? Guid.Empty : siteModel.Machines[0].ID; var s3Proxy = DIContext.Obtain <Func <TransferProxyType, IS3FileTransfer> >()(TransferProxyType.TAGFiles); s3Proxy.WriteFile(tagFiles[0], $"{siteModel.ID}/{uidForArchiveRepresentation}/{Path.GetFileName(tagFiles[0])}"); var rebuilder = CreateBuilder(siteModel.ID, false, TransferProxyType.TAGFiles); // Add the rebuilder to the manager in a 'hands-off' mode to allow notification routing to it. var manager = DIContext.Obtain <ISiteModelRebuilderManager>(); manager.AddRebuilder(rebuilder).Should().BeTrue(); // Start the rebuild executing var rebuilderTask = rebuilder.ExecuteAsync(); // Wait until the rebuilder is in the monitoring state and then inject the contents of the tag file buffer queue cache into the handler while (rebuilder.Metadata.Phase != RebuildSiteModelPhase.Monitoring) { await Task.Delay(1000); } var mockQueueCacheDictionary = mutableIgniteMock.MockedCacheDictionaries[TRexCaches.TAGFileBufferQueueCacheName()] as Dictionary <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>; var handler = new TAGFileBufferQueueItemHandler(); handler.Should().NotBeNull(); // Inject the keys for the handler to use to extract the TAG file content to be processed. mockQueueCacheDictionary.ForEach(kv => handler.Add(kv.Key)); // Now wait for the rebuilder task to complete var result = await rebuilderTask; result.Should().NotBeNull(); result.DeletionResult.Should().Be(DeleteSiteModelResult.OK); result.RebuildResult.Should().Be(RebuildSiteModelResult.OK); result.NumberOfTAGFileKeyCollections.Should().Be(1); result.NumberOfTAGFilesProcessed.Should().Be(1); result.NumberOfTAGFilesFromS3.Should().Be(1); result.LastProcessedTagFile.Should().Be(Path.GetFileName(tagFiles[0])); // Get the site model again and validate that there is still a single machine with the expected John Doe status siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(siteModel.ID); siteModel.Machines.Count.Should().Be(1); siteModel.Machines[0].IsJohnDoeMachine.Should().Be(treatMachineAsJohnDoe); // Belt and braces - clean the mocked TAG file buffer queue mockQueueCacheDictionary.Clear(); }
/// <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()) )); }
/// <summary> /// No-arg constructor. Instantiates the continuous query and performs initial scan of elements that the remote filter /// will populate into the node-local groupers within the mutable grid. /// </summary> public SegmentRetirementQueueManager(bool runLocally) { _log.LogInformation("Establishing segment retirement queue cache context"); // Get the ignite grid and cache references _ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Mutable) ?? Ignition.GetIgnite(TRexGrids.MutableGridName()); var queueCache = _ignite.GetCache <ISegmentRetirementQueueKey, SegmentRetirementQueueItem>(TRexCaches.SegmentRetirementQueueCacheName()); // Todo: Create a thread to periodically (needed if we don't go down the service route // .... _log.LogInformation("Completed segment retirement queue manager initialization"); }
/// <summary> /// Default no-args constructor that prepares a spatial affinity partition map for the immutable spatial caches /// </summary> public ImmutableSpatialAffinityPartitionMap() : base(DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Immutable) .GetCache <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper>(TRexCaches.SpatialSubGridDirectoryCacheName(StorageMutability.Immutable))) { }
public void Test_TAGFileBufferQueue_AddingTAGFile() { EnsureServer(); var queue = new TAGFileBufferQueue(); Assert.NotNull(queue); // Load a TAG file and add it to the queue. Verify the TAG file appears in the cache var tagFileName = "TestTAGFile-TAGFile-Read-Stream.tag"; var projectUid = Guid.NewGuid(); var assetUid = Guid.NewGuid(); byte[] tagContent; using (var tagFileStream = new FileStream(Path.Combine("TestData", "TAGFiles", tagFileName), FileMode.Open, FileAccess.Read)) { tagContent = new byte[tagFileStream.Length]; tagFileStream.Read(tagContent, 0, (int)tagFileStream.Length); } var tagKey = new TAGFileBufferQueueKey(tagFileName, projectUid, assetUid); var tagItem = new TAGFileBufferQueueItem { InsertUTC = DateTime.UtcNow, ProjectID = projectUid, AssetID = assetUid, FileName = tagFileName, Content = tagContent }; // Perform the actual add queue.Add(tagKey, tagItem); // Read it back from the cache to ensure it was added as expected. var queueCache = _ignite.GetCache <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(TRexCaches.TAGFileBufferQueueCacheName()); var tagItem2 = queueCache.Get(tagKey); Assert.True(tagItem2 != null, "Tag item read back from buffer queue cache was null"); Assert.True(tagItem.Content.Length == tagItem2.Content.Length, "Tag content lengths different"); Assert.True(tagItem.InsertUTC == tagItem2.InsertUTC, "Tag insert UTCs different"); Assert.True(tagItem.AssetID == tagItem2.AssetID, "Tag AssetUIDs different"); Assert.True(tagItem.FileName == tagItem2.FileName, "Tag FileNames different"); Assert.True(tagItem.ProjectID == tagItem2.ProjectID, "Tag ProjectUIDs different"); }
public void SiteModelsCacheName() { TRexCaches.NonSpatialCacheName(StorageMutability.Mutable, FileSystemStreamType.ProductionDataXML).Should().Be(TRexCaches.kSiteModelsCacheMutable); TRexCaches.NonSpatialCacheName(StorageMutability.Immutable, FileSystemStreamType.ProductionDataXML).Should().Be(TRexCaches.kSiteModelsCacheImmutable); }
/// <summary> /// Default no-arg constructor supplied default TRex grid and MutableNonSpatial cache name for surveyed surface information /// </summary> public SurveyedSurfaceService(StorageMutability mutability) : base(TRexGrids.GridName(mutability), "SurveyedSurfaceService") { CacheName = TRexCaches.ImmutableNonSpatialCacheName(); }
/// <summary> /// Executes the life cycle of the service until it is aborted /// </summary> public void Execute(IServiceContext context) { try { _log.LogInformation($"{nameof(SegmentRetirementQueueService)} {context.Name} starting executing"); _aborted = false; _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); // Get the ignite grid and cache references var mutableIgnite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Mutable) ?? Ignition.GetIgnite(TRexGrids.MutableGridName()); if (mutableIgnite == null) { _log.LogError("Mutable Ignite reference in service is null - aborting service execution"); return; } // Don't start operations until the local (mutable) grid is confirmed as active DIContext.ObtainRequired <IActivatePersistentGridServer>().WaitUntilGridActive(TRexGrids.MutableGridName()); // Once active, delay start of operations for a time to ensure everything is up and running var delay = DIContext.ObtainRequired <IConfigurationStore>().GetValueInt("TREX_SEGMENT_RETIREMENT_QUEUE_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 = mutableIgnite.GetCache <ISegmentRetirementQueueKey, SegmentRetirementQueueItem>(TRexCaches.TAGFileBufferQueueCacheName()); var queue = new SegmentRetirementQueue(); var handler = new SegmentRetirementQueueItemHandler(); // Cycle looking for new work to do until aborted... do { try { // Obtain a specific local mutable storage proxy so as to have a local transactional proxy // for this activity var storageProxy = DIContext.Obtain <IStorageProxyFactory>().MutableGridStorage(); if (storageProxy.Mutability != StorageMutability.Mutable) { throw new TRexException("Non mutable storage proxy available to segment retirement queue"); } _log.LogInformation("About to query retiree spatial streams from cache"); var earlierThan = DateTime.UtcNow - retirementAge; // Retrieve the list of segments to be retired var retirees = queue.Query(earlierThan); // Pass the list to the handler for action var retireesCount = retirees?.Count ?? 0; if (retireesCount > 0) { _log.LogInformation($"About to retire {retireesCount} groups of spatial streams from mutable and immutable contexts"); if (handler.Process(storageProxy, queueCache, retirees)) { if (_reportDetailedSegmentRetirementActivityToLog) { _log.LogInformation($"Successfully retired {retireesCount} spatial streams from mutable and immutable contexts"); } // Remove the elements from the segment retirement queue queue.Remove(earlierThan); } else { _log.LogError($"Failed to retire {retireesCount} spatial streams from mutable and immutable contexts"); } } } catch (Exception e) { _log.LogError(e, "Exception reported while obtaining new group of retirees to process:"); } _waitHandle.WaitOne(SEGMENT_RETIREMENT_QUEUE_SERVICE_CHECK_INTERVAL_MS); } while (!_aborted); } catch (Exception e) { _log.LogError(e, $"Unhandled exception occurred in {nameof(SegmentRetirementQueueService)}"); } finally { _log.LogInformation($"{nameof(SegmentRetirementQueueService)} {context.Name} completed executing"); } }
/// <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() .Add(x => x.AddSingleton <IStorageProxyFactory>(new StorageProxyFactory())) //*********************************************** // Injected factories for non-transacted proxies // ********************************************** .Add(x => x.AddSingleton <Func <IIgnite, StorageMutability, FileSystemStreamType, IStorageProxyCache <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper> > > (factory => (ignite, mutability, streamType) => new StorageProxyCache <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper>(ignite?.GetCache <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper>(TRexCaches.SpatialCacheName(mutability, streamType))))) .Add(x => x.AddSingleton <Func <IIgnite, StorageMutability, FileSystemStreamType, IStorageProxyCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper> > > (factory => (ignite, mutability, streamType) => new StorageProxyCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(ignite?.GetCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(TRexCaches.NonSpatialCacheName(mutability, streamType))))) .Add(x => x.AddSingleton <Func <IIgnite, StorageMutability, FileSystemStreamType, IStorageProxyCache <ISiteModelMachineAffinityKey, ISerialisedByteArrayWrapper> > > (factory => (ignite, mutability, streamType) => { // SiteModel change maps are only maintained on the immutable grid if (mutability != StorageMutability.Immutable) { return(null); } return(new StorageProxyCache <ISiteModelMachineAffinityKey, ISerialisedByteArrayWrapper>(ignite?.GetCache <ISiteModelMachineAffinityKey, ISerialisedByteArrayWrapper>(TRexCaches.NonSpatialCacheName(mutability, streamType)))); })) //*********************************************** // Injected factories for transacted proxies // ********************************************** .Add(x => x.AddSingleton <Func <IIgnite, StorageMutability, FileSystemStreamType, IStorageProxyCacheTransacted <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper> > > (factory => (ignite, mutability, streamType) => new StorageProxyCacheTransacted <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper>(ignite?.GetCache <ISubGridSpatialAffinityKey, ISerialisedByteArrayWrapper>(TRexCaches.SpatialCacheName(mutability, streamType)), new SubGridSpatialAffinityKeyEqualityComparer()))) .Add(x => x.AddSingleton <Func <IIgnite, StorageMutability, FileSystemStreamType, IStorageProxyCacheTransacted <INonSpatialAffinityKey, ISerialisedByteArrayWrapper> > > (factory => (ignite, mutability, streamType) => new StorageProxyCacheTransacted <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(ignite?.GetCache <INonSpatialAffinityKey, ISerialisedByteArrayWrapper>(TRexCaches.NonSpatialCacheName(mutability, streamType)), new NonSpatialAffinityKeyEqualityComparer()))) .Add(x => x.AddSingleton <Func <IIgnite, StorageMutability, FileSystemStreamType, IStorageProxyCacheTransacted <ISiteModelMachineAffinityKey, ISerialisedByteArrayWrapper> > > (factory => (ignite, mutability, streamType) => { // SiteModel change maps are only maintained on the immutable grid if (mutability != StorageMutability.Immutable) { return(null); } return(new StorageProxyCacheTransacted <ISiteModelMachineAffinityKey, ISerialisedByteArrayWrapper>(ignite?.GetCache <ISiteModelMachineAffinityKey, ISerialisedByteArrayWrapper>(TRexCaches.NonSpatialCacheName(mutability, streamType)), new SiteModelMachineAffinityKeyEqualityComparer())); })); }