예제 #1
0
        public async Task WhenWorkIsAddedAgainWhenPreviousIsAnalysing_ThenDontWaitAnotherOneToGetReady()
        {
            var now      = DateTime.UtcNow;
            var queue    = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 10 * 1000);
            var document = CreateTestDocumentId();

            queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground);

            now = PassOverThrotlingPeriod(now);

            var work        = queue.TakeWork(AnalyzerWorkType.Foreground);
            var waitingCall = Task.Run(async() => await queue.WaitForegroundWorkComplete());
            await Task.Delay(50);

            // User updates code -> document is queued again during period when theres already api call waiting
            // to continue.
            queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground);

            // First iteration of work is done.
            queue.WorkComplete(AnalyzerWorkType.Foreground);

            // Waiting call continues because its iteration of work is done, even when theres next
            // already waiting.
            await waitingCall;

            Assert.True(waitingCall.IsCompleted);
        }
예제 #2
0
        private async Task Worker(AnalyzerWorkType workType)
        {
            while (true)
            {
                try
                {
                    var currentWorkGroupedByProjects = _workQueue
                                                       .TakeWork(workType)
                                                       .Select(document => (project: document.Project, document))
                                                       .GroupBy(x => x.project, x => x.document)
                                                       .ToImmutableArray();

                    foreach (var projectGroup in currentWorkGroupedByProjects)
                    {
                        var projectPath = projectGroup.Key.FilePath;

                        EventIfBackgroundWork(workType, projectPath, ProjectDiagnosticStatus.Started);

                        await AnalyzeProject(projectGroup);

                        EventIfBackgroundWork(workType, projectPath, ProjectDiagnosticStatus.Ready);
                    }

                    _workQueue.WorkComplete(workType);

                    await Task.Delay(50);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Analyzer worker failed: {ex}");
                }
            }
        }
예제 #3
0
        public void WhenForegroundWorkIsUnderAnalysisOutFromQueueThenWaitUntilNextIterationOfItIsReady()
        {
            var now      = DateTime.UtcNow;
            var queue    = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 500);
            var document = CreateTestDocumentId();

            queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground);

            now = PassOverThrotlingPeriod(now);

            var work = queue.TakeWork(AnalyzerWorkType.Foreground);

            var pendingTask = queue.WaitForegroundWorkComplete();

            pendingTask.Wait(TimeSpan.FromMilliseconds(50));

            Assert.False(pendingTask.IsCompleted);
            queue.WorkComplete(AnalyzerWorkType.Foreground);
            pendingTask.Wait(TimeSpan.FromMilliseconds(50));
            Assert.True(pendingTask.IsCompleted);
        }
        private async Task Worker(AnalyzerWorkType workType)
        {
            while (true)
            {
                try
                {
                    var solution = _workspace.CurrentSolution;

                    var currentWorkGroupedByProjects = _workQueue
                                                       .TakeWork(workType)
                                                       .Select(documentId => (projectId: solution.GetDocument(documentId)?.Project?.Id, documentId))
                                                       .Where(x => x.projectId != null)
                                                       .GroupBy(x => x.projectId, x => x.documentId)
                                                       .ToImmutableArray();

                    foreach (var projectGroup in currentWorkGroupedByProjects)
                    {
                        var projectPath = solution.GetProject(projectGroup.Key).FilePath;

                        EventIfBackgroundWork(workType, projectPath, ProjectDiagnosticStatus.Started);

                        await AnalyzeAndReport(solution, projectGroup);

                        EventIfBackgroundWork(workType, projectPath, ProjectDiagnosticStatus.Ready);
                    }

                    _workQueue.WorkComplete(workType);

                    await Task.Delay(50);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Analyzer worker failed: {ex}");
                }
            }
        }