/// <summary> /// Loads the set of surveyed surfaces for a site model. If none exist and empty list is returned. /// </summary> private ISurveyedSurfaces Load(Guid siteModelUid) { _log.LogInformation($"Loading surveyed surfaces for project {siteModelUid}"); var ss = DIContext.ObtainRequired <ISurveyedSurfaces>(); try { _readStorageProxy.ReadStreamFromPersistentStore(siteModelUid, SURVEYED_SURFACE_STREAM_NAME, FileSystemStreamType.SurveyedSurfaces, out var ms); if (ms != null) { using (ms) { ss.FromStream(ms); } } } catch (KeyNotFoundException) { /* This is OK, the element is not present in the cache yet */ } catch (Exception e) { throw new TRexException("Exception reading Alignment cache element from Ignite", e); } _log.LogInformation($"Loaded {ss.Count} surveyed surfaces for project {siteModelUid}"); return(ss); }
public CalculateDesignElevationPatchResponse Invoke(CalculateDesignElevationPatchArgument args) { try { // Log.LogInformation($"CalculateDesignElevationPatchComputeFunc: Arg = {arg}"); var Executor = new CalculateDesignElevationPatch(); var heightsResult = Executor.Execute(DIContext.ObtainRequired <ISiteModels>().GetSiteModel(args.ProjectID), args.ReferenceDesign, args.CellSize, args.OriginX, args.OriginY, out var calcResult); return(new CalculateDesignElevationPatchResponse { CalcResult = calcResult, Heights = heightsResult }); } catch (Exception e) { _log.LogError(e, "Exception calculating design elevation patch"); return(new CalculateDesignElevationPatchResponse { Heights = null, CalcResult = Models.DesignProfilerRequestResult.UnknownError }); } }
/// <summary> /// Performs execution business logic for this executor /// </summary> public DesignProfilerRequestResult Execute(Guid projectUid, Guid designUid) { try { var siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(projectUid, false); if (siteModel == null) { _log.LogError($"Site model {projectUid} not found"); return(DesignProfilerRequestResult.NoSelectedSiteModel); } var removed = DIContext.ObtainRequired <IDesignManager>().Remove(projectUid, designUid); if (removed) { // Broadcast to listeners that design has changed var sender = DIContext.ObtainRequired <IDesignChangedEventSender>(); sender.DesignStateChanged(DesignNotificationGridMutability.NotifyImmutable, projectUid, designUid, ImportedFileType.DesignSurface, designRemoved: true); } else { _log.LogError($"Failed to remove design {designUid} from project {projectUid} as it may not exist in the project"); return(DesignProfilerRequestResult.DesignDoesNotExist); } return(DesignProfilerRequestResult.OK); } catch (Exception e) { _log.LogError(e, "Execute: Exception: "); return(DesignProfilerRequestResult.UnknownError); } }
/// <summary> /// Performs execution business logic for this executor /// </summary> /// <returns></returns> public Fence Execute(Guid projectUid, Guid referenceDesignUid, double startStation, double endStation, double leftOffset, double rightOffset) { try { var siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(projectUid, false); var design = DIContext.ObtainRequired <IDesignFiles>().Lock(referenceDesignUid, siteModel, siteModel.CellSize, out var lockResult); if (design == null) { Log.LogWarning($"Failed to read file for design {referenceDesignUid}"); return(null); } if (design is SVLAlignmentDesign svlDesign) { var result = svlDesign.DetermineFilterBoundary(startStation, endStation, leftOffset, rightOffset, out var fence); if (result != DesignProfilerRequestResult.OK) { Log.LogWarning($"Failed to compute filter boundary with error {result}"); return(null); } return(fence); } throw new TRexException($"Design {design.FileName} is not an alignment design"); } catch (Exception E) { Log.LogError(E, "Execute: Exception: "); return(null); } }
/// <summary> /// Loads the set of Alignments for a site model. If none exist and empty list is returned. /// </summary> private IAlignments Load(Guid siteModelUid) { _log.LogInformation($"Loading alignments for project {siteModelUid}"); var alignments = DIContext.ObtainRequired <IAlignments>(); try { _readStorageProxy.ReadStreamFromPersistentStore(siteModelUid, ALIGNMENTS_STREAM_NAME, FileSystemStreamType.Alignments, out var ms); if (ms != null) { using (ms) { alignments.FromStream(ms); } } } catch (KeyNotFoundException) { /* This is OK, the element is not present in the cache yet */ } catch (Exception e) { throw new TRexException("Exception reading Alignment cache element from Ignite", e); } _log.LogInformation($"Loaded {alignments.Count} alignments for project {siteModelUid}"); return(alignments); }
/// <summary> /// Loads the set of designs for a site model. If none exist an empty list is returned. /// </summary> private IDesigns Load(Guid siteModelId) { _log.LogInformation($"Loading designs for project {siteModelId}"); var designs = DIContext.ObtainRequired <IDesigns>(); try { _readStorageProxy.ReadStreamFromPersistentStore(siteModelId, DESIGNS_STREAM_NAME, FileSystemStreamType.Designs, out var ms); if (ms != null) { using (ms) { designs.FromStream(ms); } } } catch (KeyNotFoundException) { // This is OK, the element is not present in the cache yet - return an empty design list } catch (Exception e) { throw new TRexException("Exception reading designs cache element from Ignite", e); } _log.LogInformation($"Loaded {designs.Count} designs for project {siteModelId}"); return(designs); }
public void Test_TAGFileCellPassGeneration_CompareKnownCellPassConstruction_Folders(string folderName) { // Get list of TAG files var fileNames = Directory.GetFiles(folderName, "*.tag"); foreach (var tagFileName in fileNames) { var linesLogFileName = Path.Combine(Path.GetDirectoryName(tagFileName), $"CellMutationLog-{Path.GetFileName(tagFileName)}.txt.output"); var mutationLogFileName = Path.Combine(Path.GetDirectoryName(tagFileName), $"CellMutationLog-{Path.GetFileName(tagFileName)}.txt"); var Lines = new List <string>(); ICell_NonStatic_MutationHook Hook = DIContext.ObtainRequired <ICell_NonStatic_MutationHook>(); Hook.SetActions(new CellPassWriter(x => Lines.Add(x))); try { DITagFileFixture.ReadTAGFileFullPath(tagFileName); } finally { Hook.ClearActions(); } File.WriteAllLines(linesLogFileName, Lines); CompareMutationLogs(Lines, mutationLogFileName); } }
public AlignmentDesignStationRangeResponse Invoke(DesignSubGridRequestArgumentBase args) { try { var executor = new CalculateAlignmentDesignStationRange(); var stationRange = executor.Execute(DIContext.ObtainRequired <ISiteModels>().GetSiteModel(args.ProjectID), args.ReferenceDesign.DesignID); if (stationRange.StartStation == double.MaxValue || stationRange.EndStation == double.MinValue) { return new AlignmentDesignStationRangeResponse() { RequestResult = DesignProfilerRequestResult.FailedToCalculateAlignmentStationRange } } ; return(new AlignmentDesignStationRangeResponse { RequestResult = DesignProfilerRequestResult.OK, StartStation = stationRange.Item1, EndStation = stationRange.Item2 }); } catch (Exception e) { _log.LogError(e, $"Failed to compute alignment design station range. Site Model ID: {args.ProjectID} design ID: {args.ReferenceDesign.DesignID}"); return(new AlignmentDesignStationRangeResponse { RequestResult = DesignProfilerRequestResult.UnknownError }); } }
public IDesignChangedEventSenderResponse Invoke(IDesignChangedEvent arg) { var localNodeId = Guid.Empty; try { var siteModels = DIContext.Obtain <ISiteModels>(); if (siteModels == null) { _log.LogError("No ISiteModels instance available from DIContext to send design change message to"); return(new DesignChangedEventSenderResponse { Success = false, NodeUid = localNodeId }); } localNodeId = DIContext.ObtainRequired <ITRexGridFactory>().Grid(siteModels.PrimaryMutability).GetCluster().GetLocalNode().Id; var designFiles = DIContext.ObtainOptional <IDesignFiles>(); if (designFiles == null) { // No cache, leave early... return(new DesignChangedEventSenderResponse { Success = true, NodeUid = localNodeId }); } var siteModel = siteModels.GetSiteModel(arg.SiteModelUid); if (siteModel == null) { _log.LogWarning($"No site model found for ID {arg.SiteModelUid}"); return(new DesignChangedEventSenderResponse { Success = true, NodeUid = localNodeId }); } designFiles.DesignChangedEventHandler(arg.DesignUid, siteModel, arg.FileType); return(new DesignChangedEventSenderResponse { Success = true, NodeUid = localNodeId }); } catch (Exception e) { _log.LogError(e, "Exception occurred processing site model attributes changed event"); return(new DesignChangedEventSenderResponse { Success = false, NodeUid = localNodeId }); } finally { _log.LogInformation( $"Completed handling notification of design changed for Site:{arg.SiteModelUid}, Design:{arg.DesignUid}, DesignRemoved:{arg.DesignRemoved}, ImportedFileType:{arg.FileType}"); } }
public async Task <IClientLeafSubGrid> ExecuteAsync(ISurfaceElevationPatchArgument arg) => Execute(arg); // Task.Run(() => Execute(arg)); public IClientLeafSubGrid Execute(ISurfaceElevationPatchArgument arg) { if (arg.SurveyedSurfacePatchType > SurveyedSurfacePatchType.CompositeElevations) { return(null); } var cachingSupported = arg.SurveyedSurfacePatchType != SurveyedSurfacePatchType.CompositeElevations && _cache != null; // Check the item is available in the cache if (cachingSupported && _cache?.Get(arg.OTGCellBottomLeftX, arg.OTGCellBottomLeftY) is IClientLeafSubGrid cacheResult) { return(_cache.ExtractFromCachedItem(cacheResult, arg.ProcessingMap, arg.SurveyedSurfacePatchType)); } SubGridTreeBitmapSubGridBits savedMap = null; // Always request the full sub grid from the surveyed surface engine unless composite elevations are requested if (cachingSupported) { savedMap = arg.ProcessingMap; arg.ProcessingMap = SubGridTreeBitmapSubGridBits.FullMask; } var subGridInvalidationVersion = cachingSupported ? _cache.InvalidationVersion : 0; var executor = new CalculateSurfaceElevationPatch(); _sitemodel ??= DIContext.ObtainRequired <ISiteModels>().GetSiteModel(arg.SiteModelID); _designFiles ??= DIContext.ObtainRequired <IDesignFiles>(); _surveyedSurfaces ??= _sitemodel.SurveyedSurfaces; var clientResult = executor.Execute(_sitemodel, arg.OTGCellBottomLeftX, arg.OTGCellBottomLeftY, arg.CellSize, arg.SurveyedSurfacePatchType, arg.IncludedSurveyedSurfaces, _designFiles, _surveyedSurfaces, arg.ProcessingMap); if (clientResult != null) { // For now, only cache non-composite elevation sub grids if (cachingSupported) { _cache?.Add(clientResult, subGridInvalidationVersion); } if (savedMap != null) { clientResult = _cache.ExtractFromCachedItem(clientResult, savedMap, arg.SurveyedSurfacePatchType); } } return(clientResult); }
public CalculateDesignElevationSpotResponse Invoke(CalculateDesignElevationSpotArgument args) { try { var Executor = new CalculateDesignElevationSpot(); return(Executor.Execute(DIContext.ObtainRequired <ISiteModels>().GetSiteModel(args.ProjectID), args.ReferenceDesign, args.SpotX, args.SpotY)); } catch (Exception e) { _log.LogError(e, "Exception calculating design spot height"); return(new CalculateDesignElevationSpotResponse { Elevation = Common.Consts.NullDouble, CalcResult = DesignProfilerRequestResult.UnknownError }); } }
public ISiteModelAttributesChangedEventSenderResponse Invoke(ISiteModelAttributesChangedEvent arg) { var localNodeId = Guid.Empty; try { var siteModels = DIContext.Obtain <ISiteModels>(); if (siteModels == null) { _log.LogError("No ISiteModels instance available from DIContext to send attributes change message to"); return(new SiteModelAttributesChangedEventSenderResponse { Success = false, NodeUid = localNodeId }); } localNodeId = DIContext.ObtainRequired <ITRexGridFactory>().Grid(siteModels.PrimaryMutability).GetCluster().GetLocalNode().Id; _log.LogInformation( $"Received notification of site model attributes changed for {arg.SiteModelID}: ExistenceMapModified={arg.ExistenceMapModified}, DesignsModified={arg.DesignsModified}, SurveyedSurfacesModified {arg.SurveyedSurfacesModified} CsibModified={arg.CsibModified}, MachinesModified={arg.MachinesModified}, MachineTargetValuesModified={arg.MachineTargetValuesModified}, AlignmentsModified {arg.AlignmentsModified}, ExistenceMapChangeMask {arg.ExistenceMapChangeMask != null}"); // Tell the SiteModels instance to reload the designated site model that has changed siteModels.SiteModelAttributesHaveChanged(arg); return(new SiteModelAttributesChangedEventSenderResponse { Success = true, NodeUid = localNodeId }); } catch (Exception e) { _log.LogError(e, "Exception occurred processing site model attributes changed event"); return(new SiteModelAttributesChangedEventSenderResponse { Success = false, NodeUid = localNodeId }); } finally { _log.LogInformation( $"Completed handling notification of site model attributes changed for '{arg.SiteModelID}': ExistenceMapModified={arg.ExistenceMapModified}, DesignsModified={arg.DesignsModified}, SurveyedSurfacesModified {arg.SurveyedSurfacesModified} CsibModified={arg.CsibModified}, MachinesModified={arg.MachinesModified}, MachineTargetValuesModified={arg.MachineTargetValuesModified}, AlignmentsModified {arg.AlignmentsModified}, ExistenceMapChangeMask {arg.ExistenceMapChangeMask != null}"); } }
private static ProgressiveVolumesResponse ConvertBoundaryFromGridToWGS84(Guid projectUid, ProgressiveVolumesResponse response) { try { var convertCoordinates = DIContext.ObtainRequired <ICoreXWrapper>(); if (response.Volumes != null) { foreach (var aggregator in response.Volumes) { if (!aggregator.Volume.BoundingExtentGrid.IsValidPlanExtent) // No conversion possible { continue; } var neeCoords = new[] { new XYZ( aggregator.Volume.BoundingExtentGrid.MinX, aggregator.Volume.BoundingExtentGrid.MinY, // ReSharper disable once CompareOfFloatsByEqualityOperator aggregator.Volume.BoundingExtentGrid.MinZ == Consts.NullDouble ? 0.0 : aggregator.Volume.BoundingExtentGrid.MinZ), new XYZ( aggregator.Volume.BoundingExtentGrid.MaxX, aggregator.Volume.BoundingExtentGrid.MaxY, // ReSharper disable once CompareOfFloatsByEqualityOperator aggregator.Volume.BoundingExtentGrid.MaxZ == Consts.NullDouble ? 0.0 : aggregator.Volume.BoundingExtentGrid.MaxZ) }; var siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(projectUid); var llhCoords = convertCoordinates.NEEToLLH(siteModel.CSIB(), neeCoords.ToCoreX_XYZ()).ToTRex_XYZ(); aggregator.Volume.BoundingExtentLLH = new BoundingWorldExtent3D { MinX = MathUtilities.RadiansToDegrees(llhCoords[0].X), MinY = MathUtilities.RadiansToDegrees(llhCoords[0].Y), MaxX = MathUtilities.RadiansToDegrees(llhCoords[1].X), MaxY = MathUtilities.RadiansToDegrees(llhCoords[1].Y) }; } } } catch (Exception e) { // Don't rethrow here, doing so will terminate the otherwise valid request (with valid response). Leave the grid boundary extents in place with null LLH extents _log.LogError(e, "Exception converting coordinates for progressive volumes. Response will contain grid coordinate extents."); } return(response); }
public DesignFilterSubGridMaskResponse Invoke(DesignSubGridFilterMaskArgument args) { try { // Calculate an elevation patch for the requested location and convert it into a bitmask detailing which cells have non-null values var executor = new CalculateDesignElevationPatch(); var patch = executor.Execute(DIContext.ObtainRequired <ISiteModels>().GetSiteModel(args.ProjectID), args.ReferenceDesign, args.CellSize, args.OriginX, args.OriginY, out var calcResult); var result = new DesignFilterSubGridMaskResponse(); if (patch == null) { _log.LogWarning($"Request for design elevation patch that does not exist: Project: {args.ProjectID}, design {args.ReferenceDesign}, location {args.OriginX}:{args.OriginY}, calcResult: {calcResult}"); result.Bits = null; // Requestors should not ask for sub grids that don't exist in the design. result.RequestResult = calcResult; return(result); } result.RequestResult = calcResult; result.Bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled); var patchCells = patch.Cells; for (byte i = 0; i < SubGridTreeConsts.SubGridTreeDimension; i++) { for (byte j = 0; j < SubGridTreeConsts.SubGridTreeDimension; j++) { result.Bits[i, j] = !patchCells[i, j].Equals(Common.Consts.NullHeight); } } return(result); } catch (Exception e) { _log.LogError(e, "Exception calculating design filter sub grid mask"); return(new DesignFilterSubGridMaskResponse { Bits = null, RequestResult = Models.DesignProfilerRequestResult.UnknownError }); } }
public void Test_TAGFileCellPassGeneration_CompareKnownCellPassConstruction_Dimensions2018CaseMachine(string tagFileName, string mutationLogFileName) { var Lines = new List <string>(); ICell_NonStatic_MutationHook Hook = DIContext.ObtainRequired <ICell_NonStatic_MutationHook>(); Hook.SetActions(new CellPassWriter(x => Lines.Add(x))); try { DITagFileFixture.ReadTAGFile("Dimensions2018-CaseMachine", tagFileName); } finally { Hook.ClearActions(); } //File.WriteAllLines(Path.Combine(@"C:\temp\SavedMutationLogsFromTests\" + mutationLogFileName), Lines); CompareMutationLogs(Lines, Path.Combine("TestData", "TagFiles", "Dimensions2018-CaseMachine", mutationLogFileName)); }
/// <summary> /// Invokes the surface elevation patch computation function on the server nodes the request has been sent to /// </summary> public ISerialisedByteArrayWrapper Invoke(ISurfaceElevationPatchArgument arg) { try { var executor = new CalculateSurfaceElevationPatch(); var siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(arg.SiteModelID); if (siteModel == null) { _log.LogWarning($"Failed to get site model with ID {arg.SiteModelID}"); return(new SerialisedByteArrayWrapper(null)); } var result = executor.Execute(siteModel, arg.OTGCellBottomLeftX, arg.OTGCellBottomLeftY, arg.CellSize, arg.SurveyedSurfacePatchType, arg.IncludedSurveyedSurfaces, DIContext.ObtainRequired <IDesignFiles>(), siteModel.SurveyedSurfaces, arg.ProcessingMap); byte[] resultAsBytes = null; if (result != null) { try { resultAsBytes = result.ToBytes(); } finally { DIContext.Obtain <IClientLeafSubGridFactory>().ReturnClientSubGrid(ref result); } } return(new SerialisedByteArrayWrapper(resultAsBytes)); } catch (Exception e) { _log.LogError(e, "Exception requesting surveyed surface elevation patch"); return(new SerialisedByteArrayWrapper(null)); } }
public IRebuildSiteModelTAGNotifierEventSenderResponse Invoke(IRebuildSiteModelTAGNotifierEvent arg) { var localNodeId = Guid.Empty; try { var siteModels = DIContext.Obtain <ISiteModels>(); if (siteModels == null) { _log.LogError("No ISiteModels instance available from DIContext to send attributes change message to"); return(new RebuildSiteModelTAGNotifierEventSenderResponse { Success = false, NodeUid = localNodeId }); } localNodeId = DIContext.ObtainRequired <ITRexGridFactory>().Grid(siteModels.PrimaryMutability).GetCluster().GetLocalNode().Id; PerformRebuilderNotificationAction(arg); return(new RebuildSiteModelTAGNotifierEventSenderResponse { Success = true, NodeUid = localNodeId }); } catch (Exception e) { _log.LogError(e, "Exception occurred processing site model attributes changed event"); return(new RebuildSiteModelTAGNotifierEventSenderResponse { Success = false, NodeUid = localNodeId }); } }
public bool Invoke(Guid nodeId, IDesignChangedEvent message) { try { _log.LogInformation( $"Received notification of design changed for site:{message.SiteModelUid}, design:{message.DesignUid}, DesignType:{message.FileType}, DesignRemoved:{message.DesignRemoved}, ImportedFileType:{message.FileType}"); var designFiles = DIContext.ObtainOptional <IDesignFiles>(); if (designFiles == null) { // No cache, leave early... return(true); } var siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(message.SiteModelUid); if (siteModel == null) { _log.LogWarning($"No site model found for ID {message.SiteModelUid}"); return(true); } designFiles.DesignChangedEventHandler(message.DesignUid, siteModel, message.FileType); } catch (Exception e) { _log.LogError(e, "Exception occurred processing design changed event"); return(true); // Stay subscribed } finally { _log.LogInformation( $"Completed handling notification of design changed for Site:{message.SiteModelUid}, Design:{message.DesignUid}, DesignRemoved:{message.DesignRemoved}, ImportedFileType:{message.FileType}"); } return(true); }
/// <summary> /// Adds the given coordinate system to the identified project by placing the coordinate system /// into the mutable non spatial cache for the project. This will then be propagated to the immutable /// non spatial cache for the project /// Additionally, it notifies listeners of the coordinate system change. /// </summary> // ReSharper disable once IdentifierTypo public bool Execute(Guid projectUid, string csib) { // todo: Enrich return value to encode or provide additional information relating to failures try { // Tell the SiteModels instance to reload the designated site model that has changed var siteModels = DIContext.Obtain <ISiteModels>(); if (siteModels == null) { _log.LogError("No ISiteModels instance available from DIContext to send attributes change message to"); return(false); } var siteModel = siteModels.GetSiteModel(projectUid, true); if (siteModel == null) { _log.LogError($"Failed to obtain site model for UID = {projectUid}"); return(false); } if (siteModel.SetCSIB(csib)) { // Notify the grid listeners that attributes of this site model have changed. var sender = DIContext.ObtainRequired <ISiteModelAttributesChangedEventSender>(); sender.ModelAttributesChanged(SiteModelNotificationEventGridMutability.NotifyAll, siteModel.ID, CsibChanged: true); } } catch (Exception e) { _log.LogError(e, "Exception occurred adding coordinate system to project"); throw; } return(true); }
/// <summary> /// Executes the stationOffset logic in the cluster compute context where each cluster node processes its fraction of the work and returns the /// results to the application service context /// </summary> public async Task <StationOffsetReportRequestResponse_ClusterCompute> ExecuteAsync() { StationOffsetReportRequestResponse_ClusterCompute response = null; try { // Note: Start/end point lat/lon fields have been converted into grid local coordinate system by this point if (requestArgument.Points.Count > 0) { Log.LogInformation($"#In#: DataModel {requestArgument.ProjectID}, pointCount: {requestArgument.Points.Count}"); } else { Log.LogInformation($"#In#: DataModel {requestArgument.ProjectID}, Note! vertices list has insufficient vertices (min of 1 required)"); return(new StationOffsetReportRequestResponse_ClusterCompute { ResultStatus = RequestErrorStatus.OK, ReturnCode = ReportReturnCode.NoData }); } siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(requestArgument.ProjectID); if (siteModel == null) { Log.LogError($"Failed to locate site model {requestArgument.ProjectID}"); return(new StationOffsetReportRequestResponse_ClusterCompute { ResultStatus = RequestErrorStatus.NoSuchDataModel }); } return(response = GetProductionData()); } finally { Log.LogInformation( $"#Out# Execute: DataModel {requestArgument.ProjectID} complete for stationOffset report. #Result#:{response?.ResultStatus ?? RequestErrorStatus.Exception} with {response?.StationOffsetRows.Count ?? 0} offsets"); } }
public bool ExecutePipeline() { try { if (ActiveDesign != null && (VolumeType == VolumeComputationType.BetweenFilterAndDesign || VolumeType == VolumeComputationType.BetweenDesignAndFilter)) { if (ActiveDesign == null || ActiveDesign.Design.DesignDescriptor.IsNull) { _log.LogError($"No design provided to prod data/design volumes calc for datamodel {SiteModel.ID}"); VolumesRequestResponse.ResultStatus = RequestErrorStatus.NoDesignProvided; return(false); } } // Note: The execution context is on a compute cluster node already. However, the processor still performs the same function // within the local context. using var processor = DIContext.ObtainRequired <IPipelineProcessorFactory>().NewInstanceNoBuild <ProgressiveVolumesSubGridsRequestArgument> (requestDescriptor: RequestDescriptor, dataModelID: SiteModel.ID, gridDataType: GridDataType.ProgressiveVolumes, response: VolumesRequestResponse, cutFillDesign: null, filters: new FilterSet(Filter), task: DIContext.ObtainRequired <Func <PipelineProcessorTaskStyle, ITRexTask> >()(PipelineProcessorTaskStyle.ProgressiveVolumes), pipeline: DIContext.ObtainRequired <Func <PipelineProcessorPipelineStyle, ISubGridPipelineBase> >()(PipelineProcessorPipelineStyle.ProgressiveVolumes), requestAnalyser: DIContext.ObtainRequired <IRequestAnalyser>(), requestRequiresAccessToDesignFileExistenceMap: false, // Note: RefDesign != null || RefOriginal != null, requireSurveyedSurfaceInformation: false, //UseSurveyedSurfaces, //_filteredSurveyedSurfaces.Count > 0, overrideSpatialCellRestriction: BoundingIntegerExtent2D.Inverted(), liftParams: null ); // Assign the aggregator into the volumes computation task if (!(processor.Task is VolumesComputationTask volumesComputationTask)) { throw new ArgumentException($"Processor task for progressive volumes is not a {nameof(VolumesComputationTask)}, it is '{processor.Task}'"); } volumesComputationTask.Aggregator = Aggregator; // Create the initialization lambda to be applied to the sub grid request argument creation in the sub grid // pipeline processor execution context. if (processor is IPipelineProcessor <ProgressiveVolumesSubGridsRequestArgument> customProcessor) { customProcessor.CustomArgumentInitializer = arg => { arg.StartDate = StartDate; arg.EndDate = EndDate; arg.Interval = Interval; }; } processor.Task.RequestDescriptor = RequestDescriptor; if (!processor.Build()) { _log.LogError($"Failed to build pipeline processor for request to model {SiteModel.ID} with status {processor.Response.ResultStatus}"); VolumesRequestResponse.ResultStatus = processor.Response.ResultStatus; return(false); } processor.Process(); if (processor.Response.ResultStatus != RequestErrorStatus.OK) { _log.LogError($"Failed to compute progressive volumes data, for project: {SiteModel.ID}. response: {processor.Response.ResultStatus}."); VolumesRequestResponse.ResultStatus = processor.Response.ResultStatus; return(false); } return(true); } catch (Exception e) { _log.LogError(e, "Pipeline processor raised exception"); } return(false); }
/// <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"); } }
/// <summary> /// Performs execution business logic for this executor /// </summary> public ExportToGeometry Execute(Guid projectUid, Guid alignmentDesignUid, bool convertArcsToPolyLines, double arcChordTolerance) { try { var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(projectUid, false); if (siteModel == null) { _log.LogError($"Site model {projectUid} not found"); return(null); } if (convertArcsToPolyLines && arcChordTolerance < 0.001) { _log.LogError("Arc chord tolerance too small, must be >= 0.001 meters"); return(null); } var lockResult = DesignLoadResult.UnknownFailure; var design = DIContext.ObtainRequired <IDesignFiles>().Lock(alignmentDesignUid, siteModel, siteModel.CellSize, out lockResult); if (lockResult != DesignLoadResult.Success) { _log.LogError($"Failed to lock design with error {lockResult}"); return(null); } if (design == null) { _log.LogError($"Failed to read file for alignment {alignmentDesignUid}"); return(null); } if (!(design is SVLAlignmentDesign alignment)) { _log.LogError($"Design {alignmentDesignUid} is not an alignment"); return(null); } var master = alignment.GetMasterAlignment(); if (master == null) { _log.LogError($"Design {alignmentDesignUid} does not contain a master alignment"); return(null); } var geometryExporter = new ExportToGeometry { AlignmentLabelingInterval = 10, Units = DistanceUnitsType.Meters, ConvertArcsToPolyLines = convertArcsToPolyLines, ArcChordTolerance = arcChordTolerance }; var success = geometryExporter.ConstructSVLCenterlineAlignmentGeometry(master); if (!success) { _log.LogError($"Failed to generate geometry for alignment design {alignmentDesignUid}, error = {geometryExporter.CalcResult}"); } return(geometryExporter); } catch (Exception e) { _log.LogError(e, "Execute: Exception: "); return(null); } }
/// <summary> /// Executes the profiler /// </summary> public async Task <StationOffsetReportRequestResponse_ApplicationService> ExecuteAsync(StationOffsetReportRequestArgument_ApplicationService arg) { _log.LogInformation($"Start {nameof(ComputeStationOffsetReportExecutor_ApplicationService)}"); try { if (arg.Filters?.Filters != null && arg.Filters.Filters.Length > 0) { // Prepare the filters for use in stationOffset operations. Failure to prepare any filter results in this request terminating if (!(arg.Filters.Filters.Select(x => FilterUtilities.PrepareFilterForUse(x, arg.ProjectID)).All(x => x == RequestErrorStatus.OK))) { return(new StationOffsetReportRequestResponse_ApplicationService { ResultStatus = RequestErrorStatus.FailedToPrepareFilter }); } } // keep alignment design knowledge here and pass points var argClusterCompute = new StationOffsetReportRequestArgument_ClusterCompute { ProjectID = arg.ProjectID, Filters = arg.Filters, ReferenceDesign = arg.ReferenceDesign, TRexNodeID = arg.TRexNodeID, ReportElevation = arg.ReportElevation, ReportCmv = arg.ReportCmv, ReportMdp = arg.ReportMdp, ReportPassCount = arg.ReportPassCount, ReportTemperature = arg.ReportTemperature, ReportCutFill = arg.ReportCutFill, Points = new List <StationOffsetPoint>(), Overrides = arg.Overrides, LiftParams = arg.LiftParams }; var siteModel = DIContext.ObtainRequired <ISiteModels>().GetSiteModel(arg.ProjectID); var designFiles = DIContext.ObtainRequired <IDesignFiles>(); // alignment will convert interval/offsets into northing/eastings for the project var alignmentDesign = designFiles.Lock(arg.AlignmentDesignUid, siteModel, siteModel.CellSize, out var loadResult) as SVLAlignmentDesign; if (alignmentDesign == null || loadResult != DesignLoadResult.Success) { return(new StationOffsetReportRequestResponse_ApplicationService { ReturnCode = ReportReturnCode.NoData, ResultStatus = RequestErrorStatus.NoDesignProvided }); } try { argClusterCompute.Points = alignmentDesign.GetOffsetPointsInNEE(arg.CrossSectionInterval, arg.StartStation, arg.EndStation, arg.Offsets, out var calcResult); _log.LogInformation($"{nameof(StationOffsetReportRequestResponse_ApplicationService)}: pointCount: {argClusterCompute.Points.Count}, calcResult: {calcResult}"); if (argClusterCompute.Points.Count == 0) { return(new StationOffsetReportRequestResponse_ApplicationService { ReturnCode = ReportReturnCode.NoData, ResultStatus = RequestErrorStatus.NoProductionDataFound }); } } finally { designFiles.UnLock(arg.AlignmentDesignUid, alignmentDesign); } var request = new StationOffsetReportRequest_ClusterCompute(); var clusterComputeResponse = await request.ExecuteAsync(argClusterCompute); // Return the core package to the caller var applicationResponse = new StationOffsetReportRequestResponse_ApplicationService { ReturnCode = clusterComputeResponse.ReturnCode, ResultStatus = clusterComputeResponse.ResultStatus }; applicationResponse.LoadStationOffsets(clusterComputeResponse.StationOffsetRows); _log.LogInformation($"End {nameof(ComputeStationOffsetReportExecutor_ApplicationService)}: ReturnCode {applicationResponse.ReturnCode}."); return(applicationResponse); } catch (Exception e) { _log.LogError(e, $"{nameof(StationOffsetReportRequestResponse_ApplicationService)}: Unexpected exception."); throw; } }
/// <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"); } }
/// <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"); } }
public S3FileTransfer(TransferProxyType type) { _type = type; Proxy = DIContext.ObtainRequired <ITransferProxyFactory>().NewProxy(_type); }