private OutputRequest FulfilRequest(Simulation simulation, SimInput serieInput) { Log.Debug($"{nameof(SimData)} retrieving output"); var serie = simulation.LoadData(serieInput); _outputs.TryAdd( (serieInput.Hash, simulation), SimDataOutput.Create(simulation, serieInput, serie, OutputOrigin.Storage, DateTime.UtcNow, false) ); return(OutputRequest.Create(serieInput, Array(serieInput))); }
private ProcessingOutcome Process( SimDataItem <OutputRequest> simDataItem, CancellationToken cancellationToken, out Task <OutputRequest?> outputRequestTask ) { var simulation = simDataItem.Simulation; var seriesInput = simDataItem.Item.SeriesInput; ProcessingOutcome processingOutcome; if (_outputs.TryGetValue((seriesInput.Hash, simulation), out SimDataOutput _)) { outputRequestTask = Task.FromResult <OutputRequest?>(OutputRequest.Create(seriesInput, Array(seriesInput))); processingOutcome = ProcessingOutcome.AlreadyAcquired; }
private async Task <OutputRequest> FulfilRequestAsync( Simulation simulation, SimInput seriesInput, ServerLicense serverLicense, bool persist, CancellationToken cancellationToken) { var serieInputs = await EvaluateNonScalarsAsync( seriesInput, simulation.SimConfig.SimInput, serverLicense, cancellationToken ); Log.Debug($"Evaluating non-scalar parameter values produced n={serieInputs.Count} series"); var useExec = simulation.SimConfig.SimCode.Exec.IsAString(); async Task <(SimInput SerieInput, NumDataTable Serie, bool Persist, OutputOrigin OutputOrigin)> AcquireSerieDataAsync(SimInput serieInput) { if (simulation.HasData(serieInput)) { Log.Debug($"{nameof(SimData)} retrieving data"); var retrieved = simulation.LoadData(serieInput); return(serieInput, retrieved, false, OutputOrigin.Storage); } Log.Debug($"{nameof(SimData)} generating data"); var serieConfig = simulation.SimConfig.With(serieInput); NumDataTable serie; var stopWatch = Stopwatch.StartNew(); if (simulation.IsRSimulation()) { var client = await serverLicense.GetRClientAsync(cancellationToken); if (useExec) { var pathToCodeFile = simulation.PathToCodeFile; RequireFile(pathToCodeFile); await client.RunExecAsync(pathToCodeFile, serieConfig, cancellationToken); serie = await client.TabulateExecOutputAsync(serieConfig, cancellationToken); } else { var pathToCodeFile = simulation.PopulateTemplate(serieConfig.SimInput.SimParameters); await client.SourceFileAsync(pathToCodeFile, cancellationToken); serie = await client.TabulateTmplOutputAsync(serieConfig, cancellationToken); } } else { var mcsimExecutor = serverLicense.GetMCSimExecutor(simulation); var numDataTable = mcsimExecutor.Execute(serieConfig.SimInput.SimParameters); RequireNotNull(numDataTable, "MCSim execution failed"); serie = numDataTable; } stopWatch.Stop(); var msElapsed = 1000L * stopWatch.ElapsedTicks / Stopwatch.Frequency; lock (_syncLock) { if (!_executionIntervals.TryGetValue(simulation, out SimExecutionInterval? executionInterval)) { executionInterval = new SimExecutionInterval(simulation); executionInterval.Load(); _executionIntervals.Add(simulation, executionInterval); } executionInterval.AddInterval(msElapsed); } return(serieInput, serie, persist, OutputOrigin.Generation); } var outputs = (await Task.WhenAll(serieInputs.Map(AcquireSerieDataAsync))).ToArr(); var outputsRequiringPersistence = outputs .Filter(t => { var didAdd = _outputs.TryAdd( (t.SerieInput.Hash, simulation), SimDataOutput.Create(simulation, t.SerieInput, t.Serie, t.OutputOrigin, DateTime.UtcNow, t.Persist) ); return(didAdd && t.Persist); }); if (!outputsRequiringPersistence.IsEmpty) { _mreDataService.Set(); } return(OutputRequest.Create( seriesInput, outputs.Map(t => t.SerieInput) )); }
private int AcquireOutputsImpl(CancellationToken cancellationToken) { var snapshot = _outputRequests .ToArray() .OrderBy(kvp => kvp.Value.RequestedOn); var nAwaitingServerLicense = 0; foreach (var item in snapshot) { var simDataItem = item.Value; try { Log.Debug($"{nameof(SimData)} processing {simDataItem.Item.SeriesInput.Hash} output request..."); var outcome = Process(simDataItem, cancellationToken, out Task <OutputRequest?> outputRequestTask); cancellationToken.ThrowIfCancellationRequested(); if (outcome == ProcessingOutcome.AlreadyAcquired || outcome == ProcessingOutcome.AcquiringData) { _outputRequests.TryRemove(item.Key, out SimDataItem <OutputRequest> _); outputRequestTask.ContinueWith(task => { OutputRequest outputRequest; if (task.IsFaulted) { RequireNotNull(task.Exception?.InnerException); outputRequest = OutputRequest.Create( simDataItem.Item.SeriesInput, task.Exception.InnerException ); } else { RequireNotNull(task.Result); outputRequest = task.Result; } var fulfilled = SimDataItem.Create( outputRequest, simDataItem.Simulation, simDataItem.Requester, simDataItem.RequestToken, simDataItem.RequestedOn, DateTime.UtcNow ); _outputRequestsSubject.OnNext(fulfilled); Log.Debug($"{nameof(SimData)} fulfilled {simDataItem.Item.SeriesInput.Hash} output request on {fulfilled.FulfilledOn}"); }, cancellationToken); } else if (outcome == ProcessingOutcome.NoServerAvailable) { ++nAwaitingServerLicense; } else { throw new InvalidOperationException($"Unhandled processing outcome: {outcome}"); } } catch (Exception ex) { _outputRequests.TryRemove(item.Key, out SimDataItem <OutputRequest> _); var fulfilled = SimDataItem.Create( OutputRequest.Create(simDataItem.Item.SeriesInput, ex), simDataItem.Simulation, simDataItem.Requester, simDataItem.RequestToken, simDataItem.RequestedOn, DateTime.UtcNow ); _outputRequestsSubject.OnNext(fulfilled); } } return(nAwaitingServerLicense); }