Пример #1
0
        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)));
        }
Пример #2
0
        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;
            }
Пример #3
0
        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)
                       ));
        }
Пример #4
0
        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);
        }