Skip to content

Commit

Permalink
ref: Don't only update App State in the OOM tracker (#2276)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinrenskers authored Oct 13, 2022
1 parent 8b040e4 commit 0e2e593
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 116 deletions.
41 changes: 41 additions & 0 deletions Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
0A94157D28F6B893006A5DD1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 63AA759B1EB8AEF500D153DE;
remoteInfo = Sentry;
};
0A94157F28F6B893006A5DD1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 63AA76651EB8CB2F00D153DE;
remoteInfo = SentryTests;
};
7B64385C26A6C0A6000D0F65 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7BB6224126A56C4E00D0E75E /* Project object */;
Expand Down Expand Up @@ -101,6 +115,15 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
0A94157928F6B893006A5DD1 /* Products */ = {
isa = PBXGroup;
children = (
0A94157E28F6B893006A5DD1 /* Sentry.framework */,
0A94158028F6B893006A5DD1 /* SentryTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
7B64385826A6C0A6000D0F65 /* iOS-SwiftUI-UITests */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -242,6 +265,10 @@
productRefGroup = 7BB6224A26A56C4E00D0E75E /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 0A94157928F6B893006A5DD1 /* Products */;
ProjectRef = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
},
{
ProductGroup = 84D4FEAB28ECD52E00EDAAFE /* Products */;
ProjectRef = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */;
Expand All @@ -256,6 +283,20 @@
/* End PBXProject section */

/* Begin PBXReferenceProxy section */
0A94157E28F6B893006A5DD1 /* Sentry.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = Sentry.framework;
remoteRef = 0A94157D28F6B893006A5DD1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
0A94158028F6B893006A5DD1 /* SentryTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = SentryTests.xctest;
remoteRef = 0A94157F28F6B893006A5DD1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
84D4FEB228ECD52E00EDAAFE /* Sentry.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
Expand Down
4 changes: 4 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
0A56DA5F28ABA01B00C400D5 /* SentryTransactionContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A56DA5E28ABA01B00C400D5 /* SentryTransactionContext+Private.h */; };
0A6EEADD28A657970076B469 /* UIViewRecursiveDescriptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6EEADC28A657970076B469 /* UIViewRecursiveDescriptionTests.swift */; };
0A8F0A392886CC70000B15F6 /* SentryPermissionsObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AABE2EE288592750057ED69 /* SentryPermissionsObserver.h */; };
0A94158228F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */; };
0A9BF4E228A114940068D266 /* SentryViewHierarchyIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A9BF4E128A114940068D266 /* SentryViewHierarchyIntegration.m */; };
0A9BF4E428A114B50068D266 /* SentryViewHierarchyIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A9BF4E328A114B50068D266 /* SentryViewHierarchyIntegration.h */; };
0A9BF4E928A125390068D266 /* TestSentryViewHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9BF4E628A123270068D266 /* TestSentryViewHierarchy.swift */; };
Expand Down Expand Up @@ -757,6 +758,7 @@
0A5370A028A3EC2400B2DCDE /* SentryViewHierarchyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryViewHierarchyTests.swift; sourceTree = "<group>"; };
0A56DA5E28ABA01B00C400D5 /* SentryTransactionContext+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryTransactionContext+Private.h"; path = "include/SentryTransactionContext+Private.h"; sourceTree = "<group>"; };
0A6EEADC28A657970076B469 /* UIViewRecursiveDescriptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewRecursiveDescriptionTests.swift; sourceTree = "<group>"; };
0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppStateManagerTests.swift; sourceTree = "<group>"; };
0A9BF4E128A114940068D266 /* SentryViewHierarchyIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryViewHierarchyIntegration.m; sourceTree = "<group>"; };
0A9BF4E328A114B50068D266 /* SentryViewHierarchyIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryViewHierarchyIntegration.h; path = include/SentryViewHierarchyIntegration.h; sourceTree = "<group>"; };
0A9BF4E628A123270068D266 /* TestSentryViewHierarchy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryViewHierarchy.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2400,6 +2402,7 @@
7B85BD8D24C5C3A6000A4225 /* SentryFileManagerTestExtension.swift */,
7B4C817124D1BC2B0076ACE4 /* SentryFileManager+TestProperties.h */,
7B98D7EB25FB7C4900C5A389 /* SentryAppStateTests.swift */,
0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */,
69BEE6F62620729E006DF9DF /* UrlSessionDelegateSpy.swift */,
7BD86ECA264A6DB5005439DB /* TestSysctl.swift */,
7B16FD012654F86B008177D3 /* SentrySysctlTests.swift */,
Expand Down Expand Up @@ -3612,6 +3615,7 @@
7B88F30224BC5C6D00ADF90A /* SentrySdkInfoTests.swift in Sources */,
7BC8523B2458849E005A70F0 /* SentryDataCategoryMapperTests.swift in Sources */,
63FE721220DA66EC00CDBAE8 /* SentryCrashMach_Tests.m in Sources */,
0A94158228F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift in Sources */,
7B6D98E924C6D336005502FA /* SentrySdkInfo+Equality.m in Sources */,
7BDB03BF25136A7D00BAE198 /* TestSentryDispatchQueueWrapper.swift in Sources */,
7B6438A726A70DDB000D0F65 /* UIViewControllerSentryTests.swift in Sources */,
Expand Down
8 changes: 8 additions & 0 deletions Sources/Sentry/SentryAppStartTracker.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ - (void)start
if (PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode) {
[self buildAppStartMeasurement];
}

# if SENTRY_HAS_UIKIT
[self.appStateManager start];
# endif
}

- (void)buildAppStartMeasurement
Expand Down Expand Up @@ -259,6 +263,10 @@ - (void)stop
[NSNotificationCenter.defaultCenter removeObserver:self
name:UIApplicationDidEnterBackgroundNotification
object:nil];

# if SENTRY_HAS_UIKIT
[self.appStateManager stop];
# endif
}

- (void)dealloc
Expand Down
143 changes: 132 additions & 11 deletions Sources/Sentry/SentryAppStateManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
#import <SentryAppStateManager.h>
#import <SentryCrashWrapper.h>
#import <SentryCurrentDateProvider.h>
#import <SentryDispatchQueueWrapper.h>
#import <SentryFileManager.h>
#import <SentryOptions.h>

#if SENTRY_HAS_UIKIT
# import <SentryInternalNotificationNames.h>
# import <SentryNSNotificationCenterWrapper.h>
# import <UIKit/UIKit.h>
#endif

Expand All @@ -20,6 +23,8 @@
@property (nonatomic, strong) SentryFileManager *fileManager;
@property (nonatomic, strong) id<SentryCurrentDateProvider> currentDate;
@property (nonatomic, strong) SentrySysctl *sysctl;
@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue;
@property (nonatomic) NSInteger startCount;

@end

Expand All @@ -30,19 +35,146 @@ - (instancetype)initWithOptions:(SentryOptions *)options
fileManager:(SentryFileManager *)fileManager
currentDateProvider:(id<SentryCurrentDateProvider>)currentDateProvider
sysctl:(SentrySysctl *)sysctl
dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper
{
if (self = [super init]) {
self.options = options;
self.crashWrapper = crashWrapper;
self.fileManager = fileManager;
self.currentDate = currentDateProvider;
self.sysctl = sysctl;
self.dispatchQueue = dispatchQueueWrapper;
self.startCount = 0;
}
return self;
}

#if SENTRY_HAS_UIKIT

- (void)start
{
if (self.startCount == 0) {
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(didBecomeActive)
name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(didBecomeActive)
name:SentryHybridSdkDidBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(willResignActive)
name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(willTerminate)
name:SentryNSNotificationCenterWrapper.willTerminateNotificationName
object:nil];

[self storeCurrentAppState];
}

self.startCount += 1;
}

- (void)stop
{
if (self.startCount <= 0) {
return;
}

self.startCount -= 1;

if (self.startCount == 0) {
// Remove the observers with the most specific detail possible, see
// https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver
[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryHybridSdkDidBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryNSNotificationCenterWrapper.willTerminateNotificationName
object:nil];

[self deleteAppState];
}
}

- (void)dealloc
{
// In dealloc it's safe to unsubscribe for all, see
// https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver
[NSNotificationCenter.defaultCenter removeObserver:self];
[self deleteAppState];
}

/**
* It is called when an app is receiving events / it is in the foreground and when we receive a
* SentryHybridSdkDidBecomeActiveNotification.
*
* This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification
* regardless of whether your app uses scenes, see
* https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive.
*/
- (void)didBecomeActive
{
[self updateAppStateInBackground:^(SentryAppState *appState) { appState.isActive = YES; }];
}

/**
* The app is about to lose focus / going to the background. This is only called when an app was
* receiving events / was is in the foreground.
*/
- (void)willResignActive
{
[self updateAppStateInBackground:^(SentryAppState *appState) { appState.isActive = NO; }];
}

- (void)willTerminate
{
// The app is terminating so it is fine to do this on the main thread.
// Furthermore, so users can manually post UIApplicationWillTerminateNotification and then call
// exit(0), to avoid getting false OOM when using exit(0), see GH-1252.
[self updateAppState:^(SentryAppState *appState) { appState.wasTerminated = YES; }];
}

- (void)updateAppStateInBackground:(void (^)(SentryAppState *))block
{
// We accept the tradeoff that the app state might not be 100% up to date over blocking the main
// thread.
[self.dispatchQueue dispatchAsyncWithBlock:^{ [self updateAppState:block]; }];
}

- (void)updateAppState:(void (^)(SentryAppState *))block
{
@synchronized(self) {
SentryAppState *appState = [self.fileManager readAppState];
if (nil != appState) {
block(appState);
[self.fileManager storeAppState:appState];
}
}
}

- (SentryAppState *)buildCurrentAppState
{
// Is the current process being traced or not? If it is a debugger is attached.
Expand Down Expand Up @@ -72,17 +204,6 @@ - (void)deleteAppState
[self.fileManager deleteAppState];
}

- (void)updateAppState:(void (^)(SentryAppState *))block
{
@synchronized(self) {
SentryAppState *appState = [self.fileManager readAppState];
if (nil != appState) {
block(appState);
[self.fileManager storeAppState:appState];
}
}
}

#endif

@end
11 changes: 6 additions & 5 deletions Sources/Sentry/SentryDependencyContainer.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ - (SentryAppStateManager *)appStateManager
if (_appStateManager == nil) {
SentryOptions *options = [[[SentrySDK currentHub] getClient] options];
_appStateManager = [[SentryAppStateManager alloc]
initWithOptions:options
crashWrapper:self.crashWrapper
fileManager:self.fileManager
currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]
sysctl:[[SentrySysctl alloc] init]];
initWithOptions:options
crashWrapper:self.crashWrapper
fileManager:self.fileManager
currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]
sysctl:[[SentrySysctl alloc] init]
dispatchQueueWrapper:self.dispatchQueueWrapper];
}
return _appStateManager;
}
Expand Down
Loading

0 comments on commit 0e2e593

Please sign in to comment.