/// <summary> /// Saves a calculation that has been dispatched by the batchworker. /// </summary> /// <param name="calculation">The calculation.</param> /// <param name="sealingSlabs">The sealing slabs.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="dbInsertFactor">The database insert factor.</param> /// <exception cref="System.Exception"> /// </exception> private void SaveDispatched(Calculation calculation, IEnumerable <SealingSlab> sealingSlabs, CancellationToken cancellationToken, out double dbInsertFactor) { cancellationToken.ThrowIfCancellationRequested(); dbInsertFactor = 0; var stateRunning = stateDepot.GetByName(State.NameRunning); if (calculation.StateId != stateRunning.Id) { throw new Exception($"Not in state {stateRunning.Name} for saving dispatched calulation {calculation.Id}."); } if (sealingSlabs == null) { throw new Exception($"No sealing slabs for calulation {calculation.Id}."); } foreach (var sealingSlab in sealingSlabs) { sealingSlab.CalculationId = calculation.Id; } DateTime timeStart = DateTime.Now; int maxIteration = sealingSlabDepot.GetMaxIteration(calculation.Id); // Continue only with sealing slabs that haven't been saved yet. // Only take the defined amount of iterations. var iterationSealingSlabs = sealingSlabs .Where(x => x.Iteration > maxIteration && x.Iteration <= App.Config.SaveIterationsCount) .GroupBy(x => x.Iteration); foreach (var sealingSlabGroup in iterationSealingSlabs) { // Use transaction to make sealing slabs consistent per iteration. using (var transaction = database.GetTransaction()) { sealingSlabDepot.InsertBulk(sealingSlabGroup, App.Config.SealingSlabChunkSize); transaction.Complete(); cancellationToken.ThrowIfCancellationRequested(); } } var diff = (DateTime.Now - timeStart); double measuredSeconds = diff.TotalSeconds; int sealingSlabCount = iterationSealingSlabs.Sum(x => x.Count()); dbInsertFactor = EstimationService.CalculateDBInsertFactor(calculation.SealingSlabRadiusPixels, sealingSlabCount, measuredSeconds, App.Config.SealingSlabChunkSize); App.Logger.Info($"Calculated DBInsertFactor: {dbInsertFactor}."); var stateDone = stateDepot.GetByName(State.NameDone); calculation.StateId = stateDone.Id; calculationDepot.Save(calculation); // database }
/// <summary> /// Dispatches the calculation. /// </summary> /// <param name="calculation">The calculation.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="circleChunkSize">Size of the circle chunk.</param> private void DispatchCalculation(Calculation calculation, CancellationToken cancellationToken, int circleChunkSize) { App.Logger.Info($"Dispatch calculation {calculation.Id}..."); cancellationToken.ThrowIfCancellationRequested(); var stateCancelling = stateDepot.GetByName(State.NameCancelling); var stateRunning = stateDepot.GetByName(State.NameRunning); var plotter = calculationService.GetSealingSlabPlotter(calculation); calculation.StateId = stateRunning.Id; calculation.StartDate = DateTime.Now; double estimatedSeconds = GetEstimatedSeconds(plotter, calculation, circleChunkSize); if (estimatedSeconds > 0) { calculation.EstimatedEndDate = calculation.StartDate.Value.AddSeconds(estimatedSeconds); } calculation.EndDate = null; calculationDepot.Save(calculation); App.Logger.Info($"State of calculation {calculation.Id} set to {stateRunning.Name}."); var startTime = DateTime.Now; var unsetAreaResult = CalculateUnsetArea(calculation, plotter, cancellationToken); var allSealingSlabs = unsetAreaResult.IterationSealingSlabs.SelectMany(x => x).ToList(); double measuredSeconds = (DateTime.Now - startTime).TotalSeconds; double cpuFactor = EstimationService.CalculateCpuFactor(calculation.SealingSlabRadiusPixels, allSealingSlabs.Count(), measuredSeconds); App.Logger.Info($"Calculation time: {measuredSeconds}."); App.Logger.Info($"Calculated EstimationCPUFactor: {cpuFactor}."); calculation.UnsetAreaResult = (decimal)unsetAreaResult.FreeToTotalPixelRatio; calculation.ResidualWaterResult = calculationService.CalculateResidualWater(calculation); // Result is the most important part and can already be saved here. calculationDepot.Save(calculation); SaveCSVExport(calculation, unsetAreaResult); double dbInsertFactor = 0; SaveDispatched(calculation, allSealingSlabs, cancellationToken, out dbInsertFactor); // Save the estimation factors for cpu and db-insert operations. estimationService.Save(cpuFactor, dbInsertFactor); App.Logger.Info($"State of calculation {calculation.Id} set to done."); }
public DispatchService() { var databaseFactory = new NPocoDataBaseFactory(); database = databaseFactory.GetDatabase(); var databaseTimer = databaseFactory.GetDatabase(); stateDepot = new StateDepot(database); calculationDepot = new CalculationDepot(database); calculationDepotTimer = new CalculationDepot(databaseTimer); sealingSlabDepot = new SealingSlabDepot(database); calculationService = new CalculationService(stateDepot, calculationDepot, sealingSlabDepot, new CalculationViewDepot(database), databaseFactory); estimationService = new EstimationService(new EstimationDepot(database)); }
public DispatchService(StateDepot stateDepot, CalculationDepot calculationDepot, CalculationDepot calculationDepotTimer, SealingSlabDepot sealingSlabDepot, CalculationService calculationService, EstimationService estimationService, IDatabase database) { this.stateDepot = stateDepot; this.calculationDepot = calculationDepot; this.calculationDepotTimer = calculationDepotTimer; this.sealingSlabDepot = sealingSlabDepot; this.calculationService = calculationService; this.estimationService = estimationService; this.database = database; }