Beispiel #1
0
        async Task <bool> IManager.RunPostprocessor(
            KeyValuePair <ILogSourcePostprocessor, ILogSource>[] typesAndSources,
            object customData)
        {
            var sources = typesAndSources.Select(typesAndSource =>
            {
                var outputType   = typesAndSource.Key;
                var forLogSource = typesAndSource.Value;

                if (!knownLogSources.TryGetValue(forLogSource, out LogSourceRecord logSourceRecord))
                {
                    throw new ArgumentException("Log source is unknown");
                }

                var postprocessorRecord = logSourceRecord.PostprocessorsOutputs.SingleOrDefault(parserRec => parserRec.metadata == outputType);
                if (postprocessorRecord == null)
                {
                    throw new ArgumentException("Bad Postprocessor output type: " + outputType.Kind.ToString());
                }

                if (postprocessorRecord.state.PostprocessorNeedsRunning == null)
                {
                    throw new InvalidOperationException("Can not start postprocessor in this state");
                }

                string outputFileName;
                using (var section = forLogSource.LogSourceSpecificStorageEntry.OpenXMLSection(
                           outputType.MakePostprocessorOutputFileName(), Persistence.StorageSectionOpenFlag.ReadOnly))
                    outputFileName = section.AbsolutePath;

                bool needsProcessing = logSourceRecord.logSource.Visible && postprocessorRecord.state.PostprocessorNeedsRunning == true;
                needsProcessing     |= crossLogSourcePostprocessorsTypes.Contains(postprocessorRecord.metadata);

                var sourceContentsEtag = logSourceRecord.logSource.Provider.Stats.ContentsEtag?.ToString();

                return(new
                {
                    OutputType = outputType,
                    PostprocessorInput = logSourceRecord.ToPostprocessorInput(
                        outputFileName, sourceContentsEtag, customData
                        ),
                    PostprocessorRecord = postprocessorRecord,
                    LogSourceMeta = logSourceRecord.metadata,
                    LogSource = logSourceRecord.logSource,
                    NeedsProcessing = needsProcessing,
                    TemplatesTracker = new TemplatesTracker(),
                    IsSelected = new Ref <bool>()
                });
            }).ToList();

            bool noLogNeedsProcessing = sources.All(s => !s.NeedsProcessing);

            if (noLogNeedsProcessing)
            {
                sources.ForEach(s => s.IsSelected.Value = true);
            }
            else
            {
                sources.ForEach(s => s.IsSelected.Value = s.NeedsProcessing);
            }

            var outerTasks = new List <Task>();

            foreach (var postprocessorTypeGroup in sources.Where(s => s.IsSelected.Value).GroupBy(s => s.OutputType))
            {
                var postprocessorProgress = progressAggregator.CreateChildAggregator();
                postprocessorProgress.ProgressChanged += (s, e) => FireChangedEvent();

                var innerTask = RunPostprocessorBody(async() =>
                {
                    IPostprocessorRunSummary summary;
                    using (var progressSinks = new ProgressSinksCollection())
                    {
                        summary = await postprocessorTypeGroup.Key.Run(
                            postprocessorTypeGroup
                            .Select(s => s
                                    .PostprocessorInput
                                    .AttachProgressHandler(postprocessorProgress, progressSinks.Sinks)
                                    .SetTemplatesTracker(s.TemplatesTracker)
                                    )
                            .ToArray()
                            );
                    }
                    foreach (var p in postprocessorTypeGroup)
                    {
                        telemetry.ReportUsedFeature(
                            MakeLogSourcePostprocessorFeatureId(p.LogSourceMeta, postprocessorTypeGroup.Key),
                            p.TemplatesTracker.GetUsedTemplates()
                            );
                    }
                    return(summary);
                });

                foreach (var postprocessorRecord in postprocessorTypeGroup.Select(s => s.PostprocessorRecord))
                {
                    var flowCompletion = new TaskCompletionSource <int>();
                    postprocessorRecord.SetState(new RunningState(postprocessorRecord.state.ctx, innerTask, postprocessorProgress, flowCompletion));
                    outerTasks.Add(flowCompletion.Task);
                }
            }

            Refresh();

            await Task.WhenAll(outerTasks);

            return(true);
        }
        async Task <bool> IPostprocessorsManager.RunPostprocessor(
            KeyValuePair <ILogSourcePostprocessor, ILogSource>[] typesAndSources,
            bool forceSourcesSelection, object customData)
        {
            var sources = typesAndSources.Select(typesAndSource =>
            {
                var outputType   = typesAndSource.Key;
                var forLogSource = typesAndSource.Value;

                LogSourceRecordInternal logSourceRecord;
                if (!knownLogSources.TryGetValue(forLogSource, out logSourceRecord))
                {
                    throw new ArgumentException("Log source is unknown");
                }

                var postprocessorRecord = logSourceRecord.PostprocessorsOutputs.SingleOrDefault(parserRec => parserRec.Metadata == outputType);
                if (postprocessorRecord == null)
                {
                    throw new ArgumentException("Bad Postprocessor output type: " + outputType.TypeID);
                }

                if (postprocessorRecord.status == LogSourcePostprocessorOutput.Status.InProgress)
                {
                    throw new InvalidOperationException("Postprocessor output for log source is already being generated");
                }

                string outputFileName;
                using (var section = forLogSource.LogSourceSpecificStorageEntry.OpenXMLSection(
                           MakePostprocessorOutputFileName(outputType), Persistence.StorageSectionOpenFlag.ReadOnly))
                    outputFileName = section.AbsolutePath;

                bool needsProcessing =
                    logSourceRecord.logSource.Visible && (
                        postprocessorRecord.status == LogSourcePostprocessorOutput.Status.NeverRun ||
                        postprocessorRecord.status == LogSourcePostprocessorOutput.Status.Failed ||
                        postprocessorRecord.status == LogSourcePostprocessorOutput.Status.Outdated);
                needsProcessing |= crossLogSourcePostprocessorsTypes.Contains(postprocessorRecord.Metadata);

                XAttribute contentsEtagAttr = null;
                var sourceContentsEtag      = logSourceRecord.logSource.Provider.Stats.ContentsEtag;
                if (sourceContentsEtag != null)
                {
                    contentsEtagAttr = new XAttribute(
                        XName.Get("etag", xmlNs),
                        logSourceRecord.logSource.Provider.Stats.ContentsEtag
                        );
                }

                return(new
                {
                    OutputType = outputType,
                    PostprocessorInput = logSourceRecord.ToPostprocessorInput(
                        outputFileName, contentsEtagAttr, customData
                        ),
                    PostprocessorRecord = postprocessorRecord,
                    LogSourceMeta = logSourceRecord.metadata,
                    LogSource = logSourceRecord.logSource,
                    NeedsProcessing = needsProcessing,
                    UILogSourceInfo = new LogsSourcesSelectorDialogParams.LogSourceInfo()
                    {
                        Description = forLogSource.GetShortDisplayNameWithAnnotation()
                    },
                    TemplatesTracker = new TemplatesTracker()
                });
            }).ToList();

            bool noLogNeedsProcessing = sources.All(s => !s.NeedsProcessing);

            if (noLogNeedsProcessing)
            {
                sources.ForEach(s => s.UILogSourceInfo.IsSelected = true);
            }
            else
            {
                sources.ForEach(s => s.UILogSourceInfo.IsSelected = s.NeedsProcessing);
            }

            if (forceSourcesSelection && userInteractions != null)
            {
                if (!await userInteractions.ShowLogsSourcesSelectorDialog(new LogsSourcesSelectorDialogParams()
                {
                    LogSources = sources.Select(s => s.UILogSourceInfo).ToList()
                }, CancellationToken.None))
                {
                    return(false);
                }
            }

            var outerTasks = new List <Task>();

            foreach (var postprocessorTypeGroup in sources.Where(s => s.UILogSourceInfo.IsSelected).GroupBy(s => s.OutputType))
            {
                var postprocessorProgress = progressAggregator.CreateChildAggregator();
                postprocessorProgress.ProgressChanged += (s, e) => RefreshInternal(assumeSomethingChanging: true);

                var innerTask = RunPostprocessor(async() =>
                {
                    IPostprocessorRunSummary summary;
                    using (var progressSinks = new ProgressSinksCollection())
                    {
                        summary = await postprocessorTypeGroup.Key.Run(
                            postprocessorTypeGroup
                            .Select(s => s
                                    .PostprocessorInput
                                    .AttachProgressHandler(postprocessorProgress, progressSinks.Sinks)
                                    .SetTemplatesTracker(s.TemplatesTracker)
                                    )
                            .ToArray()
                            );
                    }
                    foreach (var p in postprocessorTypeGroup)
                    {
                        telemetry.ReportUsedFeature(
                            MakeLogSourcePostprocessorFeatureId(p.LogSourceMeta, postprocessorTypeGroup.Key),
                            p.TemplatesTracker.GetUsedTemplates()
                            );
                    }
                    return(summary);
                });
                outerTasks.Add(AwaitOnPostprocessorTaskAndUpdate(innerTask));

                foreach (var postprocessorRecord in postprocessorTypeGroup.Select(s => s.PostprocessorRecord))
                {
                    postprocessorRecord.postprocessorTask     = innerTask;
                    postprocessorRecord.postprocessorProgress = postprocessorProgress;
                }
            }

            RefreshInternal();

            await Task.WhenAll(outerTasks);

            return(true);
        }