async Task <IEnumerable <IPackageSearchMetadata> > GetPackagesWithUpdatesAsync(string searchText, SearchFilter searchFilter, CancellationToken cancellationToken) { if (_context != null) { _installedPackages = await _context.GetInstalledPackagesAsync(); _context = null; } var packages = _installedPackages .GetEarliest() .Where(p => p.Id.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1) .OrderBy(p => p.Id); var latestItems = await TaskCombinators.ThrottledAsync( packages, (p, t) => _metadataProvider.GetLatestPackageMetadataAsync(p, searchFilter.IncludePrerelease, t), cancellationToken); var packagesWithUpdates = packages .Join(latestItems.Where(i => i != null), p => p.Id, m => m.Identity.Id, (p, m) => new { cv = p.Version, m = m }, StringComparer.OrdinalIgnoreCase) .Where(j => VersionComparer.VersionRelease.Compare(j.cv, j.m.Identity.Version) < 0) .Select(j => j.m); return(packagesWithUpdates); }
// For unit testing purposes internal static async ValueTask <PackageItemLoader> CreateAsync( IServiceBroker serviceBroker, PackageLoadContext context, IReadOnlyCollection <PackageSourceContextInfo> packageSources, ContractItemFilter itemFilter, IReconnectingNuGetSearchService searchService, INuGetPackageFileService packageFileService, string searchText = null, bool includePrerelease = true, bool useRecommender = false) { var itemLoader = new PackageItemLoader( serviceBroker, searchService, context, packageSources, itemFilter, searchText, includePrerelease, useRecommender); await itemLoader.InitializeAsync(packageFileService); return(itemLoader); }
private void RefreshAvailableUpdatesCount() { NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async() => { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); _topPanel._labelUpgradeAvailable.Count = 0; var loadContext = new PackageLoadContext(ActiveSources, Model.IsSolution, Model.Context); var packageFeed = await CreatePackageFeedAsync(loadContext, ItemFilter.UpdatesAvailable, _uiLogger); var loader = new PackageItemLoader( loadContext, packageFeed, includePrerelease: IncludePrerelease); // cancel previous refresh update count task, if any // and start a new one. var refreshCts = new CancellationTokenSource(); Interlocked.Exchange(ref _refreshCts, refreshCts)?.Cancel(); Model.CachedUpdates = new PackageSearchMetadataCache { Packages = await loader.GetAllPackagesAsync(refreshCts.Token), IncludePrerelease = IncludePrerelease }; _topPanel._labelUpgradeAvailable.Count = Model.CachedUpdates.Packages.Count; }); }
/// <summary> /// This method is called from several event handlers. So, consolidating the use of JTF.Run in this method /// </summary> private void SearchPackagesAndRefreshUpdateCount(string searchText, bool useCache) { NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async() => { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var loadContext = new PackageLoadContext(ActiveSources, Model.IsSolution, Model.Context); if (useCache) { loadContext.CachedPackages = Model.CachedUpdates; } ; var packageFeed = await CreatePackageFeedAsync(loadContext, _topPanel.Filter, _uiLogger); var loader = new PackageItemLoader( loadContext, packageFeed, searchText, IncludePrerelease); var loadingMessage = string.IsNullOrWhiteSpace(searchText) ? Resx.Resources.Text_Loading : string.Format(CultureInfo.CurrentCulture, Resx.Resources.Text_Searching, searchText); // Set a new cancellation token source which will be used to cancel this task in case // new loading task starts or manager ui is closed while loading packages. _loadCts = new CancellationTokenSource(); // start SearchAsync task for initial loading of packages var searchResultTask = loader.SearchAsync(continuationToken: null, cancellationToken: _loadCts.Token); // this will wait for searchResultTask to complete instead of creating a new task _packageList.LoadItems(loader, loadingMessage, _uiLogger, searchResultTask, _loadCts.Token); // We only refresh update count, when we don't use cache so check it it's false if (!useCache) { // clear existing caches Model.CachedUpdates = null; if (_topPanel.Filter.Equals(ItemFilter.UpdatesAvailable)) { // it means selected tab is update itself, so just wait for searchAsyncTask to complete // without making another call to loader to get all packages. _topPanel._labelUpgradeAvailable.Count = 0; var searchResult = await searchResultTask; Model.CachedUpdates = new PackageSearchMetadataCache { Packages = searchResult.Items, IncludePrerelease = IncludePrerelease }; _topPanel._labelUpgradeAvailable.Count = Model.CachedUpdates.Packages.Count; } else { RefreshAvailableUpdatesCount(); } } }); }
/// <summary> /// This method is called from several event handlers. So, consolidating the use of JTF.Run in this method /// </summary> private void SearchPackageInActivePackageSource(string searchText, bool useCache) { NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async() => { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var loadContext = new PackageLoadContext(ActiveSources, Model.IsSolution, Model.Context); if (useCache) { loadContext.CachedPackages = Model.CachedUpdates; } ; var packageFeed = await CreatePackageFeedAsync(loadContext, _topPanel.Filter, _uiLogger); var loader = new PackageItemLoader( loadContext, packageFeed, searchText, IncludePrerelease); var loadingMessage = string.IsNullOrWhiteSpace(searchText) ? Resx.Resources.Text_Loading : string.Format(CultureInfo.CurrentCulture, Resx.Resources.Text_Searching, searchText); _packageList.LoadItems(loader, loadingMessage, _uiLogger); }); }
public ConsolidatePackageFeed( PackageLoadContext context, IPackageMetadataProvider metadataProvider, Common.ILogger logger) : this(new PackageIdentity[0], metadataProvider, logger) { _context = context; }
public InstalledPackageFeed( PackageLoadContext context, IPackageMetadataProvider metadataProvider, Common.ILogger logger) : this(new PackageIdentity[0], metadataProvider, logger) { this._context = context; }
public UpdatePackageFeed( PackageLoadContext context, IPackageMetadataProvider metadataProvider, PackageSearchMetadataCache cachedUpdates, Common.ILogger logger) : this(new PackageIdentity[0], metadataProvider, cachedUpdates, logger) { _context = context; }
private static IPackageMetadataProvider CreatePackageMetadataProvider(PackageLoadContext context) { var logger = new VisualStudioActivityLogger(); return(new MultiSourcePackageMetadataProvider( context.SourceRepositories, context.PackageManager?.PackagesFolderSourceRepository, context.PackageManager?.GlobalPackageFolderRepositories, logger)); }
private void RefreshConsolidatablePackagesCount() { NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async() => { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); _topPanel._labelConsolidate.Count = 0; var loadContext = new PackageLoadContext(ActiveSources, Model.IsSolution, Model.Context); var packageFeed = await CreatePackageFeedAsync(loadContext, ItemFilter.Consolidate, _uiLogger); var loader = new PackageItemLoader( loadContext, packageFeed, includePrerelease: IncludePrerelease); _topPanel._labelConsolidate.Count = await loader.GetTotalCountAsync(100, CancellationToken.None); }); }
private static async Task <IPackageFeed> CreatePackageFeedAsync(PackageLoadContext context, ItemFilter filter, INuGetUILogger uiLogger) { // Go off the UI thread to perform non-UI operations await TaskScheduler.Default; var logger = new VisualStudioActivityLogger(); if (filter == ItemFilter.All) { return(new MultiSourcePackageFeed(context.SourceRepositories, uiLogger)); } var metadataProvider = CreatePackageMetadataProvider(context); var installedPackages = await context.GetInstalledPackagesAsync(); if (filter == ItemFilter.Installed) { return(new InstalledPackageFeed(installedPackages, metadataProvider, logger)); } if (filter == ItemFilter.Consolidate) { return(new ConsolidatePackageFeed(installedPackages, metadataProvider, logger)); } // Search all / updates available cannot work without a source repo if (context.SourceRepositories == null) { return(null); } if (filter == ItemFilter.UpdatesAvailable) { return(new UpdatePackageFeed( installedPackages, metadataProvider, context.Projects, context.CachedPackages, logger)); } throw new InvalidOperationException("Unsupported feed type"); }
private PackageItemLoader( IServiceBroker serviceBroker, PackageLoadContext context, IReadOnlyCollection <PackageSourceContextInfo> packageSources, ContractItemFilter itemFilter, string searchText, bool includePrerelease, bool useRecommender) { Assumes.NotNull(serviceBroker); Assumes.NotNull(context); Assumes.NotNullOrEmpty(packageSources); _serviceBroker = serviceBroker; _context = context; _searchText = searchText ?? string.Empty; _includePrerelease = includePrerelease; _packageSources = packageSources; _itemFilter = itemFilter; _useRecommender = useRecommender; }
public PackageItemLoader( PackageLoadContext context, IPackageFeed packageFeed, string searchText = null, bool includePrerelease = true) { if (context == null) { throw new ArgumentNullException(nameof(context)); } _context = context; if (packageFeed == null) { throw new ArgumentNullException(nameof(packageFeed)); } _packageFeed = packageFeed; _searchText = searchText ?? string.Empty; _includePrerelease = includePrerelease; }
private void RefreshAvailableUpdatesCount() { NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async() => { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); _topPanel._labelUpgradeAvailable.Count = 0; var loadContext = new PackageLoadContext(ActiveSources, Model.IsSolution, Model.Context); var packageFeed = await CreatePackageFeedAsync(loadContext, ItemFilter.UpdatesAvailable, _uiLogger); var loader = new PackageItemLoader( loadContext, packageFeed, includePrerelease: IncludePrerelease); Model.CachedUpdates = new PackageSearchMetadataCache { Packages = await loader.GetAllPackagesAsync(CancellationToken.None), IncludePrerelease = IncludePrerelease }; _topPanel._labelUpgradeAvailable.Count = Model.CachedUpdates.Packages.Count; }); }
/// <summary> /// Updates the detail pane based on the selected package /// </summary> private async Task UpdateDetailPaneAsync() { var selectedPackage = _packageList.SelectedItem; if (selectedPackage == null) { _packageDetail.Visibility = Visibility.Hidden; _packageDetail.DataContext = null; } else { _packageDetail.Visibility = Visibility.Visible; _packageDetail.DataContext = _detailModel; await _detailModel.SetCurrentPackage(selectedPackage, _topPanel.Filter, () => _packageList.SelectedItem); _packageDetail.ScrollToHome(); var context = new PackageLoadContext(ActiveSources, Model.IsSolution, Model.Context); var metadataProvider = CreatePackageMetadataProvider(context); await _detailModel.LoadPackageMetadaAsync(metadataProvider, CancellationToken.None); } }
private async Task PerformActionImplAsync( IServiceBroker serviceBroker, INuGetProjectManagerService projectManagerService, INuGetUI uiService, ResolveActionsAsync resolveActionsAsync, NuGetOperationType operationType, UserAction userAction, CancellationToken cancellationToken) { var status = NuGetOperationStatus.Succeeded; var startTime = DateTimeOffset.Now; var packageCount = 0; var continueAfterPreview = true; var acceptedLicense = true; List <string> removedPackages = null; var existingPackages = new HashSet <Tuple <string, string> >(); List <Tuple <string, string> > addedPackages = null; List <Tuple <string, string> > updatedPackagesOld = null; List <Tuple <string, string> > updatedPackagesNew = null; // Enable granular level telemetry events for nuget ui operation uiService.ProjectContext.OperationId = Guid.NewGuid(); Stopwatch packageEnumerationTime = new Stopwatch(); packageEnumerationTime.Start(); try { // collect the install state of the existing packages foreach (IProjectContextInfo project in uiService.Projects) { IEnumerable <IPackageReferenceContextInfo> installedPackages = await project.GetInstalledPackagesAsync( uiService.UIContext.ServiceBroker, cancellationToken); foreach (IPackageReferenceContextInfo package in installedPackages) { Tuple <string, string> packageInfo = new Tuple <string, string>( package.Identity.Id, (package.Identity.Version == null ? "" : package.Identity.Version.ToNormalizedString())); if (!existingPackages.Contains(packageInfo)) { existingPackages.Add(packageInfo); } } } } catch (Exception) { // don't teardown the process if we have a telemetry failure } packageEnumerationTime.Stop(); await _lockService.ExecuteNuGetOperationAsync(async() => { try { uiService.BeginOperation(); using (INuGetProjectUpgraderService projectUpgrader = await serviceBroker.GetProxyAsync <INuGetProjectUpgraderService>( NuGetServices.ProjectUpgraderService, cancellationToken)) { bool isAcceptedFormat = await CheckPackageManagementFormatAsync(projectUpgrader, uiService, cancellationToken); if (!isAcceptedFormat) { return; } } TelemetryServiceUtility.StartOrResumeTimer(); IReadOnlyList <ProjectAction> actions = await resolveActionsAsync(projectManagerService); IReadOnlyList <PreviewResult> results = await GetPreviewResultsAsync(projectManagerService, actions, cancellationToken); if (operationType == NuGetOperationType.Uninstall) { // removed packages don't have version info removedPackages = results.SelectMany(result => result.Deleted) .Select(package => package.Id) .Distinct() .ToList(); packageCount = removedPackages.Count; } else { // log rich info about added packages addedPackages = results.SelectMany(result => result.Added) .Select(package => new Tuple <string, string>(package.Id, (package.Version == null ? "" : package.Version.ToNormalizedString()))) .Distinct() .ToList(); var addCount = addedPackages.Count; //updated packages can have an old and a new id. updatedPackagesOld = results.SelectMany(result => result.Updated) .Select(package => new Tuple <string, string>(package.Old.Id, (package.Old.Version == null ? "" : package.Old.Version.ToNormalizedString()))) .Distinct() .ToList(); updatedPackagesNew = results.SelectMany(result => result.Updated) .Select(package => new Tuple <string, string>(package.New.Id, (package.New.Version == null ? "" : package.New.Version.ToNormalizedString()))) .Distinct() .ToList(); var updateCount = updatedPackagesNew.Count; // update packages count packageCount = addCount + updateCount; if (updateCount > 0) { // set operation type to update when there are packages being updated operationType = NuGetOperationType.Update; } } TelemetryServiceUtility.StopTimer(); // Show the preview window. if (uiService.DisplayPreviewWindow) { bool shouldContinue = uiService.PromptForPreviewAcceptance(results); if (!shouldContinue) { continueAfterPreview = false; return; } } TelemetryServiceUtility.StartOrResumeTimer(); // Show the license acceptance window. bool accepted = await CheckLicenseAcceptanceAsync(uiService, results, cancellationToken); TelemetryServiceUtility.StartOrResumeTimer(); if (!accepted) { acceptedLicense = false; return; } // Warn about the fact that the "dotnet" TFM is deprecated. if (uiService.DisplayDeprecatedFrameworkWindow) { bool shouldContinue = await ShouldContinueDueToDotnetDeprecationAsync(projectManagerService, uiService, cancellationToken); TelemetryServiceUtility.StartOrResumeTimer(); if (!shouldContinue) { return; } } if (!cancellationToken.IsCancellationRequested) { await projectManagerService.ExecuteActionsAsync( actions, cancellationToken); string[] projectIds = actions .Select(action => action.ProjectId) .Distinct() .ToArray(); uiService.UIContext.RaiseProjectActionsExecuted(projectIds); } else { status = NuGetOperationStatus.Cancelled; } } catch (System.Net.Http.HttpRequestException ex) { status = NuGetOperationStatus.Failed; if (ex.InnerException != null) { uiService.ShowError(ex.InnerException); } else { uiService.ShowError(ex); } } catch (Exception ex) { status = NuGetOperationStatus.Failed; uiService.ShowError(ex); } finally { TelemetryServiceUtility.StopTimer(); var duration = TelemetryServiceUtility.GetTimerElapsedTime(); uiService.ProjectContext.Log(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Operation_TotalTime, duration)); uiService.EndOperation(); // don't show "Succeeded" if we actually cancelled... if ((!continueAfterPreview) || (!acceptedLicense)) { if (status == NuGetOperationStatus.Succeeded) { status = NuGetOperationStatus.Cancelled; } } var plc = new PackageLoadContext(isSolution: false, uiService.UIContext); IReadOnlyCollection <string> frameworks = await plc.GetSupportedFrameworksAsync(); string[] projectIds = (await ProjectUtility.GetSortedProjectIdsAsync( uiService.UIContext.ServiceBroker, uiService.Projects, cancellationToken)).ToArray(); var packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(uiService.Settings); bool isPackageSourceMappingEnabled = packageSourceMapping?.IsEnabled ?? false; var actionTelemetryEvent = new VSActionsTelemetryEvent( uiService.ProjectContext.OperationId.ToString(), projectIds, operationType, OperationSource.UI, startTime, status, packageCount, DateTimeOffset.Now, duration.TotalSeconds, isPackageSourceMappingEnabled: isPackageSourceMappingEnabled); var nuGetUI = uiService as NuGetUI; AddUiActionEngineTelemetryProperties( actionTelemetryEvent, continueAfterPreview, acceptedLicense, userAction, nuGetUI?.SelectedIndex, nuGetUI?.RecommendedCount, nuGetUI?.RecommendPackages, nuGetUI?.RecommenderVersion, nuGetUI?.TopLevelVulnerablePackagesCount ?? 0, nuGetUI?.TopLevelVulnerablePackagesMaxSeverities?.ToList() ?? new List <int>(), existingPackages, addedPackages, removedPackages, updatedPackagesOld, updatedPackagesNew, frameworks); actionTelemetryEvent["InstalledPackageEnumerationTimeInMilliseconds"] = packageEnumerationTime.ElapsedMilliseconds; TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent); } }, cancellationToken); }
public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken) { var searchToken = continuationToken as FeedSearchContinuationToken; if (searchToken == null) { throw new InvalidOperationException("Invalid token"); } if (_context != null) { _installedPackages = await _context.GetInstalledPackagesAsync(); _context = null; } var packagesNeedingConsolidation = _installedPackages .GroupById() .Where(g => g.Count() > 1) .Select(g => new PackageIdentity(g.Key, g.Max())) .ToArray(); var packages = packagesNeedingConsolidation .Where(p => p.Id.IndexOf(searchToken.SearchString, StringComparison.OrdinalIgnoreCase) != -1) .OrderBy(p => p.Id) .Skip(searchToken.StartIndex) .Take(PageSize + 1) .ToArray(); var hasMoreItems = packages.Length > PageSize; if (hasMoreItems) { packages = packages.Take(packages.Length - 1).ToArray(); } var items = await TaskCombinators.ThrottledAsync( packages, (p, t) => _metadataProvider.GetPackageMetadataAsync(p, searchToken.SearchFilter.IncludePrerelease, t), cancellationToken); var result = SearchResult.FromItems(items.ToArray()); var loadingStatus = hasMoreItems ? LoadingStatus.Ready : packages.Length == 0 ? LoadingStatus.NoItemsFound : LoadingStatus.NoMoreItems; result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { { "Consolidate", loadingStatus } }; if (hasMoreItems) { result.NextToken = new FeedSearchContinuationToken { SearchString = searchToken.SearchString, SearchFilter = searchToken.SearchFilter, StartIndex = searchToken.StartIndex + packages.Length }; } return(result); }
/// <summary> /// The internal implementation to perform user action. /// </summary> /// <param name="resolveActionsAsync">A function that returns a task that resolves the user /// action into project actions.</param> /// <param name="executeActionsAsync">A function that returns a task that executes /// the project actions.</param> private async Task PerformActionImplAsync( INuGetUI uiService, Func <SourceCacheContext, Task <IReadOnlyList <ResolvedAction> > > resolveActionsAsync, Func <IReadOnlyList <ResolvedAction>, SourceCacheContext, Task> executeActionsAsync, NuGetOperationType operationType, UserAction userAction, CancellationToken token) { var status = NuGetOperationStatus.Succeeded; var startTime = DateTimeOffset.Now; var packageCount = 0; bool continueAfterPreview = true; bool acceptedLicense = true; List <string> removedPackages = null; HashSet <Tuple <string, string> > existingPackages = new HashSet <Tuple <string, string> >(); List <Tuple <string, string> > addedPackages = null; List <Tuple <string, string> > updatedPackagesOld = null; List <Tuple <string, string> > updatedPackagesNew = null; // Enable granular level telemetry events for nuget ui operation uiService.ProjectContext.OperationId = Guid.NewGuid(); Stopwatch packageEnumerationTime = new Stopwatch(); packageEnumerationTime.Start(); try { // collect the install state of the existing packages foreach (var project in uiService.Projects) { var result = await project.GetInstalledPackagesAsync(token); foreach (var package in result) { Tuple <string, string> packageInfo = new Tuple <string, string>(package.PackageIdentity.Id, (package.PackageIdentity.Version == null ? "" : package.PackageIdentity.Version.ToNormalizedString())); if (!existingPackages.Contains(packageInfo)) { existingPackages.Add(packageInfo); } } } } catch (Exception) { // don't teardown the process if we have a telemetry failure } packageEnumerationTime.Stop(); await _lockService.ExecuteNuGetOperationAsync(async() => { try { uiService.BeginOperation(); var acceptedFormat = await CheckPackageManagementFormat(uiService, token); if (!acceptedFormat) { return; } TelemetryServiceUtility.StartOrResumeTimer(); using (var sourceCacheContext = new SourceCacheContext()) { var actions = await resolveActionsAsync(sourceCacheContext); var results = GetPreviewResults(actions); if (operationType == NuGetOperationType.Uninstall) { // removed packages don't have version info removedPackages = results.SelectMany(result => result.Deleted) .Select(package => package.Id) .Distinct() .ToList(); packageCount = removedPackages.Count; } else { // log rich info about added packages addedPackages = results.SelectMany(result => result.Added) .Select(package => new Tuple <string, string>(package.Id, (package.Version == null ? "" : package.Version.ToNormalizedString()))) .Distinct() .ToList(); var addCount = addedPackages.Count; //updated packages can have an old and a new id. updatedPackagesOld = results.SelectMany(result => result.Updated) .Select(package => new Tuple <string, string>(package.Old.Id, (package.Old.Version == null ? "" : package.Old.Version.ToNormalizedString()))) .Distinct() .ToList(); updatedPackagesNew = results.SelectMany(result => result.Updated) .Select(package => new Tuple <string, string>(package.New.Id, (package.New.Version == null ? "" : package.New.Version.ToNormalizedString()))) .Distinct() .ToList(); var updateCount = updatedPackagesNew.Count; // update packages count packageCount = addCount + updateCount; if (updateCount > 0) { // set operation type to update when there are packages being updated operationType = NuGetOperationType.Update; } } TelemetryServiceUtility.StopTimer(); // Show the preview window. if (uiService.DisplayPreviewWindow) { var shouldContinue = uiService.PromptForPreviewAcceptance(results); if (!shouldContinue) { continueAfterPreview = false; return; } } TelemetryServiceUtility.StartOrResumeTimer(); // Show the license acceptance window. var accepted = await CheckLicenseAcceptanceAsync(uiService, results, token); TelemetryServiceUtility.StartOrResumeTimer(); if (!accepted) { acceptedLicense = false; return; } // Warn about the fact that the "dotnet" TFM is deprecated. if (uiService.DisplayDeprecatedFrameworkWindow) { var shouldContinue = ShouldContinueDueToDotnetDeprecation(uiService, actions, token); TelemetryServiceUtility.StartOrResumeTimer(); if (!shouldContinue) { return; } } if (!token.IsCancellationRequested) { // execute the actions await executeActionsAsync(actions, sourceCacheContext); // fires ActionsExecuted event to update the UI uiService.OnActionsExecuted(actions); } else { status = NuGetOperationStatus.Cancelled; } } } catch (System.Net.Http.HttpRequestException ex) { status = NuGetOperationStatus.Failed; if (ex.InnerException != null) { uiService.ShowError(ex.InnerException); } else { uiService.ShowError(ex); } } catch (Exception ex) { status = NuGetOperationStatus.Failed; uiService.ShowError(ex); } finally { TelemetryServiceUtility.StopTimer(); var duration = TelemetryServiceUtility.GetTimerElapsedTime(); uiService.ProjectContext.Log(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Operation_TotalTime, duration)); uiService.EndOperation(); // don't show "Succeeded" if we actually cancelled... if ((!continueAfterPreview) || (!acceptedLicense)) { if (status == NuGetOperationStatus.Succeeded) { status = NuGetOperationStatus.Cancelled; } } PackageLoadContext plc = new PackageLoadContext(sourceRepositories: null, isSolution: false, uiService.UIContext); var frameworks = plc.GetSupportedFrameworks().ToList(); var actionTelemetryEvent = VSTelemetryServiceUtility.GetActionTelemetryEvent( uiService.ProjectContext.OperationId.ToString(), uiService.Projects, operationType, OperationSource.UI, startTime, status, packageCount, duration.TotalSeconds); var nuGetUI = uiService as NuGetUI; AddUiActionEngineTelemetryProperties( actionTelemetryEvent, continueAfterPreview, acceptedLicense, userAction, nuGetUI?.SelectedIndex, nuGetUI?.RecommendedCount, nuGetUI?.RecommendPackages, nuGetUI?.RecommenderVersion, existingPackages, addedPackages, removedPackages, updatedPackagesOld, updatedPackagesNew, frameworks); actionTelemetryEvent["InstalledPackageEnumerationTimeInMilliseconds"] = packageEnumerationTime.ElapsedMilliseconds; TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent); } }, token); }
public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken) { var searchToken = continuationToken as FeedSearchContinuationToken; if (searchToken == null) { throw new InvalidOperationException("Invalid token"); } if (_context != null) { _installedPackages = await _context.GetInstalledPackagesAsync(); _context = null; } var packages = _installedPackages .GetLatest() .Where(p => p.Id.IndexOf(searchToken.SearchString, StringComparison.OrdinalIgnoreCase) != -1) .OrderBy(p => p.Id) .Skip(searchToken.StartIndex) .Take(PageSize + 1) .ToArray(); var hasMoreItems = packages.Length > PageSize; if (hasMoreItems) { packages = packages.Take(packages.Length - 1).ToArray(); } var items = await TaskCombinators.ThrottledAsync( packages, (p, t) => GetPackageMetadataAsync (p, searchToken.SearchFilter.IncludePrerelease, t), cancellationToken); // The packages were originally sorted which is important because we Skip and Take based on that sort // however the asynchronous execution has randomly reordered the set. So we need to resort. var result = SearchResult.FromItems(items.OrderBy(p => p.Identity.Id).ToArray()); var loadingStatus = hasMoreItems ? LoadingStatus.Ready : packages.Length == 0 ? LoadingStatus.NoItemsFound : LoadingStatus.NoMoreItems; result.SourceSearchStatus = new Dictionary <string, LoadingStatus> { { "Installed", loadingStatus } }; if (hasMoreItems) { result.NextToken = new FeedSearchContinuationToken { SearchString = searchToken.SearchString, SearchFilter = searchToken.SearchFilter, StartIndex = searchToken.StartIndex + packages.Length }; } return(result); }