private void ObserveOutputRequest(SimDataItem <OutputRequest> simDataItem) { if (simDataItem.IsResetEvent()) { return; } simDataItem.Item.SerieInputs.IfRight( o => LogOutputRequest(simDataItem, o) ); }
private void LogOutputRequest(SimDataItem <OutputRequest> simDataItem, Arr <SimInput> serieInputs) { var requesterTypeName = simDataItem.Requester.GetType().Name; var description = simDataItem.GetDescription(); var simulation = simDataItem.Simulation; var defaultInput = simulation.SimConfig.SimInput; var logging = serieInputs .Map(i => { var outputInfo = _simData.GetOutputInfo(i, simulation); return(outputInfo.Match( oi => Some((Input: i, oi.SerieInput.Hash, oi.Persist)), () => None )); }) .Somes() .Map(t => new { LogEntry = new SimDataLogEntry( ++_logIndex, DateTime.UtcNow, t.Hash, defaultInput.GetEdits(t.Input).ToAssignments(), requesterTypeName, description ), t.Persist }) .ToArr(); logging .Filter(l => l.Persist) .Iter(l => _pendingToFile.Enqueue((simulation, l.LogEntry))); var sessionLogIsRequester = requesterTypeName == ToString(); if (!sessionLogIsRequester) { var logEntries = logging.Map(l => l.LogEntry); lock (_logEntriesSyncLock) { _logEntries.AddRange(logEntries); } logEntries.Iter(le => _logEntriesSubject.OnNext(le)); } }
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 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); }