Repository: dotnet/roslyn
File: src/Workspaces/Remote/ServiceHub/Host/RemoteWorkspace.cs (C#)

Code before:
                    await task.NoThrowAwaitable(false);
            }
            catch (Exception ex) when (FatalError.ReportAndPropagate(ex, ErrorSeverity.Critical))
            {
                // Similar to AcquireSolutionAndIncrementInFlightCountAsync Any exception thrown in the above
                // (including cancellation) is critical and unrecoverable.  We must clean up our state, and anything
                // that prevents that could leave us in an inconsistent position.
            }
        }
    }

    private async Task<Solution> GetOrCreateSolutionToUpdateAsync(
        AssetProvider assetProvider,
        Checksum solutionChecksum,
        CancellationToken cancellationToken)
    {
        // See if we can just incrementally update the current solution.
        var newSolutionCompilationChecksums = await assetProvider.GetAssetAsync<SolutionCompilationStateChecksums>(
            AssetPathKind.SolutionCompilationStateChecksums, solutionChecksum, cancellationToken).ConfigureAwait(false);
        var newSolutionChecksums = await assetProvider.GetAssetAsync<SolutionStateChecksums>(
            AssetPathKind.SolutionStateChecksums, newSolutionCompilationChecksums.SolutionState, cancellationToken).ConfigureAwait(false);
        var newSolutionInfo = await assetProvider.GetAssetAsync<SolutionInfo.SolutionAttributes>(
            AssetPathKind.SolutionAttributes, newSolutionChecksums.Attributes, cancellationToken).ConfigureAwait(false);

        // In solution load, we might not yet have CurrentSolution updated since we haven't synchronized our primary solution over. But we might already have
        // synchronized part of it over, so let's see if we have a solution that matches what we need.
        Solution? bestSolution = null;
        int? bestSolutionProjectsMissing = null;

        void UpdateBestSolution(Solution candidateSolution)
        {
            if (candidateSolution.Id == newSolutionInfo.Id && candidateSolution.FilePath == newSolutionInfo.FilePath)
            {
                // Compute how many projects are missing from this one
                var ids = new HashSet<ProjectId>(newSolutionChecksums.Projects.Ids);
                foreach (var id in candidateSolution.ProjectIds)
                    ids.Remove(id);

                var projectsMissing = ids.Count;

                if (!bestSolutionProjectsMissing.HasValue)
                {
                    bestSolution = candidateSolution;
                    bestSolutionProjectsMissing = projectsMissing;
                }
                else if (projectsMissing < bestSolutionProjectsMissing.Value)
                {
                    bestSolution = candidateSolution;
                    bestSolutionProjectsMissing = projectsMissing;
                }
            }

Review comment (performance):
Consider clarifying "but we may have already synchronized part of it over".  Do you mean by some other remote call that is running concurrently to this one?  if so, mention taht.  

also, mention a few other things, like this is really an optimization around the first batch of request that may fly over.  like VS starts, then launches oop, then sends a bunch of calls over.  we want to avoid potentially having those first N initial calls be overly expensive.  also worth calling out that due to razor/SGs, this is more important as the first ops on a solution are now even more expensive.  so sharing that instance is very valuable. 



Code after:
                    await task.NoThrowAwaitable(false);
            }
            catch (Exception ex) when (FatalError.ReportAndPropagate(ex, ErrorSeverity.Critical))
            {
                // Similar to AcquireSolutionAndIncrementInFlightCountAsync Any exception thrown in the above
                // (including cancellation) is critical and unrecoverable.  We must clean up our state, and anything
                // that prevents that could leave us in an inconsistent position.
            }
        }
    }

    private async Task<Solution> GetOrCreateSolutionToUpdateAsync(
        AssetProvider assetProvider,
        Checksum solutionChecksum,
        CancellationToken cancellationToken)
    {
        // See if we can just incrementally update the current solution.
        var newSolutionCompilationChecksums = await assetProvider.GetAssetAsync<SolutionCompilationStateChecksums>(
            AssetPathKind.SolutionCompilationStateChecksums, solutionChecksum, cancellationToken).ConfigureAwait(false);
        var newSolutionChecksums = await assetProvider.GetAssetAsync<SolutionStateChecksums>(
            AssetPathKind.SolutionStateChecksums, newSolutionCompilationChecksums.SolutionState, cancellationToken).ConfigureAwait(false);
        var newSolutionInfo = await assetProvider.GetAssetAsync<SolutionInfo.SolutionAttributes>(
            AssetPathKind.SolutionAttributes, newSolutionChecksums.Attributes, cancellationToken).ConfigureAwait(false);

        // We update CurrentSolution by periodically syncing the primary solution over from our main process. During solution load, that might not happen prior to
        // a file being opened and the user trying to interact with a project; in that case CurrentSolution might still be empty. In that window of time,
        // each operation from OOP would then synchronize over the projects or cone from scratch, and then effectively throwing away that state since the next request will
        // try to base itself from the (empty) CurrentSolution again. To avoid that, we'll see if we have some other forked solution available that has some of the projects we might
        // need, but checking how many projects are missing. This is especially important for cases where the projects may have generators, since a first time generator run
        // could be expensive.
        Solution? bestSolution = null;
        int? bestSolutionProjectsMissingCount = null;

        // First, is our CurrentSolution already a candidate that can't be beat?
        UpdateBestSolution(this.CurrentSolution);
        if (bestSolution is not null && bestSolutionProjectsMissingCount == 0)
            return bestSolution;

        using var _ = PooledHashSet<Solution>.GetInstance(out var solutions);
        using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false))
        {
            _lastRequestedAnyBranchSolutions.AddAllTo(solutions);
        }

        foreach (var solution in solutions)
            UpdateBestSolution(solution);

        if (bestSolution is not null)
            return bestSolution;

        // If not, have to create a new, fresh, solution instance to update.