private async Task <SolutionStateChecksums> ComputeChecksumsAsync(CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds.Select(id => ProjectStates[id]) .Where(s => RemoteSupportedLanguages.IsSupported(s.Language)) .Select(s => s.GetChecksumAsync(cancellationToken)); var serializer = _solutionServices.Workspace.Services.GetService <ISerializerService>(); var infoChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var optionsChecksum = serializer.CreateChecksum(Options, cancellationToken); var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <AnalyzerReferenceChecksumCollection>(AnalyzerReferences, _ => new AnalyzerReferenceChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums(infoChecksum, optionsChecksum, new ProjectChecksumCollection(projectChecksums), analyzerReferenceChecksums)); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
private async Task <ProjectStateChecksums> ComputeChecksumsAsync(CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ProjectState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum var documentChecksumsTasks = DocumentIds.Select(id => DocumentStates[id].GetChecksumAsync(cancellationToken)); var additionalDocumentChecksumTasks = AdditionalDocumentIds.Select(id => AdditionalDocumentStates[id].GetChecksumAsync(cancellationToken)); var serializer = new Serializer(_solutionServices.Workspace); var infoChecksum = serializer.CreateChecksum(ProjectInfo.Attributes, cancellationToken); // these compiler objects doesn't have good place to cache checksum. but rarely ever get changed. var compilationOptionsChecksum = SupportsCompilation ? ChecksumCache.GetOrCreate(CompilationOptions, _ => serializer.CreateChecksum(CompilationOptions, cancellationToken)) : Checksum.Null; var parseOptionsChecksum = SupportsCompilation ? ChecksumCache.GetOrCreate(ParseOptions, _ => serializer.CreateChecksum(ParseOptions, cancellationToken)) : Checksum.Null; var projectReferenceChecksums = ChecksumCache.GetOrCreate <ProjectReferenceChecksumCollection>(ProjectReferences, _ => new ProjectReferenceChecksumCollection(ProjectReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var metadataReferenceChecksums = ChecksumCache.GetOrCreate <MetadataReferenceChecksumCollection>(MetadataReferences, _ => new MetadataReferenceChecksumCollection(MetadataReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <AnalyzerReferenceChecksumCollection>(AnalyzerReferences, _ => new AnalyzerReferenceChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var documentChecksums = await Task.WhenAll(documentChecksumsTasks).ConfigureAwait(false); var additionalChecksums = await Task.WhenAll(additionalDocumentChecksumTasks).ConfigureAwait(false); return(new ProjectStateChecksums( infoChecksum, compilationOptionsChecksum, parseOptionsChecksum, new DocumentChecksumCollection(documentChecksums), projectReferenceChecksums, metadataReferenceChecksums, analyzerReferenceChecksums, new TextDocumentChecksumCollection(additionalChecksums))); } }
private Checksum GetParseOptionsChecksum(ISerializerService serializer) => this.SupportsCompilation ? ChecksumCache.GetOrCreate( this.ParseOptions, _ => serializer.CreateParseOptionsChecksum(this.ParseOptions) ) : Checksum.Null;
private static Checksum GetMetadataChecksumSlow(Solution solution, PortableExecutableReference reference, CancellationToken cancellationToken) { return(ChecksumCache.GetOrCreate(reference, _ => { var serializer = solution.Workspace.Services.GetService <ISerializerService>(); var checksum = serializer.CreateChecksum(reference, cancellationToken); return checksum; })); }
public static Checksum GetMetadataChecksum( Solution solution, PortableExecutableReference reference, CancellationToken cancellationToken) { // We can reuse the index for any given reference as long as it hasn't changed. // So our checksum is just the checksum for the PEReference itself. return(ChecksumCache.GetOrCreate(reference, _ => { var serializer = solution.Workspace.Services.GetService <ISerializerService>(); var checksum = serializer.CreateChecksum(reference, cancellationToken); return checksum; })); }
private static Checksum GetMetadataChecksumSlow(Solution solution, PortableExecutableReference reference, CancellationToken cancellationToken) { return(ChecksumCache.GetOrCreate(reference, _ => { var serializer = solution.Workspace.Services.GetService <ISerializerService>(); var checksum = serializer.CreateChecksum(reference, cancellationToken); // Include serialization format version in our checksum. That way if the // version ever changes, all persisted data won't match the current checksum // we expect, and we'll recompute things. return Checksum.Create(checksum, SerializationFormatChecksum); })); }
public static Checksum GetMetadataChecksum( Solution solution, PortableExecutableReference reference, CancellationToken cancellationToken) { // We can reuse the index for any given reference as long as it hasn't changed. // So our checksum is just the checksum for the PEReference itself. // First see if the value is already in the cache, to avoid an allocation if possible. if (ChecksumCache.TryGetValue(reference, out var cached)) { return(cached); } // Break things up to the fast path above and this slow path where we allocate a closure. return(GetMetadataChecksumSlow(solution, reference, cancellationToken)); }
private async Task <ProjectStateChecksums> ComputeChecksumsAsync(CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.ProjectState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // Here, we use the _documentStates and _additionalDocumentStates and visit them in order; we ensure that those are // sorted by ID so we have a consistent sort. var documentChecksumsTasks = _documentStates.Select(pair => pair.Value.GetChecksumAsync(cancellationToken)); var additionalDocumentChecksumTasks = _additionalDocumentStates.Select(pair => pair.Value.GetChecksumAsync(cancellationToken)); var analyzerConfigDocumentChecksumTasks = _analyzerConfigDocumentStates.Select(pair => pair.Value.GetChecksumAsync(cancellationToken)); var serializer = _solutionServices.Workspace.Services.GetService <ISerializerService>(); var infoChecksum = serializer.CreateChecksum(ProjectInfo.Attributes, cancellationToken); // these compiler objects doesn't have good place to cache checksum. but rarely ever get changed. var compilationOptionsChecksum = SupportsCompilation ? ChecksumCache.GetOrCreate(CompilationOptions, _ => serializer.CreateChecksum(CompilationOptions, cancellationToken)) : Checksum.Null; cancellationToken.ThrowIfCancellationRequested(); var parseOptionsChecksum = GetParseOptionsChecksum(serializer); var projectReferenceChecksums = ChecksumCache.GetOrCreate <ProjectReferenceChecksumCollection>(ProjectReferences, _ => new ProjectReferenceChecksumCollection(ProjectReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var metadataReferenceChecksums = ChecksumCache.GetOrCreate <MetadataReferenceChecksumCollection>(MetadataReferences, _ => new MetadataReferenceChecksumCollection(MetadataReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <AnalyzerReferenceChecksumCollection>(AnalyzerReferences, _ => new AnalyzerReferenceChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var documentChecksums = await Task.WhenAll(documentChecksumsTasks).ConfigureAwait(false); var additionalChecksums = await Task.WhenAll(additionalDocumentChecksumTasks).ConfigureAwait(false); var analyzerConfigDocumentChecksums = await Task.WhenAll(analyzerConfigDocumentChecksumTasks).ConfigureAwait(false); return(new ProjectStateChecksums( infoChecksum, compilationOptionsChecksum, parseOptionsChecksum, new DocumentChecksumCollection(documentChecksums), projectReferenceChecksums, metadataReferenceChecksums, analyzerReferenceChecksums, new TextDocumentChecksumCollection(additionalChecksums), new AnalyzerConfigDocumentChecksumCollection(analyzerConfigDocumentChecksums))); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
/// <param name="projectsToInclude">Cone of projects to compute a checksum for. Pass in <see langword="null"/> /// to get a checksum for the entire solution</param> private async Task <SolutionStateChecksums> ComputeChecksumsAsync( HashSet <ProjectId>?projectsToInclude, SerializableOptionSet options, CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum. Limit to the requested set of projects // if applicable. var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds.Where(id => projectsToInclude == null || projectsToInclude.Contains(id)) .Select(id => ProjectStates[id]) .Where(s => RemoteSupportedLanguages.IsSupported(s.Language)) .Select(s => s.GetChecksumAsync(cancellationToken)) .ToArray(); var serializer = _solutionServices.Workspace.Services.GetRequiredService <ISerializerService>(); var attributesChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var optionsChecksum = serializer.CreateChecksum(options, cancellationToken); var frozenSourceGeneratedDocumentIdentityChecksum = Checksum.Null; var frozenSourceGeneratedDocumentTextChecksum = Checksum.Null; if (FrozenSourceGeneratedDocumentState != null) { frozenSourceGeneratedDocumentIdentityChecksum = serializer.CreateChecksum(FrozenSourceGeneratedDocumentState.Identity, cancellationToken); frozenSourceGeneratedDocumentTextChecksum = (await FrozenSourceGeneratedDocumentState.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false)).Text; } var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <ChecksumCollection>(AnalyzerReferences, _ => new ChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums(attributesChecksum, optionsChecksum, new ChecksumCollection(projectChecksums), analyzerReferenceChecksums, frozenSourceGeneratedDocumentIdentityChecksum, frozenSourceGeneratedDocumentTextChecksum)); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
private async Task <SolutionStateChecksums> ComputeChecksumsAsync(CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds.Select(id => ProjectStates[id]) .Where(s => RemoteSupportedLanguages.IsSupported(s.Language)) .Select(s => s.GetChecksumAsync(cancellationToken)); var serializer = _solutionServices.Workspace.Services.GetService <ISerializerService>(); var infoChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums(infoChecksum, new ProjectChecksumCollection(projectChecksums))); } }
public static async Task <Checksum> GetChecksumAsync( Document document, CancellationToken cancellationToken) { // Since we build the SyntaxTreeIndex from a SyntaxTree, we need our checksum to change // any time the SyntaxTree could have changed. Right now, that can only happen if the // text of the document changes, or the ParseOptions change. So we get the checksums // for both of those, and merge them together to make the final checksum. var documentChecksumState = await document.State.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false); var textChecksum = documentChecksumState.Text; var parseOptions = document.Project.ParseOptions; var serializer = new Serializer(document.Project.Solution.Workspace); var parseOptionsChecksum = ChecksumCache.GetOrCreate( parseOptions, _ => serializer.CreateChecksum(parseOptions, cancellationToken)); return(Checksum.Create(WellKnownSynchronizationKind.SyntaxTreeIndex, new[] { textChecksum, parseOptionsChecksum })); }
/// <param name="projectsToInclude">Cone of projects to compute a checksum for. Pass in <see langword="null"/> /// to get a checksum for the entire solution</param> private async Task <SolutionStateChecksums> ComputeChecksumsAsync( HashSet <ProjectId>?projectsToInclude, SerializableOptionSet options, CancellationToken cancellationToken) { try { using (Logger.LogBlock(FunctionId.SolutionState_ComputeChecksumsAsync, FilePath, cancellationToken)) { // get states by id order to have deterministic checksum. Limit expensive computation to the // requested set of projects if applicable. var orderedProjectIds = ChecksumCache.GetOrCreate(ProjectIds, _ => ProjectIds.OrderBy(id => id.Id).ToImmutableArray()); var projectChecksumTasks = orderedProjectIds .Select(id => (state: ProjectStates[id], mustCompute: projectsToInclude == null || projectsToInclude.Contains(id))) .Where(t => RemoteSupportedLanguages.IsSupported(t.state.Language)) .Select(async t => { // if it's a project that's specifically in the sync'ed cone, include this checksum so that // this project definitely syncs over. if (t.mustCompute) { return(await t.state.GetChecksumAsync(cancellationToken).ConfigureAwait(false)); } // If it's a project that is not in the cone, still try to get the latest checksum for it if // we have it. That way we don't send over a checksum *without* that project, causing the // OOP side to throw that project away (along with all the compilation info stored with it). if (t.state.TryGetStateChecksums(out var stateChecksums)) { return(stateChecksums.Checksum); } // We have never computed the checksum for this project. Don't send anything for it. return(null); }) .ToArray(); var serializer = _solutionServices.Workspace.Services.GetRequiredService <ISerializerService>(); var attributesChecksum = serializer.CreateChecksum(SolutionAttributes, cancellationToken); var optionsChecksum = serializer.CreateChecksum(options, cancellationToken); var frozenSourceGeneratedDocumentIdentityChecksum = Checksum.Null; var frozenSourceGeneratedDocumentTextChecksum = Checksum.Null; if (FrozenSourceGeneratedDocumentState != null) { frozenSourceGeneratedDocumentIdentityChecksum = serializer.CreateChecksum(FrozenSourceGeneratedDocumentState.Identity, cancellationToken); frozenSourceGeneratedDocumentTextChecksum = (await FrozenSourceGeneratedDocumentState.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false)).Text; } var analyzerReferenceChecksums = ChecksumCache.GetOrCreate <ChecksumCollection>(AnalyzerReferences, _ => new ChecksumCollection(AnalyzerReferences.Select(r => serializer.CreateChecksum(r, cancellationToken)).ToArray())); var projectChecksums = await Task.WhenAll(projectChecksumTasks).ConfigureAwait(false); return(new SolutionStateChecksums( attributesChecksum, optionsChecksum, new ChecksumCollection(projectChecksums.WhereNotNull().ToArray()), analyzerReferenceChecksums, frozenSourceGeneratedDocumentIdentityChecksum, frozenSourceGeneratedDocumentTextChecksum)); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { throw ExceptionUtilities.Unreachable; } }
private async void VerifyFiles_Click(object sender, RoutedEventArgs e) { //*/ try { this.EnsureThings(); string cachePath = this.checksumcache_path.Text, pso2dir = this.pso2directory_path.Text; if (!File.Exists(Path.Combine(pso2dir, "pso2launcher.exe")) && !File.Exists(Path.Combine(pso2dir, "pso2.exe"))) { if (await this.MsgBoxYesNo("PSO2 Directory setting seems to not point to the 'pso2_dir' directory.\nAre you sure you still want to continue?", "Confirmation", "Yes, continue", "Nope") != MessageDialogResult.Affirmative) { return; } } if (await this.MsgBoxYesNo("Are you sure you want to verify the whole game client?", "Question") == MessageDialogResult.Affirmative) { UpdaterProfile profile; ComboBoxItem item = this.UpdaterProfile.SelectedItem as ComboBoxItem; if (item == null) { profile = Leayal.PSO2.Updater.UpdaterProfile.Balanced; } else { profile = (Leayal.PSO2.Updater.UpdaterProfile)item.Tag; } int threadcount = Math.Min(Environment.ProcessorCount, 4); item = this.maxDegreeOfParallelism.SelectedItem as ComboBoxItem; if (item != null) { threadcount = (int)item.Tag; } this.progressStep.Text = "Preparing"; this.progressbar.IsIndeterminate = true; this.tab_Progress.IsSelected = true; bool usecache = (this.checksumcache_use.IsChecked == true); this.config.SetValue("Cache", "Filepath", cachePath); this.config.SetValue("PSO2", "Directory", pso2dir); var version = await this.updater.GetPatchManagementAsync(); Action <ClientUpdateOptions> continueAction = (result) => { this.Dispatcher.BeginInvoke(new JustAction(() => { this.progressStep.Text = "Preparing patchlist"; this.progressbar.IsIndeterminate = false; this.TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal; }), DispatcherPriority.Normal, null); if (this.downloadingfiles == null) { this.downloadingfiles = new ConcurrentDictionary <string, bool>(); } else { this.downloadingfiles.Clear(); } this.currentstep = "Downloading patchlists"; Task.Run(async() => { RemotePatchlist patchlist = await this.updater.GetPatchlistAsync(version); await this.updater.VerifyAndDownloadAsync(pso2dir, version, patchlist, result); }); }; await Task.Run(() => { ClientUpdateOptions options = new ClientUpdateOptions() { Profile = profile, MaxDegreeOfParallelism = threadcount }; if ((usecache == true) && !string.IsNullOrWhiteSpace(cachePath)) { if (File.Exists(cachePath)) { try { var checksumCache = ChecksumCache.OpenFromFile(cachePath); if (!string.Equals(checksumCache.PSO2Version, version.CurrentVersion, StringComparison.OrdinalIgnoreCase)) { this.Dispatcher.BeginInvoke(new JustAction(async() => { var answer = await this.MsgBoxYesNoCancel($"The cache you provided is for PSO2 client ver {checksumCache.PSO2Version} while your current client version is {version.CurrentVersion}. ?", "Question", "Skip cache", "Rebuild cache", "Cancel operation"); if (answer == MessageDialogResult.Affirmative) { checksumCache.Dispose(); } else if (answer == MessageDialogResult.Negative) { if (options.Profile == Leayal.PSO2.Updater.UpdaterProfile.PreferSpeed) { options.Profile = Leayal.PSO2.Updater.UpdaterProfile.Balanced; } checksumCache.ChecksumList.Clear(); options.ChecksumCache = checksumCache; } else { checksumCache.Dispose(); this.tab_Mainmenu.IsSelected = true; return; } continueAction.Invoke(options); }), DispatcherPriority.Normal, null); return; } else { options.ChecksumCache = checksumCache; } } catch (InvalidCacheException) { options.ChecksumCache = ChecksumCache.Create(cachePath); } } else { options.ChecksumCache = ChecksumCache.Create(cachePath); } } continueAction.Invoke(options); }); } else { this.tab_Mainmenu.IsSelected = true; } } #if !DEBUG catch (WrappedWarningException warn) { this.tab_Mainmenu.IsSelected = true; await this.MsgBoxOK(warn.Message, "Warning"); } #endif catch (Exception ex) { this.tab_Mainmenu.IsSelected = true; MessageBox.Show(this, ex.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Updater_StepChanged(UpdateStep arg1, object arg2) { switch (arg1) { case UpdateStep.DownloadingFileStart: if (arg2 is PSO2File file) { this.downloadingfiles.TryAdd(file.SafeFilename, true); if (this.downloadingfiles.Count == 1) { this.Dispatcher.BeginInvoke(new JustActionOneArg((x) => { this.downloadingStep.Text = $"Downloading:\n{x}"; }), DispatcherPriority.Normal, this.downloadingfiles.First().Key); } else { StringBuilder sb = new StringBuilder(); sb.Append("Downloading:"); foreach (string filename in this.downloadingfiles.Keys) { sb.Append("\n"); sb.Append(filename); } this.Dispatcher.BeginInvoke(new JustActionOneArg((x) => { this.downloadingStep.Text = (string)x; }), DispatcherPriority.Normal, sb.ToString()); } } break; case UpdateStep.DownloadingFileEnd: if (arg2 is PSO2File file2) { this.downloadingfiles.TryRemove(file2.SafeFilename, out var somebool); if (this.downloadingfiles.Count == 0) { this.Dispatcher.BeginInvoke(new JustAction(() => { this.downloadingStep.Text = string.Empty; }), DispatcherPriority.Normal, null); } else if (this.downloadingfiles.Count == 1) { string va = this.downloadingfiles.First().Key; this.Dispatcher.BeginInvoke(new JustActionOneArg((x) => { this.downloadingStep.Text = $"Downloading:\n{x}"; }), DispatcherPriority.Normal, this.downloadingfiles.First().Key); } else { StringBuilder sb = new StringBuilder(); sb.Append("Downloading:"); foreach (string filename in this.downloadingfiles.Keys) { sb.Append("\n"); sb.Append(filename); } this.Dispatcher.BeginInvoke(new JustActionOneArg((x) => { this.downloadingStep.Text = (string)x; }), DispatcherPriority.Normal, sb.ToString()); } } break; case UpdateStep.BeginFileCheckAndDownload: this.currentstep = "Verifying files"; break; case UpdateStep.WriteCache: this.Dispatcher.BeginInvoke(new JustActionOneArg((x) => { ChecksumCache cache = x as ChecksumCache; if (cache != null) { if (cache.ChecksumList.Count == 1) { this.progressStep.Text = "Writing 1 entry to the cache file."; } else { this.progressStep.Text = $"Writing {cache.ChecksumList.Count} entries to the cache file."; } } }), DispatcherPriority.Normal, arg2); break; } }