Skip to content

Commit 915a740

Browse files
committed
feat: Hang tracker updates
1 parent d8ceea3 commit 915a740

File tree

12 files changed

+532
-37
lines changed

12 files changed

+532
-37
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Improvements
6+
7+
- The watchdog termination integration uses a runloop observer instead of fixed interval main thread work to avoid creating a busy runloop (#6237)
8+
39
## 8.56.1
410

511
### Fixes

Sentry.xcodeproj/project.pbxproj

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,11 +1110,15 @@
11101110
FACEED132E3179A10007B4AC /* SentyOptionsInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = FACEED122E3179A10007B4AC /* SentyOptionsInternal.m */; };
11111111
FAE2DAB82E1F317900262307 /* SentryProfilingSwiftHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = FAE2DAB72E1F317900262307 /* SentryProfilingSwiftHelpers.m */; };
11121112
FAE2DABA2E1F318900262307 /* SentryProfilingSwiftHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE2DAB92E1F318900262307 /* SentryProfilingSwiftHelpers.h */; };
1113+
FAE579842E7CF21800B710F9 /* SentryMigrateSessionInit.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE5797E2E7CF21300B710F9 /* SentryMigrateSessionInit.swift */; };
11131114
FAE5798D2E7D9D4C00B710F9 /* SentrySysctl.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE579872E7D9D4900B710F9 /* SentrySysctl.swift */; };
11141115
FAE579BA2E7DBE9900B710F9 /* SentryGlobalEventProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE579B42E7DBE9400B710F9 /* SentryGlobalEventProcessor.swift */; };
11151116
FAE579C22E7DDDE700B710F9 /* SentryThreadWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE579BC2E7DDDE400B710F9 /* SentryThreadWrapper.swift */; };
1116-
FAE579842E7CF21800B710F9 /* SentryMigrateSessionInit.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE5797E2E7CF21300B710F9 /* SentryMigrateSessionInit.swift */; };
11171117
FAE579CC2E7DE14900B710F9 /* SentryFrameRemover.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE579C62E7DE14400B710F9 /* SentryFrameRemover.swift */; };
1118+
FAE579D52E7F238100B710F9 /* HangTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE579CF2E7F237A00B710F9 /* HangTracker.swift */; };
1119+
FAE57A3C2E81C55900B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE57A362E81C54F00B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwift.swift */; };
1120+
FAE57C142E831A7700B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE57C0E2E831A7700B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwiftTests.swift */; };
1121+
FAE57C232E832A9400B710F9 /* HangTrackerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAE57C1D2E832A8F00B710F9 /* HangTrackerTests.swift */; };
11181122
FAE80C242E4695B40010A595 /* SentryEvent+Serialize.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE80C232E4695AE0010A595 /* SentryEvent+Serialize.h */; };
11191123
FAEC270E2DF3526000878871 /* SentryUserFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAEC270D2DF3526000878871 /* SentryUserFeedback.swift */; };
11201124
FAEC273D2DF3933A00878871 /* NSData+Unzip.m in Sources */ = {isa = PBXBuildFile; fileRef = FAEC273C2DF3933200878871 /* NSData+Unzip.m */; };
@@ -2459,6 +2463,10 @@
24592463
FAE579B42E7DBE9400B710F9 /* SentryGlobalEventProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryGlobalEventProcessor.swift; sourceTree = "<group>"; };
24602464
FAE579BC2E7DDDE400B710F9 /* SentryThreadWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryThreadWrapper.swift; sourceTree = "<group>"; };
24612465
FAE579C62E7DE14400B710F9 /* SentryFrameRemover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryFrameRemover.swift; sourceTree = "<group>"; };
2466+
FAE579CF2E7F237A00B710F9 /* HangTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HangTracker.swift; sourceTree = "<group>"; };
2467+
FAE57A362E81C54F00B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryWatchdogTerminationTrackingIntegrationSwift.swift; sourceTree = "<group>"; };
2468+
FAE57C0E2E831A7700B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryWatchdogTerminationTrackingIntegrationSwiftTests.swift; sourceTree = "<group>"; };
2469+
FAE57C1D2E832A8F00B710F9 /* HangTrackerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HangTrackerTests.swift; sourceTree = "<group>"; };
24622470
FAE80C232E4695AE0010A595 /* SentryEvent+Serialize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryEvent+Serialize.h"; path = "include/SentryEvent+Serialize.h"; sourceTree = "<group>"; };
24632471
FAEC270D2DF3526000878871 /* SentryUserFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUserFeedback.swift; sourceTree = "<group>"; };
24642472
FAEC273C2DF3933200878871 /* NSData+Unzip.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSData+Unzip.m"; sourceTree = "<group>"; };
@@ -3355,6 +3363,7 @@
33553363
7B2A70D627D5F06C008B0D15 /* ANR */ = {
33563364
isa = PBXGroup;
33573365
children = (
3366+
FAE57C1D2E832A8F00B710F9 /* HangTrackerTests.swift */,
33583367
7B2A70D727D5F07F008B0D15 /* SentryANRTrackerV1Tests.swift */,
33593368
621D22002DBB7E09006F9C48 /* SentryANRTrackerV1IntegrationTests.swift */,
33603369
621AE74E2C626CF70012E730 /* SentryANRTrackerV2Tests.swift */,
@@ -3763,6 +3772,7 @@
37633772
children = (
37643773
D452FE6B2DDC873400AFF56F /* Processors */,
37653774
7BFE7A0927A1B6B000D2B66E /* SentryWatchdogTerminationTrackingIntegrationTests.swift */,
3775+
FAE57C0E2E831A7700B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwiftTests.swift */,
37663776
0A2D7BB929152CBF008727AF /* SentryWatchdogTerminationScopeObserverTests.swift */,
37673777
7B98D7DF25FB73B900C5A389 /* SentryWatchdogTerminationTrackerTests.swift */,
37683778
D452FE742DDC8DC400AFF56F /* TestSentryWatchdogTerminationBreadcrumbProcessor.swift */,
@@ -4227,6 +4237,7 @@
42274237
D452FCBC2DDB6FA800AFF56F /* WatchdogTerminations */ = {
42284238
isa = PBXGroup;
42294239
children = (
4240+
FAE57A362E81C54F00B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwift.swift */,
42304241
D452FCBD2DDB6FC200AFF56F /* Processors */,
42314242
);
42324243
path = WatchdogTerminations;
@@ -4324,6 +4335,7 @@
43244335
D800942328F82E8D005D3943 /* Swift */ = {
43254336
isa = PBXGroup;
43264337
children = (
4338+
FAE579CF2E7F237A00B710F9 /* HangTracker.swift */,
43274339
F4FE9E062E6248BB0014FED5 /* SentryCrash */,
43284340
FABB48B22E59310D0071397E /* Transaction */,
43294341
FAAB29F02E3D252000ACD577 /* SentrySession.swift */,
@@ -5865,6 +5877,7 @@
58655877
FA01BCB22E69352A00968DFA /* SentryDiscardedEvent.swift in Sources */,
58665878
7BAF3DCE243DCBFE008A5414 /* SentryTransportFactory.m in Sources */,
58675879
F4E3DCCB2E1579240093CB80 /* SentryScopePersistentStore.swift in Sources */,
5880+
FAE57A3C2E81C55900B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwift.swift in Sources */,
58685881
7D65260E237F649E00113EA2 /* SentryScope.m in Sources */,
58695882
D4EDF9842D0B2A210071E7B3 /* Data+SentryTracing.swift in Sources */,
58705883
84281C472A57905700EE88F2 /* SentrySample.m in Sources */,
@@ -5888,6 +5901,7 @@
58885901
0A2D8DA9289BC905008720F6 /* SentryViewHierarchyProviderHelper.m in Sources */,
58895902
D84D2CDD2C2BF7370011AF8A /* SentryReplayEvent.swift in Sources */,
58905903
D8BC28CC2BFF78220054DA4D /* SentryRRWebTouchEvent.swift in Sources */,
5904+
FAE579D52E7F238100B710F9 /* HangTracker.swift in Sources */,
58915905
D452FC592DDB4B1700AFF56F /* SentryWatchdogTerminationBreadcrumbProcessor.m in Sources */,
58925906
FAE2DAB82E1F317900262307 /* SentryProfilingSwiftHelpers.m in Sources */,
58935907
8EA1ED0B2668F8C400E62B98 /* SentryUIViewControllerSwizzling.m in Sources */,
@@ -6034,6 +6048,7 @@
60346048
62278CA82E30B21A0022ABC6 /* SentryHttpTransportFlushIntegrationTests.swift in Sources */,
60356049
0A5370A128A3EC2400B2DCDE /* SentryViewHierarchyProviderTests.swift in Sources */,
60366050
D8FFE50C2703DBB400607131 /* SwizzlingCallTests.swift in Sources */,
6051+
FAE57C142E831A7700B710F9 /* SentryWatchdogTerminationTrackingIntegrationSwiftTests.swift in Sources */,
60376052
7BFAA6E7297AA16A00E7E02E /* SentryCrashMonitor_CppException_Tests.mm in Sources */,
60386053
9286059929A50BAB00F96038 /* SentryGeoTests.swift in Sources */,
60396054
621655662DB12A8900810504 /* SentryCrashMach-OTests.m in Sources */,
@@ -6241,6 +6256,7 @@
62416256
D884A20527C80F6300074664 /* SentryCoreDataTrackerTest.swift in Sources */,
62426257
8E70B10125CB8695002B3155 /* SentrySpanIdTests.swift in Sources */,
62436258
62E2119A2DAE99FC007D7262 /* SentryAsyncSafeLog.m in Sources */,
6259+
FAE57C232E832A9400B710F9 /* HangTrackerTests.swift in Sources */,
62446260
84EB21962BF01CEA00EDDA28 /* SentryCrashInstallationTests.swift in Sources */,
62456261
7BFE7A0A27A1B6B000D2B66E /* SentryWatchdogTerminationTrackingIntegrationTests.swift in Sources */,
62466262
FA6614FC2E4B8E1A00657755 /* TestSentryUIApplication.swift in Sources */,

Sources/Sentry/SentryBaseIntegration.m

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,8 @@ - (BOOL)shouldBeEnabledWithOptions:(SentryOptions *)options
186186
BOOL performanceDisabled
187187
= !options.enableAutoPerformanceTracing || !options.isTracingEnabled;
188188
BOOL appHangsV2Disabled = options.isAppHangTrackingV2Disabled;
189-
# if SDK_V9
190-
// The V9 watchdog tracker uses the frames tracker, so frame tracking
191-
// must be enabled if watchdog tracking is enabled.
192-
BOOL watchdogDisabled = !options.enableWatchdogTerminationTracking;
193-
# else
194-
// Before V9 this should have no effect so set it to YES
195-
BOOL watchdogDisabled = YES;
196-
# endif // SDK_V9
197189

198-
if (performanceDisabled && appHangsV2Disabled && watchdogDisabled) {
190+
if (performanceDisabled && appHangsV2Disabled) {
199191
if (appHangsV2Disabled) {
200192
SENTRY_LOG_DEBUG(@"Not going to enable %@ because enableAppHangTrackingV2 is "
201193
@"disabled or the appHangTimeoutInterval is 0.",
@@ -208,15 +200,6 @@ - (BOOL)shouldBeEnabledWithOptions:(SentryOptions *)options
208200
self.integrationName);
209201
}
210202

211-
# if SDK_V9
212-
if (watchdogDisabled) {
213-
SENTRY_LOG_DEBUG(
214-
@"Not going to enable %@ because enableWatchdogTerminationTracking "
215-
@"is disabled.",
216-
self.integrationName);
217-
}
218-
# endif // SKD_V9
219-
220203
return NO;
221204
}
222205
#endif // SENTRY_HAS_UIKIT

Sources/Sentry/SentryDependencyContainer.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ - (instancetype)init
139139
if (self = [super init]) {
140140
isInitialializingDependencyContainer = YES;
141141

142+
_hangTracker = [[SentryHangTrackerObjcBridge alloc]
143+
initWithDateProvider:SentryDependencies.dateProvider];
144+
142145
_dispatchQueueWrapper = SentryDependencies.dispatchQueueWrapper;
143146
_random = [[SentryRandom alloc] init];
144147
_threadWrapper = [[SentryThreadWrapper alloc] init];

Sources/Sentry/SentryWatchdogTerminationTrackingIntegration.m

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@
1818
# import <SentryWatchdogTerminationTracker.h>
1919
NS_ASSUME_NONNULL_BEGIN
2020

21-
@interface SentryWatchdogTerminationTrackingIntegration () <SentryANRTrackerDelegate>
21+
@interface SentryWatchdogTerminationTrackingIntegration ()
2222

2323
@property (nonatomic, strong) SentryWatchdogTerminationTracker *tracker;
24-
@property (nonatomic, strong) id<SentryANRTracker> anrTracker;
2524
@property (nullable, nonatomic, copy) NSString *testConfigurationFilePath;
2625
@property (nonatomic, strong) SentryAppStateManager *appStateManager;
26+
@property (nonatomic, strong) SentryWatchdogTerminationTrackingIntegrationSwift *swiftImpl;
27+
@property (nonatomic, strong) SentryDispatchQueueWrapper *queue;
2728

2829
@end
2930

@@ -56,6 +57,12 @@ - (BOOL)installWithOptions:(SentryOptions *)options
5657
[[SentryDispatchQueueWrapper alloc] initWithName:"io.sentry.watchdog-termination-tracker"
5758
attributes:attributes];
5859

60+
self.swiftImpl = [[SentryWatchdogTerminationTrackingIntegrationSwift alloc]
61+
initWithHangTrackerBridge:SentryDependencyContainer.sharedInstance.hangTracker
62+
timeoutInterval:options.appHangTimeoutInterval
63+
hangStarted:^{ [dispatchQueueWrapper dispatchAsyncWithBlock:^{ [self hangStarted]; }]; }
64+
hangStopped:^{ [dispatchQueueWrapper dispatchAsyncWithBlock:^{ [self hangStopped]; }]; }];
65+
5966
SentryFileManager *fileManager = [[[SentrySDKInternal currentHub] getClient] fileManager];
6067
SentryAppStateManager *appStateManager =
6168
[SentryDependencyContainer sharedInstance].appStateManager;
@@ -75,17 +82,7 @@ - (BOOL)installWithOptions:(SentryOptions *)options
7582
scopePersistentStore:scopeStore];
7683

7784
[self.tracker start];
78-
79-
# if SDK_V9
80-
BOOL isV2Enabled = YES;
81-
# else
82-
BOOL isV2Enabled = options.enableAppHangTrackingV2;
83-
# endif // SDK_V9
84-
85-
self.anrTracker =
86-
[SentryDependencyContainer.sharedInstance getANRTracker:options.appHangTimeoutInterval
87-
isV2Enabled:isV2Enabled];
88-
[self.anrTracker addListener:self];
85+
[self.swiftImpl start];
8986

9087
self.appStateManager = appStateManager;
9188

@@ -125,16 +122,16 @@ - (void)uninstall
125122
if (nil != self.tracker) {
126123
[self.tracker stop];
127124
}
128-
[self.anrTracker removeListener:self];
125+
[self.swiftImpl stop];
129126
}
130127

131-
- (void)anrDetectedWithType:(enum SentryANRType)type
128+
- (void)hangStarted
132129
{
133130
[self.appStateManager
134131
updateAppState:^(SentryAppState *appState) { appState.isANROngoing = YES; }];
135132
}
136133

137-
- (void)anrStoppedWithResult:(SentryANRStoppedResult *_Nullable)result
134+
- (void)hangStopped
138135
{
139136
[self.appStateManager
140137
updateAppState:^(SentryAppState *appState) { appState.isANROngoing = NO; }];

Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
@class SentryOptions;
2626
@class SentrySessionTracker;
2727
@class SentryGlobalEventProcessor;
28+
@class SentryHangTrackerObjcBridge;
2829

2930
@protocol SentryANRTracker;
3031
@protocol SentryRandomProtocol;
@@ -95,6 +96,7 @@ SENTRY_NO_INIT
9596
@property (nonatomic, strong) id<SentryRateLimits> rateLimits;
9697
@property (nonatomic, strong) id<SentryApplication> application;
9798
@property (nonatomic, strong) SentryThreadsafeApplication *threadsafeApplication;
99+
@property (nonatomic, strong) SentryHangTrackerObjcBridge *hangTracker;
98100

99101
#if SENTRY_HAS_REACHABILITY
100102
@property (nonatomic, strong) SentryReachability *reachability;

Sources/Sentry/include/SentryPrivate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
// Headers that also import SentryDefines should be at the end of this list
2323
// otherwise it wont compile
24+
#import "SentryAppStateManager.h"
2425
#import "SentryAsyncLog.h"
2526
#import "SentryClient+Logs.h"
2627
#import "SentryCrash.h"

0 commit comments

Comments
 (0)