-
Notifications
You must be signed in to change notification settings - Fork 54
NEW (GraphEngine): @W-11989381@: New MultipleMassSchemaLookupRule to detect performance degrading schema lookups. #1054
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
| public static final String MESSAGE_TEMPLATE = | ||
| "Avoid excessive Schema lookups in a single path. Detected %s %s at %s:%d."; | ||
| public static final String OCCURRENCE_LOOP_TEMPLATE = "inside a %s"; | ||
| public static final String OCCURRENCE_MULTIPLE_TEMPLATE = "preceded by a call to %s"; |
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 update these based on UI text review.
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.
No real changes. spotless doing its thing.
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.
spotless, can be ignored.
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.
New afterVisit methods for loop vertices.
| if (ruleThrowable instanceof FlsViolationInfo) { | ||
| incompleteThrowables.add((FlsViolationInfo) ruleThrowable); | ||
| } else if (ruleThrowable instanceof MassSchemaLookupInfo) { | ||
| tempDeleteMe.add((MassSchemaLookupInfo) ruleThrowable); |
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.
Needs a minor refactor to clean up. Also, there seems to be a bug with multiple rule types. I'll address this in another commit.
| public static final class MultipleMassSchemaLookupRuleTemplates { | ||
| public static final String MESSAGE_TEMPLATE = "%s was %s at %s:%d."; | ||
| public static final String OCCURRENCE_LOOP_TEMPLATE = "called inside a %s"; | ||
| public static final String OCCURRENCE_MULTIPLE_TEMPLATE = "preceded by a call to %s"; | ||
| } |
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.
Approved UI text.
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.
Opening up loop vertices in visitor.
|
|
||
| @Override | ||
| protected boolean isEnabled() { | ||
| return true; |
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.
Rule is now enabled.
| if (ruleThrowable instanceof FlsViolationInfo) { | ||
| incompleteThrowables.add((FlsViolationInfo) ruleThrowable); | ||
| flsViolationInfos.add((FlsViolationInfo) ruleThrowable); | ||
| } else if (ruleThrowable instanceof MultipleMassSchemaLookupInfo) { | ||
| // FIXME: PR incoming with refactors to this portion | ||
| mmsLookupInfos.add((MultipleMassSchemaLookupInfo) ruleThrowable); |
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.
There's some duplication here that can be streamlined.
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 assuming the subsequent PR will involve refactoring this so it doesn't require a Set of MMS violations specifically?
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.
Right, I'm trying to move the ownership of conversion to the ViolationInfo object so that this portion can work on the higher-level interface.
| if (ruleThrowable instanceof FlsViolationInfo) { | ||
| incompleteThrowables.add((FlsViolationInfo) ruleThrowable); | ||
| flsViolationInfos.add((FlsViolationInfo) ruleThrowable); | ||
| } else if (ruleThrowable instanceof MultipleMassSchemaLookupInfo) { | ||
| // FIXME: PR incoming with refactors to this portion | ||
| mmsLookupInfos.add((MultipleMassSchemaLookupInfo) ruleThrowable); |
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 assuming the subsequent PR will involve refactoring this so it doesn't require a Set of MMS violations specifically?
| "public class MyClass {\n" | ||
| + " void foo() {\n" | ||
| + " " | ||
| + firstCall | ||
| + "();\n" | ||
| + " " | ||
| + secondCall | ||
| + "();\n" | ||
| + " }\n" | ||
| + "}\n"; |
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.
For the future, you can use spotless:off and spotless:on to avoid lines being split like this. Keeps the code readable.
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.
Agree. This got missed. Will clean it up.
| } | ||
|
|
||
| @Test | ||
| public void testLoopAfterGgdShouldNotGetViolation() { |
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.
This is a good test. Do we also want one for a loop before a GGD as a counterpart to this one? Also possibly a loop, then a separate loop with a GGD, to verify that it doesn't stop looking after the first loop?
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.
Just tried it out and the test fails. All great use cases. Will include them.
| if (vertex.equals(sinkVertex)) { | ||
| // Mark sink as visited. From this point on, we don't need to | ||
| // look for anymore loops or additional calls. | ||
| // TODO: A more performant approach would be to stop walking path from this point |
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 the idea that once a path is confirmed to violate the rule, there's no sense in continuing to check?
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.
This is to avoid continuing to look beyond the sink vertex.
| /** | ||
| * @return Violations collected by the rule. | ||
| */ | ||
| Set<MultipleMassSchemaLookupInfo> getViolation() { |
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.
Pedantic note: Should this be getViolations, plural, or is it only possible for there to be one violation?
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 be plural. I had forgotten to rename it after a change in structure where a single violation will be returned.
| // TODO: I'm expecting to add other visitors depending on the other factors we will analyze | ||
| // to decide if a GGD call is not performant. | ||
| DefaultSymbolProviderVertexVisitor symbols = new DefaultSymbolProviderVertexVisitor(g); | ||
| ApexPathWalker.walkPath(g, path, ruleVisitor, symbols); |
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.
Performance question: Will this cause redundant path walking for the case where there's multiple GGDs? It seems like we'd walk the path once for the first sink, then walk it again for the second sink (and that second time would cause a violation when it reaches the sink from earlier). Am I missing something?
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.
You're right. This is a problem that ApexFlsViolationRule has as well. The path walking should be relatively more performant than the initial path expansion. But certainly something to improve.
|
|
||
| @Override | ||
| protected void execAfterLoopVertexVisit(BaseSFVertex vertex, SymbolProvider symbols) { | ||
| if (shouldContinue()) { |
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 quite sure I understand what's going on here. This looks like it would throw a violation for:
for (int i = 0; i < 5; i++) {
//some code
}}
getGlobalDescribe()
How does it avoid doing that? I don't understand how it knows when it exits the loop.
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.
Ahh! I'm just dumb. You're spot on. Let me rework this.
No description provided.