-
-
Notifications
You must be signed in to change notification settings - Fork 316
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
Fix: Dont create transaction for unused ViewControllers #4437
Conversation
Performance metrics 🚀
|
Revision | Plain | With Sentry | Diff |
---|---|---|---|
b2c9166 | 1246.86 ms | 1255.28 ms | 8.42 ms |
02e1163 | 1199.86 ms | 1211.78 ms | 11.92 ms |
ee8b48f | 1196.80 ms | 1213.48 ms | 16.68 ms |
533c68f | 1236.54 ms | 1256.68 ms | 20.14 ms |
10ee2ce | 1250.90 ms | 1258.57 ms | 7.67 ms |
1f9387b | 1229.00 ms | 1256.49 ms | 27.49 ms |
bef2003 | 1248.18 ms | 1258.86 ms | 10.68 ms |
6943de0 | 1237.67 ms | 1247.12 ms | 9.45 ms |
326b7eb | 1204.76 ms | 1234.96 ms | 30.20 ms |
50b058e | 1212.29 ms | 1231.16 ms | 18.88 ms |
App size
Revision | Plain | With Sentry | Diff |
---|---|---|---|
b2c9166 | 21.58 KiB | 630.26 KiB | 608.68 KiB |
02e1163 | 21.58 KiB | 418.82 KiB | 397.24 KiB |
ee8b48f | 21.58 KiB | 418.70 KiB | 397.11 KiB |
533c68f | 21.58 KiB | 630.28 KiB | 608.70 KiB |
10ee2ce | 20.76 KiB | 427.77 KiB | 407.00 KiB |
1f9387b | 21.58 KiB | 654.26 KiB | 632.68 KiB |
bef2003 | 22.85 KiB | 407.73 KiB | 384.88 KiB |
6943de0 | 20.76 KiB | 393.33 KiB | 372.57 KiB |
326b7eb | 20.76 KiB | 432.31 KiB | 411.55 KiB |
50b058e | 21.58 KiB | 714.30 KiB | 692.72 KiB |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #4437 +/- ##
=============================================
+ Coverage 91.333% 91.344% +0.010%
=============================================
Files 610 610
Lines 49927 49954 +27
Branches 18033 18056 +23
=============================================
+ Hits 45600 45630 +30
+ Misses 4235 4232 -3
Partials 92 92
... and 4 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
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 unsure if this approach will work for nested UIViewControllers. I'm not a big fan of the shouldIgnore
flag approach. The logic for covering the edge case of unused view controllers is spread across multiple classes. Flipping some flags on the spans looks like something that can break easily.
What about a transaction validation/span filtering logic? We could have a method looking all the spans with some metadata and validating that it is a correct transaction. In our case, the logic checks if it's an auto-generated transaction with a ui.load operation. It then validates that the transaction has a loadView
or a viewDidLoad
spans, and also spans for viewWillDisappear
or viewDidAppear
. The logic would discard the transaction or filter spans for nested view controllers that never get loaded.
The max transaction duration logic should also be in that validation logic
sentry-cocoa/Sources/Sentry/SentryTracer.m
Lines 560 to 570 in 79eb67d
// Prewarming can execute code up to viewDidLoad of a UIViewController, and keep the app in the | |
// background. This can lead to auto-generated transactions lasting for minutes or even hours. | |
// Therefore, we drop transactions lasting longer than SENTRY_AUTO_TRANSACTION_MAX_DURATION. | |
NSTimeInterval transactionDuration = [self.timestamp timeIntervalSinceDate:self.startTimestamp]; | |
if ([self isAutoGeneratedTransaction] | |
&& transactionDuration >= SENTRY_AUTO_TRANSACTION_MAX_DURATION) { | |
SENTRY_LOG_INFO(@"Auto generated transaction exceeded the max duration of %f seconds. Not " | |
@"capturing transaction.", | |
SENTRY_AUTO_TRANSACTION_MAX_DURATION); | |
return; | |
} |
if (child.shouldIgnore == NO) { | ||
[spans addObject:child]; | ||
} |
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.
h
: If I'm not mistaken, this approach won't work for nested UIViewControllers, as this would only remove the spans for loadView
and viewDidLoad
and not the other spans, such as TTID/TTFD.
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.
TTID and TTFD are not created for nested view controllers.
Im not sure if I understood your 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.
Sorry, TTID/TTFD was a bad example then. What about other spans, such as file IO, DB queries, manually added ones, or other future spans that we aren't yet aware of?
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.
Ok, I can see where this could happen.
What do you think we should do to them?
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.
The validation idea mentioned in the top-level comment sounds promising 👍🏻
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.
@brustolin, I would suggest a validation logic as described here #4437 (review). WDYT?
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.
We probably need to talk about this in person, maybe I didn't get it but your suggestion in the PR review comment does not solve the problem raised in here.
Also, I would not like to have a "scenario specific" logic inside the generic SentryTracer class, it feels more hacky than the one flag solution that indicates whether the span was validated by its creator or not.
@@ -132,6 +132,7 @@ class SentryUIViewControllerPerformanceTrackerTests: XCTestCase { | |||
callbackExpectation.fulfill() | |||
} | |||
let tracer = try XCTUnwrap(transactionSpan as? SentryTracer) | |||
XCTAssertTrue(tracer.shouldIgnore) |
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.
m
: It seems to me that these test additions don't fully cover the edge case described in GH-4427. I would love to see a test that emulates these edge cases.
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 addition are meant to check whether SentryUIViewControllerPerformanceTrackerTests.swift
is properly setting this values.
The test to check whether we create or not the transaction can be found in SentryTracerTests.swift
I think you’re looking at this from the wrong perspective. Don’t think about |
The |
Since you're using a different approach I prefer to start from scratch. |
📜 Description
Its possible to create a view controller but never add it to the view hierarchy.
This will create a transaction with data that is not helpful
💚 How did you test it?
Unit tests
📝 Checklist
You have to check all boxes before merging:
sendDefaultPII
is enabled.🔮 Next steps