コード例 #1
0
        public async Task UpdatePrimaryWorkspaceAsync(Checksum solutionChecksum, CancellationToken cancellationToken)
        {
            var currentSolution = s_primaryWorkspace.CurrentSolution;

            var primarySolutionChecksum = await currentSolution.State.GetChecksumAsync(cancellationToken).ConfigureAwait(false);

            if (primarySolutionChecksum == solutionChecksum)
            {
                // nothing changed
                return;
            }

            using (await s_gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false))
            {
                var updater = new SolutionCreator(_assetService, currentSolution, cancellationToken);

                if (await updater.IsIncrementalUpdateAsync(solutionChecksum).ConfigureAwait(false))
                {
                    // solution has updated
                    s_primaryWorkspace.UpdateSolution(await updater.CreateSolutionAsync(solutionChecksum).ConfigureAwait(false));
                    return;
                }

                // new solution. bulk sync all asset for the solution
                await _assetService.SynchronizeSolutionAssetsAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

                s_primaryWorkspace.ClearSolution();
                s_primaryWorkspace.AddSolution(await updater.CreateSolutionInfoAsync(solutionChecksum).ConfigureAwait(false));
            }
        }
コード例 #2
0
ファイル: SolutionService.cs プロジェクト: ideafirm/roslyn
        private async Task <Solution> CreateSolution_NoLockAsync(Checksum solutionChecksum, Solution baseSolution, CancellationToken cancellationToken)
        {
            var updater = new SolutionCreator(_assetService, baseSolution, cancellationToken);

            if (await updater.IsIncrementalUpdateAsync(solutionChecksum).ConfigureAwait(false))
            {
                // solution has updated
                return(await updater.CreateSolutionAsync(solutionChecksum).ConfigureAwait(false));
            }

            // new solution. bulk sync all asset for the solution
            await _assetService.SynchronizeSolutionAssetsAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

            var workspace = new TemporaryWorkspace(await updater.CreateSolutionInfoAsync(solutionChecksum).ConfigureAwait(false));

            return(workspace.CurrentSolution);
        }
コード例 #3
0
        /// <summary>
        /// SolutionService is designed to be stateless. if someone asks a solution (through solution checksum),
        /// it will create one and return the solution. the engine takes care of synching required data and creating a solution
        /// correspoing to the given checksum.
        ///
        /// but doing that from scratch all the time wil be expansive in terms of synching data, compilation being cached, file being parsed
        /// and etc. so even if the service itself is stateless, internally it has several caches to improve perf of various parts.
        ///
        /// first, it holds onto last solution got built. this will take care of common cases where multiple services running off same solution.
        /// second, it uses assets cache to hold onto data just synched (within 3 min) so that if it requires to build new solution,
        ///         it can save some time to re-sync data which might just used by other solution.
        /// third, it holds onto solution from primary branch from Host. and it will try to see whether it can build new solution off the
        ///        primary solution it is holding onto. this will make many solution level cache to be re-used.
        ///
        /// the primary solution can be updated in 2 ways.
        /// first, host will keep track of primary solution changes in host, and call OOP to synch to latest time to time.
        /// second, engine keeps track of whether a certain request is for primary solution or not, and if it is,
        ///         it let that request to update primary solution cache to latest.
        ///
        /// these 2 are complimentary to each other. #1 makes OOP's primary solution to be ready for next call (push), #2 makes OOP's primary
        /// solution be not stale as much as possible. (pull)
        /// </summary>
        private async Task <Solution> CreateSolution_NoLockAsync(
            Checksum solutionChecksum,
            bool fromPrimaryBranch,
            int workspaceVersion,
            Solution baseSolution,
            CancellationToken cancellationToken)
        {
            try
            {
                var updater = new SolutionCreator(_assetService, baseSolution, cancellationToken);

                // check whether solution is update to the given base solution
                if (await updater.IsIncrementalUpdateAsync(solutionChecksum).ConfigureAwait(false))
                {
                    // create updated solution off the baseSolution
                    var solution = await updater.CreateSolutionAsync(solutionChecksum).ConfigureAwait(false);

                    if (fromPrimaryBranch)
                    {
                        // if the solutionChecksum is for primary branch, update primary workspace cache with the solution
                        return(PrimaryWorkspace.UpdateSolutionIfPossible(solution, workspaceVersion));
                    }

                    // otherwise, just return the solution
                    return(solution);
                }

                // we need new solution. bulk sync all asset for the solution first.
                await _assetService.SynchronizeSolutionAssetsAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

                // get new solution info and options
                var(solutionInfo, options) = await GetSolutionInfoAndOptionsAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

                if (fromPrimaryBranch)
                {
                    // if the solutionChecksum is for primary branch, update primary workspace cache with new solution
                    if (PrimaryWorkspace.TryAddSolutionIfPossible(solutionInfo, workspaceVersion, options, out var solution))
                    {
                        return(solution);
                    }
                }

                // otherwise, just return new solution
                var workspace = new TemporaryWorkspace(solutionInfo, options);
                return(workspace.CurrentSolution);
            }
            catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceledAndPropagate(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
コード例 #4
0
ファイル: SolutionService.cs プロジェクト: zuvys/roslyn
        /// <summary>
        /// SolutionService is designed to be stateless. if someone asks a solution (through solution checksum),
        /// it will create one and return the solution. the engine takes care of synching required data and creating a solution
        /// correspoing to the given checksum.
        ///
        /// but doing that from scratch all the time wil be expansive in terms of synching data, compilation being cached, file being parsed
        /// and etc. so even if the service itself is stateless, internally it has several caches to improve perf of various parts.
        ///
        /// first, it holds onto last solution got built. this will take care of common cases where multiple services running off same solution.
        /// second, it uses assets cache to hold onto data just synched (within 3 min) so that if it requires to build new solution,
        ///         it can save some time to re-sync data which might just used by other solution.
        /// third, it holds onto solution from primary branch from Host. and it will try to see whether it can build new solution off the
        ///        primary solution it is holding onto. this will make many solution level cache to be re-used.
        ///
        /// the primary solution can be updated in 2 ways.
        /// first, host will keep track of primary solution changes in host, and call OOP to synch to latest time to time.
        /// second, engine keeps track of whether a certain request is for primary solution or not, and if it is,
        ///         it let that request to update primary solution cache to latest.
        ///
        /// these 2 are complimentary to each other. #1 makes OOP's primary solution to be ready for next call (push), #2 makes OOP's primary
        /// solution be not stale as much as possible. (pull)
        /// </summary>
        private async Task <Solution> CreateSolution_NoLockAsync(
            Checksum solutionChecksum,
            bool fromPrimaryBranch,
            int workspaceVersion,
            Solution baseSolution,
            CancellationToken cancellationToken)
        {
            var updater = new SolutionCreator(_assetService, baseSolution, cancellationToken);

            // check whether solution is update to the given base solution
            if (await updater.IsIncrementalUpdateAsync(solutionChecksum).ConfigureAwait(false))
            {
                // create updated solution off the baseSolution
                var solution = await updater.CreateSolutionAsync(solutionChecksum).ConfigureAwait(false);

                if (fromPrimaryBranch)
                {
                    // if the solutionChecksum is for primary branch, update primary workspace cache with the solution
                    return(PrimaryWorkspace.UpdateSolutionIfPossible(solution, workspaceVersion));
                }

                // otherwise, just return the solution
                return(solution);
            }

            // we need new solution. bulk sync all asset for the solution first.
            await _assetService.SynchronizeSolutionAssetsAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

            // get new solution info
            var solutionInfo = await GetSolutionInfoAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

            if (fromPrimaryBranch)
            {
                // if the solutionChecksum is for primary branch, update primary workspace cache with new solution
                if (PrimaryWorkspace.TryAddSolutionIfPossible(solutionInfo, workspaceVersion, out var solution))
                {
                    return(solution);
                }
            }

            // otherwise, just return new solution
            var workspace = new TemporaryWorkspace(solutionInfo);

            return(workspace.CurrentSolution);
        }
コード例 #5
0
        private async Task <Solution> CreateSolutionAsync(Checksum solutionChecksum, CancellationToken cancellationToken)
        {
            // synchronize whole solution first
            await _assetService.SynchronizeSolutionAssetsAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

            var solutionChecksumObject = await _assetService.GetAssetAsync <SolutionStateChecksums>(solutionChecksum, cancellationToken).ConfigureAwait(false);

            var workspace    = new AdhocWorkspace(RoslynServices.HostServices, workspaceKind: WorkspaceKind_RemoteWorkspace);
            var solutionInfo = await _assetService.GetAssetAsync <SerializedSolutionInfo>(solutionChecksumObject.Info, cancellationToken).ConfigureAwait(false);

            var projects = new List <ProjectInfo>();

            foreach (var projectChecksum in solutionChecksumObject.Projects)
            {
                var projectSnapshot = await _assetService.GetAssetAsync <ProjectStateChecksums>(projectChecksum, cancellationToken).ConfigureAwait(false);

                var projectInfo = await _assetService.GetAssetAsync <SerializedProjectInfo>(projectSnapshot.Info, cancellationToken).ConfigureAwait(false);

                if (!workspace.Services.IsSupported(projectInfo.Language))
                {
                    // only add project our workspace supports.
                    // workspace doesn't allow creating project with unknown languages
                    continue;
                }

                var documents = new List <DocumentInfo>();
                foreach (var documentChecksum in projectSnapshot.Documents)
                {
                    var documentSnapshot = await _assetService.GetAssetAsync <DocumentStateChecksums>(documentChecksum, cancellationToken).ConfigureAwait(false);

                    var documentInfo = await _assetService.GetAssetAsync <SerializedDocumentInfo>(documentSnapshot.Info, cancellationToken).ConfigureAwait(false);

                    var textLoader = TextLoader.From(
                        TextAndVersion.Create(
                            await _assetService.GetAssetAsync <SourceText>(documentSnapshot.Text, cancellationToken).ConfigureAwait(false),
                            VersionStamp.Create(),
                            documentInfo.FilePath));

                    // TODO: do we need version?
                    documents.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            textLoader,
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var p2p = new List <ProjectReference>();
                foreach (var checksum in projectSnapshot.ProjectReferences)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var reference = await _assetService.GetAssetAsync <ProjectReference>(checksum, cancellationToken).ConfigureAwait(false);

                    p2p.Add(reference);
                }

                var metadata = new List <MetadataReference>();
                foreach (var checksum in projectSnapshot.MetadataReferences)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var reference = await _assetService.GetAssetAsync <MetadataReference>(checksum, cancellationToken).ConfigureAwait(false);

                    metadata.Add(reference);
                }

                var analyzers = new List <AnalyzerReference>();
                foreach (var checksum in projectSnapshot.AnalyzerReferences)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var reference = await _assetService.GetAssetAsync <AnalyzerReference>(checksum, cancellationToken).ConfigureAwait(false);

                    analyzers.Add(reference);
                }

                var additionals = new List <DocumentInfo>();
                foreach (var documentChecksum in projectSnapshot.AdditionalDocuments)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var documentSnapshot = await _assetService.GetAssetAsync <DocumentStateChecksums>(documentChecksum, cancellationToken).ConfigureAwait(false);

                    var documentInfo = await _assetService.GetAssetAsync <SerializedDocumentInfo>(documentSnapshot.Info, cancellationToken).ConfigureAwait(false);

                    var textLoader = TextLoader.From(
                        TextAndVersion.Create(
                            await _assetService.GetAssetAsync <SourceText>(documentSnapshot.Text, cancellationToken).ConfigureAwait(false),
                            VersionStamp.Create(),
                            documentInfo.FilePath));

                    // TODO: do we need version?
                    additionals.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            textLoader,
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var compilationOptions = await _assetService.GetAssetAsync <CompilationOptions>(projectSnapshot.CompilationOptions, cancellationToken).ConfigureAwait(false);

                var parseOptions = await _assetService.GetAssetAsync <ParseOptions>(projectSnapshot.ParseOptions, cancellationToken).ConfigureAwait(false);

                projects.Add(
                    ProjectInfo.Create(
                        projectInfo.Id, projectInfo.Version, projectInfo.Name, projectInfo.AssemblyName,
                        projectInfo.Language, projectInfo.FilePath, projectInfo.OutputFilePath,
                        compilationOptions, parseOptions,
                        documents, p2p, metadata, analyzers, additionals, projectInfo.IsSubmission));
            }

            return(workspace.AddSolution(SolutionInfo.Create(solutionInfo.Id, solutionInfo.Version, solutionInfo.FilePath, projects)));
        }