-
Notifications
You must be signed in to change notification settings - Fork 340
Configure GA for memory screen. #4705
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything LGTM from a code point of view, but I'd feel more comfortable letting @kenzieschmoll verify to make sure the analytics changes are good.
@@ -35,7 +35,8 @@ class MemorySettingsDialog extends StatelessWidget { | |||
children: [ | |||
CheckboxSetting( | |||
notifier: preferences.memory.androidCollectionEnabled, | |||
title: 'Show Android memory chart', | |||
title: | |||
'Show Android memory chart in addition to Dart memory chart', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a tooltip?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, it is label for the checkbox in the settings dialog.
// Make sure the method does not trigger itself recursively. | ||
assert(!_updatingValues); | ||
_updatingValues = true; | ||
_startUpdatingValues(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of using timeStart and timeEnd, you could use timeSync, and place the whole body of this method in the syncOperation function parameter. This will be less added lines of code and will reduce some duplication
ga.timeSync(
analytics_constants.memory,
analytics_constants.MemoryTime.updateValues,
syncOperation: () {
... the previous body of this entire method
},
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about it. There are other non-functional operations to be done at start and at end. The current structure seems to be most readable for me, as non-functional elements do not crowd the method. Yes, at cost of code duplicates.
objectsAfter: couple.younger.data.objects.length, | ||
), | ||
); | ||
return result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the catch block in timeSync is hit, this will throw a late initialization error. Should we let result be nullable to handle this? or rethrow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ProcessCancelledException will never be thrown by DiffHeapClasses. If we ever start supporting it, we will test how it works and make needed adjustments.
But, what's the reason for timeSync to handle ProcessCancelledException? It seems it should be handled by the entity that started the calculation and wants to consume the result. Am I wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not referring to ProcessCancelledException. If any exception is thrown by the function passed to syncOperation, the catch block will be hit.
return result; | ||
} | ||
|
||
class _DiffAnalyticsMetrics extends ScreenAnalyticsMetrics { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any custom metrics added in a ScreenAnalyticsMetrics subclass will need to be added to the _gtagEvent, _gtagException, and the GtagEventDevTools class in _analytics_web.dart. These will also need to be added in the Analytics360 console.
For all these reasons, we should make sure any custom metrics we want to add really will add meaning to our analysis of the timed operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would also be preferable if we didn't have multiple ScreenAnalyticsMetrics subclasses for a single screen. For example, the only existing subclasses we currently have are PerformanceScreenMetrics and ProfilerScreenMetrics, so ideally we could also have MemoryScreenMetrics that hold all the custom metrics we need for the Memory screen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks to be cleaner to put the subclasses to the folder 'analytics', the same way as constants, so that analytics_web does not have to depend on individual screen folders.
I will move other subclasses later, in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a guidance to add this to the Analytics360 console?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I may be the only one with Admin access to our console, so if you can make the changes to the analytics_web file, I will update the analytics 360 console when those land. The order matters here (you'll see other comments like "// metric5, // metric6", so once the changes are in the order should not be changed.
...tools_app/lib/src/screens/memory/panes/allocation_profile/allocation_profile_table_view.dart
Outdated
Show resolved
Hide resolved
onChanged: (value) { | ||
ga.select( | ||
analytics_constants.memory, | ||
analytics_constants.MemoryEvent.tracingClassFilter, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this be triggered on every update to the text field? We probably don't want to send an analytics event for every character change to the text field. Can we send this in onSubmitted or onEditingComplete instead? You'll have to play with this a bit to make sure we send the event at the right time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added throttling to handle this.
ga.select( | ||
analytics_constants.memory, | ||
analytics_constants.sourcesDropDown, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we removing this because we are removing the SourcesDropdown feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, as we agreed in #4645, we will redesign the feature. I do not see value in maintaining analytics for it.
packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_control_pane.dart
Outdated
Show resolved
Hide resolved
packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_list.dart
Outdated
Show resolved
Hide resolved
packages/devtools_app/lib/src/screens/memory/shared/heap/model.dart
Outdated
Show resolved
Hide resolved
numberOfObjects: graph.objects.length, | ||
), | ||
); | ||
return result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also same comment about whether we should add handling for the case when the timeSync catch block is hit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added rethrow to tymeSync
analytics_constants.memory, | ||
analytics_constants.MemoryEvent.tracingClassFilter, | ||
); | ||
_sendFilterEditGaEvent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason we can't use onSubmitted or onEditingComplete? Seems a bit hack to throttle when we can use one of the text field lifecycle methods that indicates "the user is done editing"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both are designed to handle ui forms or dialogs that at some moment are 'done'. they need special signal that editing is done. it is not our case.
throttling seems to be simplest and most reliable way to handle ga for filter
packages/devtools_app/lib/src/screens/profiler/cpu_profile_controller.dart
Outdated
Show resolved
Hide resolved
@@ -42,6 +45,17 @@ class DiffPaneController extends DisposableController { | |||
// is taken, and is used to assign a unique id to each [SnapshotListItem]. | |||
int _snapshotId = 0; | |||
|
|||
VoidCallback? takeSnapshotHandler(String gaEvent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of adding an additional handler, can we just add an optional parameter gaEvent
to takeSnapshot and send the analytics event from there?
Then from the widget code:
onPressed: () => controller.takeSnapshot(myGaEvent)
I'm not seeing extra value by adding an additional method, plus this adds risk that takeSnapshot can be called from somewhere else and analytics will not be recorded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In both cases the handler should be null if snapshot taking is already in process. I do not want this logic to be duplicated.
No description provided.