Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'Analytic Summary' & PerformanceRecorderEngine to Quiet Background Processes feature #2596

Merged
merged 17 commits into from
Apr 17, 2024

Conversation

jsidewhite
Copy link
Member

@jsidewhite jsidewhite commented Apr 11, 2024

Summary of the pull request

Add 'Analytic Summary' & PerformanceRecorderEngine to Quiet Background Processes feature

  • When starting a quiet session, also start a performance recording session

  • Added Analytic Summary with process performance table (incl. filtering and sorting)

    • Displays gathered metrics from processes running during a quiet session
  • Add usage telemetry

  • Updated icon & strings from Content UX session

analyticSummary

References and relevant issues

Detailed description of the pull request / Additional comments

Validation steps performed

PR checklist

  • Closes #xxx
  • Tests added/passed
  • Documentation updated

@@ -23,7 +23,7 @@ public static IServiceCollection AddWindowsCustomization(this IServiceCollection
services.AddSingleton<DevDriveInsightsViewModel>();
services.AddTransient<DevDriveInsightsPage>();

services.AddTransient<QuietBackgroundProcessesViewModel>();
services.AddTransient<DevHome.QuietBackgroundProcesses.UI.ViewModels.QuietBackgroundProcessesViewModel>();
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probs can put DevHome.QuietBackgroundProcess.UI.ViewModels into a using statement, ya? #Resolved

[default_interface]
runtimeclass ProcessRow
{
Int64 Pid { get; };
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: UInt64 unless process IDs can be negative. #Resolved


UInt64 SampleCount { get; };
Single PercentCumulative { get; };
Single VarianceCumulative { get; };
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Single instead of Double? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not. Let's.

runtimeclass PerformanceRecorderEngine
{
PerformanceRecorderEngine();
void Start(Int32 periodInMs);
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows.Foundation.TimeSpan instead of an int. This way Start can convert to microseconds. #Resolved

<Import Project="$(SolutionDir)ToolingVersions.props" />
<Import Project="$(SolutionDir)Directory.CppBuild.props" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe DevHome does not support ARM. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can't figure out why VS keeps adding this...

<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>false</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.22000.0</WindowsTargetPlatformVersion>
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use SDK version 22621. The SDK version was recently updated. #Resolved


ProcessCategory GetCategory(DWORD pid, std::wstring_view processName)
{
auto search = [&](std::wstring_view processName, const auto& list) {
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bracket should be on a new line. #Resolved


public AdvancedCollectionView ProcessDatasAd { get; private set; }

private DevHome.QuietBackgroundProcesses.UI.ProcessData.ProcessCategory ConvertProcessType(DevHome.QuietBackgroundProcesses.ProcessCategory inputType)
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DevHome.QuietBackgroundProcesses.UI.ProcessData can go into a using statement, ya? #Resolved

Grid.Column="1"
x:Name="SortComboBox"
Margin="5 0 5 0"
PlaceholderText="Sort by"
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Sort By need localization? #Resolved


<Grid Grid.Row="2" Background="{StaticResource SmokeFillColorDefaultBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
Copy link
Contributor

@dhoehna dhoehna Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Columns default to a width of * #Resolved

this.Hide();
}

private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
Copy link
Collaborator

@krschau krschau Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should make this a RelayCommand on the ViewModel and not have to route it through the View. #Resolved

Copy link
Member Author

@jsidewhite jsidewhite Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble finding the role of the view in this MVVM paradigm. Is it always supposed to be empty?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems weird at first, but actually kind of yes -- the more you can get out of the View and into the ViewModel the better. I think of it as the ViewModel has everything the View needs to know, but the View could take all the information and lay it out totally differently. So, if the text of the Filter changes, you'd want to know and react to that no matter how the page is laid out.

In case you haven't seen it before, this is a really good in-depth paper about MVVM and I usually refer to it when I have questions: https://dotnet.microsoft.com/en-us/download/e-book/maui/pdf

@@ -61,15 +63,30 @@ namespace ABI::DevHome::QuietBackgroundProcesses
// Start timer
g_activeTimer.reset(new TimedQuietSession(duration));

// Start performance recorder
Copy link
Contributor

@nieubank nieubank Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

performance recorder

have you measured the performance impact of collecting the trace? Looks like the impact may scale linearly with increasing running processes. May be worth having a checkbox that enabled/disable analytics collection? #ByDesign

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so... the tracing traces itself :P (you can see its non-zero impact in its own output)

I'll bring it up with Bridget & Tyler.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, on my VM it's about 0.25% of the CPU

…d Processes feature

* When starting a quiet session, also start a performance recording session

* Added Analytic Summary with process performance table (incl. filtering and sorting)

    * Displays gathered metrics from processes running during a quiet session

* Add usage telemetry

* Updated icon & strings from Content UX session
@jsidewhite jsidewhite force-pushed the user/jwhites/analytic_summary_pr3 branch from f35affb to c822338 Compare April 16, 2024 05:54
}
catch (Exception ex)
{
_log.Error("Error populating performance summary table", ex);
Copy link
Collaborator

@krschau krschau Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's an exception, a user will see the table up to that point, yeah? Should we show an error instead? Or should we put the try/catch inside the loop so they can get more of the table? If we want to do either of these it can come in as a separate change. #WontFix

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table will be empty - we never populate ProcessDatasAd. I think showing the user an error is a good idea - but nobody can tell me how to surface errors to the user in Dev Home.

public void SortProcessesComboBoxChanged(string selectedValue)
{
ProcessDatasAd.SortDescriptions.Clear();
if (selectedValue == "Process")
Copy link
Collaborator

@krschau krschau Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to use string.Equals #Resolved

ProcessDatasAd.SortDescriptions.Clear();
if (selectedValue == "Process")
{
ProcessDatasAd.SortDescriptions.Add(new SortDescription("Name", SortDirection.Ascending));
Copy link
Collaborator

@krschau krschau Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better/safer to have these Name/Category/TimeAboveThreshold strings be an enum? #Resolved

Comment on lines 22 to 24
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
Copy link
Collaborator

@krschau krschau Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this.

Suggested change
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
``` #Resolved

<ListView.Header>
<Grid ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
Copy link
Collaborator

@krschau krschau Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point you should go through this with System Text scaling up to 200%. You'll probably want to hard-code less and/or make some things that are currently Height/Width => MinHeight/MinWidth, to prevent text getting cut off and accessibility bugs. #WontFix

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got super stumped - everything started with * and Auto, but devolved to hardcoded values over days of fumbling around. Need to learn the magics.

Copy link
Member Author

@jsidewhite jsidewhite Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely address in the next pass.

Because this isn't part of the main Dev Home window, but rather limited to the pop up dialog, going to suggest WontFix (and feel guilty about it)

HorizontalAlignment="Left"
HorizontalTextAlignment="Left"
TextTrimming="CharacterEllipsis"
Padding="11 11 11 11" />
Copy link
Collaborator

@krschau krschau Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nit/personal preference, but sometimes here it's just simpler to say "Padding="11"" (if they're all the same, you can just use one) #Resolved

{
var analyticSummaryPopup = new AnalyticSummaryPopup(ViewModel.GetProcessPerformanceTable());
analyticSummaryPopup.XamlRoot = this.Content.XamlRoot;
analyticSummaryPopup.RequestedTheme = this.ActualTheme;
Copy link
Collaborator

@krschau krschau Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this will prevent the theme from updating if you were to have this open and change the system theme.
Does this work?

Suggested change
analyticSummaryPopup.RequestedTheme = this.ActualTheme;
analyticSummaryPopup.RequestedTheme = this.RequestedTheme;

That way "Default" could be passed through instead of only Dark or Light. #ByDesign

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i change to RequestedTheme, then I get a mix of Dark & Light UI. ActualTheme seems to keep it consistent.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably indicates other issues. Keep it for now but consider trying to fix it in the future.

Copy link
Member Author

@jsidewhite jsidewhite Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sticking with ActualTheme after discussing behavior in side chat

@krschau krschau added this to the Dev Home v0.13 milestone Apr 16, 2024
@kanismohammed kanismohammed self-requested a review April 16, 2024 20:21
@jsidewhite jsidewhite closed this Apr 17, 2024
@jsidewhite jsidewhite reopened this Apr 17, 2024
@kanismohammed kanismohammed merged commit 887850f into main Apr 17, 2024
7 checks passed
@krschau krschau deleted the user/jwhites/analytic_summary_pr3 branch June 17, 2024 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants