From a4a5ffdc73ee0b212f8ece58c73277e41ec915ac Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Thu, 12 May 2016 13:11:07 -0700 Subject: [PATCH] Avoid loading the Elfie dll until the user actualy enables the search feature. --- .../SymbolSearchService.Update.cs | 27 +++++++++---------- .../Def/SymbolSearch/SymbolSearchService.cs | 18 ++++++------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.Update.cs b/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.Update.cs index e588990c774..fd5dcc94d2b 100644 --- a/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.Update.cs +++ b/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.Update.cs @@ -44,8 +44,6 @@ internal partial class SymbolSearchService private const string MicrosoftAssemblyReferencesName = "MicrosoftAssemblyReferences"; private static readonly LinkedList s_log = new LinkedList(); - private readonly int _dataFormatVersion = AddReferenceDatabase.TextFileFormatVersion; - /// /// Cancellation support for the task we use to keep the local database up to date. /// When VS shuts down it will dispose us. We'll cancel the task at that point. @@ -58,9 +56,6 @@ internal partial class SymbolSearchService private readonly ConcurrentDictionary _sourceToUpdateSentinel = new ConcurrentDictionary(); - private readonly DirectoryInfo _cacheDirectoryInfo; - //private readonly FileInfo _databaseFileInfo; - // Interfaces that abstract out the external functionality we need. Used so we can easily // mock behavior during tests. private readonly IPackageInstallerService _installerService; @@ -70,6 +65,7 @@ internal partial class SymbolSearchService private readonly IRemoteControlService _remoteControlService; private readonly IPatchService _patchService; private readonly IDatabaseFactoryService _databaseFactoryService; + private readonly string _localSettingsDirectory; private readonly Func _reportAndSwallowException; public void Dispose() @@ -125,23 +121,26 @@ internal Task UpdateSourceInBackgroundAsync(string source) // We were the first ones to try to update this source. Spawn off a task to do // the updating. - return new Updater(this, source).UpdateInBackgroundAsync(); + return new Updater(this, source, _localSettingsDirectory).UpdateInBackgroundAsync(); } private class Updater { private readonly SymbolSearchService _service; private readonly string _source; + private readonly DirectoryInfo _cacheDirectoryInfo; private readonly FileInfo _databaseFileInfo; - public Updater(SymbolSearchService service, string source) + public Updater(SymbolSearchService service, string source, string localSettingsDirectory) { _service = service; _source = source; - var fileName = ConvertToFileName(source); + _cacheDirectoryInfo = new DirectoryInfo(Path.Combine( + localSettingsDirectory, "PackageCache", string.Format(Invariant($"Format{AddReferenceDatabase.TextFileFormatVersion}")))); + _databaseFileInfo = new FileInfo( - Path.Combine(_service._cacheDirectoryInfo.FullName, fileName + ".txt")); + Path.Combine(_cacheDirectoryInfo.FullName, ConvertToFileName(source) + ".txt")); } /// @@ -254,12 +253,12 @@ private void CleanCacheDirectory() _service.LogInfo("Cleaning cache directory"); // (intentionally not wrapped in IOUtilities. If this throws we want to restart). - if (!_service._ioService.Exists(_service._cacheDirectoryInfo)) + if (!_service._ioService.Exists(_cacheDirectoryInfo)) { _service.LogInfo("Creating cache directory"); // (intentionally not wrapped in IOUtilities. If this throws we want to restart). - _service._ioService.Create(_service._cacheDirectoryInfo); + _service._ioService.Create(_cacheDirectoryInfo); _service.LogInfo("Cache directory created"); } @@ -268,7 +267,7 @@ private void CleanCacheDirectory() private async Task DownloadFullDatabaseAsync() { - var serverPath = Invariant($"Elfie_V{_service._dataFormatVersion}/Latest.xml"); + var serverPath = Invariant($"Elfie_V{AddReferenceDatabase.TextFileFormatVersion}/Latest.xml"); _service.LogInfo($"Downloading and processing full database: {serverPath}"); @@ -332,7 +331,7 @@ private async Task WriteDatabaseFile(byte[] bytes) () => { var guidString = Guid.NewGuid().ToString(); - var tempFilePath = Path.Combine(_service._cacheDirectoryInfo.FullName, guidString + ".tmp"); + var tempFilePath = Path.Combine(_cacheDirectoryInfo.FullName, guidString + ".tmp"); _service.LogInfo($"Temp file path: {tempFilePath}"); @@ -402,7 +401,7 @@ private async Task PatchLocalDatabaseAsync() var databaseVersion = database.DatabaseVersion; // Now attempt to download and apply patch file. - var serverPath = Invariant($"Elfie_V{_service._dataFormatVersion}/{database.DatabaseVersion}_Patch.xml"); + var serverPath = Invariant($"Elfie_V{AddReferenceDatabase.TextFileFormatVersion}/{database.DatabaseVersion}_Patch.xml"); _service.LogInfo("Downloading and processing patch file: " + serverPath); diff --git a/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.cs b/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.cs index f2a30c81729..6a2f13e2f5d 100644 --- a/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.cs +++ b/src/VisualStudio/Core/Def/SymbolSearch/SymbolSearchService.cs @@ -36,7 +36,8 @@ internal partial class SymbolSearchService : ISymbolSearchService, IDisposable { - private ConcurrentDictionary _sourceToDatabase = new ConcurrentDictionary(); + // Value is typed as 'object' so we don't load the elfie dll until actually necessary. + private ConcurrentDictionary _sourceToDatabase = new ConcurrentDictionary(); public SymbolSearchService( VSShell.SVsServiceProvider serviceProvider, @@ -104,12 +105,9 @@ private static IRemoteControlService CreateRemoteControlService(VSShell.SVsServi _remoteControlService = remoteControlService; _patchService = patchService; _databaseFactoryService = databaseFactoryService; + _localSettingsDirectory = localSettingsDirectory; _reportAndSwallowException = reportAndSwallowException; - _cacheDirectoryInfo = new DirectoryInfo(Path.Combine( - localSettingsDirectory, "PackageCache", string.Format(Invariant($"Format{_dataFormatVersion}")))); - // _databaseFileInfo = new FileInfo(Path.Combine(_cacheDirectoryInfo.FullName, "NuGetCache.txt")); - _cancellationTokenSource = cancellationTokenSource; _cancellationToken = _cancellationTokenSource.Token; } @@ -117,13 +115,14 @@ private static IRemoteControlService CreateRemoteControlService(VSShell.SVsServi public IEnumerable FindPackagesWithType( string source, string name, int arity, CancellationToken cancellationToken) { - AddReferenceDatabase database; - if (!_sourceToDatabase.TryGetValue(source, out database)) + object databaseObj; + if (!_sourceToDatabase.TryGetValue(source, out databaseObj)) { // Don't have a database to search. yield break; } + var database = databaseObj as AddReferenceDatabase; if (name == "var") { // never find anything named 'var'. @@ -190,13 +189,14 @@ private static IRemoteControlService CreateRemoteControlService(VSShell.SVsServi string name, int arity, CancellationToken cancellationToken) { // Our reference assembly data is stored in the nuget.org DB. - AddReferenceDatabase database; - if (!_sourceToDatabase.TryGetValue(NugetOrgSource, out database)) + object databaseObj; + if (!_sourceToDatabase.TryGetValue(NugetOrgSource, out databaseObj)) { // Don't have a database to search. yield break; } + var database = (AddReferenceDatabase)databaseObj; if (name == "var") { // never find anything named 'var'. -- GitLab