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 support for visualizing Preference markers #2178
Add support for visualizing Preference markers #2178
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2178 +/- ##
==========================================
- Coverage 85.73% 85.71% -0.02%
==========================================
Files 200 200
Lines 13899 13902 +3
Branches 3497 3498 +1
==========================================
Hits 11916 11916
- Misses 1817 1820 +3
Partials 166 166
Continue to review full report at Codecov.
|
Codecov Report
@@ Coverage Diff @@
## master #2178 +/- ##
==========================================
+ Coverage 85.86% 85.87% +0.01%
==========================================
Files 200 200
Lines 13999 14019 +20
Branches 3532 3544 +12
==========================================
+ Hits 12020 12039 +19
- Misses 1813 1814 +1
Partials 166 166
Continue to review full report at Codecov.
|
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.
Thanks for this addition!
Marking as "request changes" mostly because of questions and adding a test, but otherwise it looks good to me!
By chance, do you have a profile example containing this data so that we can try it out as well?
Also to make sure we don't regress by mistake, it would be a good idea to add a typical preference marker in
], |
yarn test -u TooltipMarker
.
Lastly, do you think there could be some PII (personally identifiable information) in this data, that we should give the option to remove when publishing a profile?
I do, and will upload it here!
Will do!
Great catch! Yes, we should mark the "Value" as being something that the user does not publish. Is there a way to mark the field as such? |
We don't have such automatic behavior unfornately :( Instead we need to write some adhoc code. Our sanitization code is in the file https://github.com/firefox-devtools/profiler/blob/master/src/profile-logic/sanitize.js. For example this is where we handle network markers: profiler/src/profile-logic/sanitize.js Lines 177 to 190 in 1fb607c
I think we'll need a new checkbox in our publish panel. Here is how this can be done:
Please tell me if this is too much for you and we can look into handling that for you. |
Let me know what you think about these changes! I tested the functionality and it "works" but I would definitely appreciate your feedback! Thanks for the documentation that you provided on how to do the sanitization. It was pretty easy thanks to what you sent! Thanks again! |
@julienw I know that I need to work the code coverage issues, but I'm not exactly sure how I would do that. If you could give me some instructions, I am glad to take care of it! Thanks for your mentorship on this! |
The changes look good! For tests, I think the main miss is about the sanitization.
Also I'm still waiting for a link and/or a way to capture a profile with preference markers myself, and also a link to the bugzilla bug number in this PR like Markus requested. What's not clear to me either is whether these markers will be exposed to everybody or if we'll need a custom build or a custom pref or something. If we don't expose them more generally, maybe we don't need the sanitization at all, but that's more your call! Hope that helps :) |
At that link is a profile with Preference markers that can be used to do the testing! |
We have updated the Gecko side of this so that marking preference reads is configurable at run time and not compile time. I think that means that the sanitization addition will not be that confusing to users. What do you think? Have a great weekend! |
An updated profile to use to test the FE. |
So, we discussed my colleagues, and reached an agreement that we want to provide the option, but only when there actually are some preference markers.
const getHasPreferenceMarkers: Selector<boolean> = createSelector(
getThreads,
threads => {
return threads.some(({ stringTable, markers }) => {
const indexForPreference = stringTable.indexForString('Preference');
return markers.name.some(name => name === indexForPreference);
});
}
); I'll let you adjust the exact condition, but note that here we deal with the raw marker table, not the derived marker list. The structure is a bit different. Especially the array of names is an array of indexes that we need to look up using If instead you want to use the const getHasPreferenceMarkers: Selector<boolean> = createSelector(
getThreads,
threads => {
return threads.some(({ markers }) => {
return markers.data.some(data => data && data.type === 'Preference');
});
}
);
Again, please tell me if this is too much work for you and I'd be happy to look at it closer and polish it. Thanks! |
Thank you for your reply! I will make this change and I will submit a
follow-up! Thanks for the detailed explanation!
…On Mon, Aug 5, 2019 at 12:55 PM Julien Wajsberg ***@***.***> wrote:
So, we discussed my colleagues, and reached an agreement that we want to
provide the option, but only when there actually are some preference
markers.
Here is how it can be done:
1. have a selector that returns "are there at least one preference
marker". It should probably be in src/selectors/profile.js because we
want it to compute from the whole profile (as opposed to the selectors of
per-thread that apply to one specific thread) and be something like
this:
const getHasPreferenceMarkers: Selector<boolean> = createSelector(
getThreads,
threads => {
return threads.some(({ stringTable, markers }) => {
const indexForPreference = stringTable.indexForString('Preference');
return markers.name.some(name => name === indexForPreference);
});
}
);
I'll let you adjust the exact condition, but note that here we deal with
the raw marker table, not the derived marker list. The structure is a bit
different
<https://github.com/firefox-devtools/profiler/blob/355fabf29e69ae79ac2a609ddb78e77c1d1ba9c7/src/types/profile.js#L141-L146>.
Especially the array of names is an array of indexes that we need to look
up using thread.stringTable, but because they're unique for a string in a
thread, we can look it up once at the start and compare the integers, which
is likely more performance that comparing strings.
If instead you want to use the type property inside the data array this
could look like this:
const getHasPreferenceMarkers: Selector<boolean> = createSelector(
getThreads,
threads => {
return threads.some(({ markers }) => {
return markers.data.some(data => data && data.type === 'Preference');
});
}
);
1. Then MenuButtonsPublish could take the result of this new selector
to decide whether to display the new checkbox.
Again, please tell me if this is too much work for you and I'd be happy to
look at it closer and polish it.
Thanks!
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#2178?email_source=notifications&email_token=ACCP2CUIP3CBAY2RFKOD2MLQDBLRXA5CNFSM4IHW6EYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3SNOWY#issuecomment-518313819>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACCP2CS7CK6HTKFGVUZNAZ3QDBLRXANCNFSM4IHW6EYA>
.
|
I removed my review request to clean up my queue a bit, but please put up the review flag again once you're ready! Thanks :) |
I honestly think that just by putting up a new version of the code you will get notified. If not, here's an @julienw just to make sure :-) |
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.
Thanks for the patch!
The conditional checkbox works fine.
But I don't see the tooltips working anymore and I'm not sure why.
Also there are some things I don't understand properly, especially how the type
and the name
relate.
My understanding is that type
should be Preference
but name
could change, for example PreferenceRead
and PreferenceWrite
depending on the action happening in the browser, but tell me what you think (this would be a change in the gecko patch, then).
Also there's a very easy conflict in src/types/markers
so it would be nice to rebase on top of latest master.
Note I'll be away next week, but @canaltinova or @gregtatum should be able to move this forward with you.
'includePreferenceValues', | ||
'Include preference values' | ||
) | ||
: ''} |
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.
: ''} | |
: null} |
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.
Happy to change!
'PreferenceRead', | ||
114.9, | ||
{ | ||
type: 'PreferenceRead', |
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.
should that be Preference
or PreferenceRead
?
My understanding is that we should have type
as Preference
, but the name above being PreferenceRead
or PreferenceWrite
. Is that it?
const indexForPreferenceString = stringTable.indexForString( | ||
'PreferenceRead' | ||
); | ||
return markers.name.some(name => name === indexForPreferenceString); |
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.
See the other comment below too: It's not clear to me what name
and type
should be, and if we can have several name
s in the future, but only one type, maybe it's better to use the type here.
What do you think?
src/profile-logic/sanitize.js
Outdated
PIIToBeRemoved.shouldRemovePreferenceValues && | ||
currentMarker && | ||
currentMarker.type && | ||
currentMarker.type === 'Preference' |
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.
so, this doesn't seem to work now :) at least not in the example you provided.
My feeling (as said in the comments below) is that the type
should indeed be Preference
and then this code would actually work, but this is not what I see in the profile for now.
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, you're right. That sample will no longer work. We changed the name in the gecko profiler patch to make it more obvious that these are preference reads and not some of those type of access. Because of that, the logic changed and older data captures won't work any more. I will post another test data file. Sorry!
@@ -545,6 +545,17 @@ function getMarkerDetails( | |||
); | |||
break; | |||
} | |||
case 'PreferenceRead': { |
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.
same thing here: my understanding is that the type
should be Preference
:)
Also curiously this doesn't seem to work, see the tooltips in https://deploy-preview-2178--perf-html.netlify.com/public/53ce5ae957fdfeb423d466f435b5bb2e3555cdde/marker-chart/?globalTrackOrder=0-1-2-3-4-5-6&hiddenGlobalTracks=1-2-3-4-5&localTrackOrderByPid=26901-1-2-0~26929-0~27279-0~27073-0~27115-0~27019-0~26966-0-1~&markerSearch=preference&thread=7&v=4
Right now the type and the name are the same, as you say. I don't believe that there's much of a use case to generate markers about preference writes. If it's okay with you, I will keep them both the same. In other words, the type of the marker will be PerformanceRead and the name of the marker will be PerformanceRead. Is that okay? |
If that's ok for you and the reviewer for the gecko patch then it's ok for
me !
|
As promised, an updated profile with legitimate testing data! |
I just finished rebasing on top of master so that it should merge cleanly. It looks like all the tests pass. Let me know what you think about this version and how we should proceed! |
I think the main code looks good, but that we need tests to check some of the new functionality, especially that this code won't be exercized manually a lot and we might miss bugs too easily. I think there are 2 blind spots:
For 1, I think this would happen in
For 2, I think the instructions in #2178 (comment) are still valid. Tell me if you need anything more. I think we're pretty close! |
@julienw Thank you very much for the comments on the previous iteration and the instructions for how to add the appropriate tests. I think that the code that is in this PR now should satisfy all your requested changes. Let me know what you think! Thanks again for all your help! |
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 marking the PR as "approved" but I outlined a change for the new test in sanitize.js
that would make it both easier to read and more solid in my opinion.
Once this change is in I think we can merge!
@julienw Thanks for your previous review and your approval of the version prior to this revision. I'd love your feedback on the latest version! I hope that it satisfies your comments. Thanks again for the review and working with me on this! |
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.
still a few comments about the tests :) I think they're still more complex than they could.
There is a new type of marker landing in Gecko called Preference. This marker marks each time a preference is accessed, its name, kind, type and value. This PR adds support for showing this marker's data in a tooltip.
expect(thread.markers.length).toEqual(1); | ||
|
||
const marker = thread.markers.data[0]; | ||
// All the conditions have to be checked to make Flow happy. |
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 tests we sometimes use shortcuts and use any
, like expect((marker: any).prefValue).toEqual('preferenceValue')
. It's less a big deal in tests to use any
especially for expectations.
But I think this is good as it is too so I'll just merge this, thanks :)
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.
Sadly, this is exactly the approach I was trying to avoid. I knew that would work but since it's a total subversion of the type checker, I was trying not to use it. The approach I took feels better to me but the next time I will go with the "easier" version. Thanks again for all the mentorship on landing this!
There is a new type of marker landing in Gecko called Preference.
This marker marks each time a preference is accessed, its name, kind,
type and value. This PR adds support for showing this marker's data
in a tooltip.
Bugzilla side: https://bugzilla.mozilla.org/show_bug.cgi?id=1551313