public void Test_StationOffsetReportRequestResponse_ClusterCompute_WithContent() { var rows = new List <StationOffsetRow> { new StationOffsetRow() { Station = 200, Offset = -1, Northing = 1, Easting = 2, Elevation = 3, CutFill = 4, Cmv = 5, Mdp = 6, PassCount = 7, Temperature = 8 }, new StationOffsetRow() { Station = 200, Offset = 0, Northing = 10, Easting = 11, Elevation = 12, CutFill = 13, Cmv = 14, Mdp = 15, PassCount = 16, Temperature = 17 } }; var rowList = new List <StationOffsetRow>(); rowList.AddRange(rows); var response = new StationOffsetReportRequestResponse_ClusterCompute() { ReturnCode = ReportReturnCode.NoError, ResultStatus = RequestErrorStatus.OK, StationOffsetRows = rowList }; SimpleBinarizableInstanceTester.TestClass(response, "Empty StationOffsetReportRequestResponse_ClusterCompute not same after round trip serialisation"); }
/// <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"); } }
/// <summary> /// For each point in the list, get the sub grid and extract productionData at the station/offset i.e pointOfInterest /// This could be optimized to get any poi from each sub grid before disposal /// </summary> private StationOffsetReportRequestResponse_ClusterCompute GetProductionData() { var result = new StationOffsetReportRequestResponse_ClusterCompute { ResultStatus = RequestErrorStatus.Unknown }; IDesignWrapper cutFillDesignWrapper = null; if (requestArgument.ReferenceDesign != null && requestArgument.ReferenceDesign.DesignID != Guid.Empty) { var cutFillDesign = siteModel.Designs.Locate(requestArgument.ReferenceDesign.DesignID); if (cutFillDesign == null) { throw new ArgumentException($"Design {requestArgument.ReferenceDesign.DesignID} not a recognized design in project {requestArgument.ProjectID}"); } cutFillDesignWrapper = new DesignWrapper(requestArgument.ReferenceDesign, cutFillDesign); } var existenceMap = siteModel.ExistenceMap; var utilities = DIContext.Obtain <IRequestorUtilities>(); var requestors = utilities.ConstructRequestors(null, siteModel, requestArgument.Overrides, requestArgument.LiftParams, utilities.ConstructRequestorIntermediaries(siteModel, requestArgument.Filters, true, GridDataType.CellProfile), AreaControlSet.CreateAreaControlSet(), existenceMap); // Obtain the primary partition map to allow this request to determine the elements it needs to process bool[] primaryPartitionMap = ImmutableSpatialAffinityPartitionMap.Instance().PrimaryPartitions(); SubGridTreeBitmapSubGridBits cellOverrideMask = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled); foreach (var point in requestArgument.Points) { // Determine the on-the-ground cell siteModel.Grid.CalculateIndexOfCellContainingPosition(point.Easting, point.Northing, out int OTGCellX, out int OTGCellY); var thisSubGridOrigin = new SubGridCellAddress(OTGCellX, OTGCellY); if (!primaryPartitionMap[thisSubGridOrigin.ToSpatialPartitionDescriptor()]) { continue; } // Get the sub grid relative cell location int cellX = OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask; int cellY = OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask; // Reach into the sub-grid request layer and retrieve an appropriate sub-grid cellOverrideMask.Clear(); cellOverrideMask.SetBit(cellX, cellY); requestors[0].CellOverrideMask = cellOverrideMask; // using the cell address get the index of cell in clientGrid var requestSubGridInternalResult = requestors[0].RequestSubGridInternal( thisSubGridOrigin, true, true); if (requestSubGridInternalResult.requestResult != ServerRequestResult.NoError) { Log.LogError($"Request for sub grid {thisSubGridOrigin} request failed with code {result}"); result.StationOffsetRows.Add(new StationOffsetRow(point.Station, point.Offset, point.Northing, point.Easting)); continue; } var hydratedPoint = ExtractRequiredValues(cutFillDesignWrapper, point, requestSubGridInternalResult.clientGrid as ClientCellProfileLeafSubgrid, cellX, cellY); result.StationOffsetRows.Add(hydratedPoint); } result.ResultStatus = RequestErrorStatus.OK; return(result); }