private void ConfigurePipeline(SubGridPipelineAggregative <SubGridsRequestArgument, SimpleVolumesResponse> PipeLine) { //PipeLine.TimeToLiveSeconds := VLPDSvcLocations.VLPDPSNode_VolumePipelineTTLSeconds; PipeLine.RequestDescriptor = RequestDescriptor; //PipeLine.ExternalDescriptor := FExternalDescriptor; PipeLine.DataModelID = SiteModel.ID; Log.LogDebug($"Volume calculation extents for DM={SiteModel.ID}, Request={RequestDescriptor}: {Extents}"); PipeLine.OverallExistenceMap = OverallExistenceMap; PipeLine.ProdDataExistenceMap = ProdDataExistenceMap; PipeLine.DesignSubGridOverlayMap = DesignSubgridOverlayMap; // Initialise a request analyzer to provide to the pipeline PipeLine.RequestAnalyser = DIContext.Obtain <IRequestAnalyser>(); PipeLine.RequestAnalyser.Pipeline = PipeLine; PipeLine.RequestAnalyser.WorldExtents.Assign(Extents); PipeLine.LiftParams = LiftParams; // Construct and assign the filter set into the pipeline IFilterSet FilterSet = FilterUtilities.ConstructFilters(new FilterSet(BaseFilter, TopFilter), VolumeType); if (FilterSet.Filters.Length == 3) { PipeLine.SubGridsRequestComputeStyle = SubGridsRequestComputeStyle.SimpleVolumeThreeWayCoalescing; } PipeLine.FilterSet = FilterSet; PipeLine.GridDataType = GridDataType.Height; if (FilteredTopSurveyedSurfaces.Count > 0 || FilteredBaseSurveyedSurfaces.Count > 0) { PipeLine.IncludeSurveyedSurfaceInformation = true; } }
public RequestErrorStatus ExecutePipeline() { SubGridPipelineAggregative <SubGridsRequestArgument, SimpleVolumesResponse> PipeLine; var Result = RequestErrorStatus.Unknown; var PipelineAborted = false; // bool ShouldAbortDueToCompletedEventSet = false; try { ProdDataExistenceMap = SiteModel.ExistenceMap; 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}"); return(RequestErrorStatus.NoDesignProvided); } DesignSubgridOverlayMap = GetExistenceMaps().GetSingleExistenceMap(SiteModel.ID, ExistenceMaps.Interfaces.Consts.EXISTENCE_MAP_DESIGN_DESCRIPTOR, ActiveDesign.Design.ID); if (DesignSubgridOverlayMap == null) { return(RequestErrorStatus.NoDesignProvided); } } OverallExistenceMap = new SubGridTreeSubGridExistenceBitMask(); // Work out the surveyed surfaces and coverage areas that need to be taken into account var SurveyedSurfaces = SiteModel.SurveyedSurfaces; if (SurveyedSurfaces != null) { // See if we need to handle surveyed surface data for 'base' // Filter out any surveyed surfaces which don't match current filter (if any) - realistically, this is time filters we're thinking of here if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenFilterAndDesign) { if (!SurveyedSurfaces.ProcessSurveyedSurfacesForFilter(SiteModel.ID, BaseFilter, FilteredTopSurveyedSurfaces, FilteredBaseSurveyedSurfaces, OverallExistenceMap)) { return(RequestErrorStatus.Unknown); } } // See if we need to handle surveyed surface data for 'top' // Filter out any surveyed surfaces which don't match current filter (if any) - realistically, this is time filters we're thinking of here if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenDesignAndFilter) { if (!SurveyedSurfaces.ProcessSurveyedSurfacesForFilter(SiteModel.ID, TopFilter, FilteredBaseSurveyedSurfaces, FilteredTopSurveyedSurfaces, OverallExistenceMap)) { return(RequestErrorStatus.Unknown); } } } // Add in the production data existence map to the computed surveyed surfaces existence maps OverallExistenceMap.SetOp_OR(ProdDataExistenceMap); // If necessary, impose spatial constraints from filter design(s) if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenFilterAndDesign) { if (!DesignFilterUtilities.ProcessDesignElevationsForFilter(SiteModel, BaseFilter, OverallExistenceMap)) { return(RequestErrorStatus.Unknown); } } if (VolumeType == VolumeComputationType.Between2Filters || VolumeType == VolumeComputationType.BetweenDesignAndFilter) { if (!DesignFilterUtilities.ProcessDesignElevationsForFilter(SiteModel, TopFilter, OverallExistenceMap)) { return(RequestErrorStatus.Unknown); } } var PipelinedTask = new VolumesComputationTask { Aggregator = Aggregator }; try { PipeLine = new SubGridPipelineAggregative <SubGridsRequestArgument, SimpleVolumesResponse>(/*0, */ PipelinedTask); PipelinedTask.PipeLine = PipeLine; ConfigurePipeline(PipeLine); if (PipeLine.Initiate()) { var completionResult = PipeLine.WaitForCompletion(); Log.LogInformation(completionResult ? "WaitForCompletion successful" : $"WaitForCompletion timed out with {PipeLine.SubGridsRemainingToProcess} sub grids remaining to be processed"); if (PipeLine.SubGridsRemainingToProcess > 0) { Log.LogInformation($"Pipeline completed with {PipeLine.SubGridsRemainingToProcess} sub grids remaining to be processed"); } } /* * while not FPipeLine.AllFinished and not FPipeLine.PipelineAborted do * begin * WaitResult := FPipeLine.CompleteEvent.WaitFor(5000); * * if VLPDSvcLocations.Debug_EmitSubgridPipelineProgressLogging then * begin * if ((FEpochCount > 0) or (FPipeLine.SubmissionNode.TotalNumberOfSubgridsScanned > 0)) and * ((FPipeLine.OperationNode.NumPendingResultsReceived > 0) or (FPipeLine.OperationNode.OustandingSubgridsToOperateOn > 0)) then * SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d, model %d): #Progress# - Scanned = %d, Submitted = %d, Processed = %d (with %d pending and %d results outstanding)', * [Self.ClassName, * FRequestDescriptor, FPipeline.ProjectUid, * FPipeLine.SubmissionNode.TotalNumberOfSubgridsScanned, * FPipeLine.SubmissionNode.TotalSumbittedSubgridRequests, * FPipeLine.OperationNode.TotalOperatedOnSubgrids, * FPipeLine.OperationNode.NumPendingResultsReceived, * FPipeLine.OperationNode.OustandingSubgridsToOperateOn]), slmcDebug); * end; * * if (WaitResult = wrSignaled) and not FPipeLine.AllFinished and not FPipeLine.PipelineAborted and not FPipeLine.Terminated then * begin * if ShouldAbortDueToCompletedEventSet then * begin * if (FPipeLine.OperationNode.NumPendingResultsReceived > 0) or (FPipeLine.OperationNode.OustandingSubgridsToOperateOn > 0) then * SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d, model %d) being aborted as it''s completed event has remained set but still has work to do (%d outstanding subgrids, %d pending results to process) over a sleep epoch', * [Self.ClassName, * FRequestDescriptor, FPipeline.ProjectUid, * FPipeLine.OperationNode.OustandingSubgridsToOperateOn, * FPipeLine.OperationNode.NumPendingResultsReceived]), slmcError); * FPipeLine.Abort; * ASNodeImplInstance.AsyncResponder.ASNodeResponseProcessor.PerformTaskCancellation(FPipelinedTask); * Exit; * end * else * begin * if (FPipeLine.OperationNode.NumPendingResultsReceived > 0) or (FPipeLine.OperationNode.OustandingSubgridsToOperateOn > 0) then * SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d, model %d) has it''s completed event set but still has work to do (%d outstanding subgrids, %d pending results to process)', * [Self.ClassName, * FRequestDescriptor, FPipeline.ProjectUid, * FPipeLine.OperationNode.OustandingSubgridsToOperateOn, * FPipeLine.OperationNode.NumPendingResultsReceived]), slmcDebug); * Sleep(500); * ShouldAbortDueToCompletedEventSet := True; * end; * end; * * if FPipeLine.TimeToLiveExpired then * begin * FAbortedDueToTimeout := True; * FPipeLine.Abort; * ASNodeImplInstance.AsyncResponder.ASNodeResponseProcessor.PerformTaskCancellation(FPipelinedTask); * * // The pipeline has exceed its allotted time to complete. It will now * // be aborted and this request will be failed. * SIGLogMessage.PublishNoODS(Self, Format('%s: Pipeline (request %d) aborted due to time to live expiration (%d seconds)', * [Self.ClassName, FRequestDescriptor, FPipeLine.TimeToLiveSeconds]), slmcError); * Exit; * end; */ PipelineAborted = PipeLine.Aborted; if (!PipeLine.Terminated && !PipeLine.Aborted) { Result = RequestErrorStatus.OK; } } finally { if (AbortedDueToTimeout) { Result = RequestErrorStatus.AbortedDueToPipelineTimeout; } else if (PipelinedTask.IsCancelled || PipelineAborted) { Result = RequestErrorStatus.RequestHasBeenCancelled; } } } catch (Exception e) { Log.LogError(e, "ExecutePipeline raised exception"); } return(Result); } catch (Exception e) { Log.LogError(e, "Exception"); } return(RequestErrorStatus.Unknown); }