-
Notifications
You must be signed in to change notification settings - Fork 130
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 session delivery logic to always use the delivery queue #295
Conversation
* Remove timer logic * Remove unused properties * Separate capturing an auto-session from a manual one * Move event handling logic into session tracker. Encapsulates the logic for determining whether to record/send a new session. * Rename tracker event handlers to be consistent with each other * Move delivery logic into API client, remove store semaphore
If autoCaptureSessions is updated after Bugsnag is started, only capture subsequent sessions rather than trying to retrofit an existing one. This reduces the possibility of making assumptions about whether Bugsnag has started already.
Updated individual scenarios to reflect that session tracking is not accounted for in the request count. Updated AppDelegate scenario loading logic to always use the same configuration
567cea8
to
5a77351
Compare
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 left a few comments inline, mostly I think this makes sense.
I think it'd be good to test what the effect of these changes are on React Native/Unity, and also to clarify whether entering the foreground can record a duplicate session.
@synchronized (self) { | ||
_shouldAutoCaptureSessions = shouldAutoCaptureSessions; | ||
|
||
if (shouldAutoCaptureSessions) { // track any existing sessions |
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.
IIRC this logic (or similar) may have been added to enable automatic session tracking on React Native. Have we tested the effects of these changes on downstream notifiers?
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.
bugsnag-react-native will need a slight tweak in the initialization logic. While configuring the JS options, when all of the following are true:
- Bugsnag has already been configured on the native side
- The native configuration has
shouldAutoCaptureSessions
set toNO
- The JS configuration has
autoCaptureSessions
set totrue
Then [BugsnagReactNative start]
should call startSession
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.
@martin308 do you foresee a problem with this on the unity side? My hunch is that it’s even less of a problem since the automatic session logic now lives on the C# side.
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.
Yeh there wouldn't be an issue with it the way it is setup right now. For the native notifiers we turn off automatic session tracking
*/ | ||
@property SessionTrackerCallback callback; | ||
- (void)handleHandledErrorEvent; |
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.
Would it also make sense to have an unhandled equivalent of this method?
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.
Not really; if an unhandled event occurs, the app is crashing. There can’t be more than 1 unhandled event in a single session.
repeats:YES]; | ||
[self sessionTick:self]; | ||
} | ||
[self.sessionTracker handleAppForegroundEvent]; |
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 this capture 2 sessions on application startup rather than 1? startNewSessionIfAutoCaptureEnabled
will also start a session, unless I'm mistaken.
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.
It only captures 1 event, since the foreground session only happens when coming from the background and having backgroundTime
more than 60s before.
} | ||
self.backgroundStartTime = nil; |
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.
If this can be nil and we're expecting sessions to be started from multiple threads, would it make sense to make this property atomic/make any checks compound operations?
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.
While sessions can be started from multiple threads, the notifications for UIApplicationWillEnterForeground
/Background
only happen on the main thread and are the only place invoking these handlers. We can document this though and enforce it with assertions in debug mode though.
- (void)deliverSessionsInStore:(BugsnagSessionFileStore *)store { | ||
[self.sendQueue addOperationWithBlock:^{ | ||
if (!self.config.apiKey) | ||
return; |
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 it worth logging a warning if this is the case? I believe this state shouldn't really be allowed.
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.
Logging is a good idea. It shouldn’t happen but this is a guard to prevent either crashing or sending an invalid payload if it hasn’t been set.
[self.sessionTracker startNewSession:[NSDate date] | ||
withUser:self.user | ||
autoCaptured:NO]; | ||
[self.sessionTracker startNewSession]; | ||
|
||
BugsnagSession *secondSession = self.sessionTracker.currentSession; | ||
XCTAssertNotEqualObjects(firstSession.sessionId, secondSession.sessionId); | ||
} | ||
|
||
- (void)testIncrementCounts { |
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 it possible to test unhandled counts? Or is that already covered elsewhere?
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.
It needs an integration test case. I’ll note to add one.
@@ -15,6 +15,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { | |||
let arguments = ProcessInfo.processInfo.arguments | |||
var delay: TimeInterval = 0 | |||
var eventType = "none" | |||
var eventMode = "regular" |
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.
What's the difference between an event type and an event mode? Do they need to be separate concepts?
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 needs to be separation between “run this scenario’s crashing code” and “configure Bugsnag for this scenario (and not run the crashy code)”. Without this, an individual scenario can’t configure Bugsnag for relaunching the app.
@@ -32,6 +32,11 @@ | |||
*/ | |||
@implementation ReadGarbagePointerScenario | |||
|
|||
- (void)startBugsnag { | |||
self.config.shouldAutoCaptureSessions = NO; |
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 it worth making this the default in the mazerunner fixture's AppDelegate, seeing as most of the scenarios already assume 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.
No, because having it there made it difficult to test the default behavior for session tracking. For example, the auto-capture scenarios should test the behavior when not setting the value at all to ensure the default behavior is to send a session request. It’s also easier to debug an individual case when only setting the minimal values for running the scenario by default. I lost a bit of time to confusion when I couldn’t figure out where a config value was being set between AppDelegate, Scenario, and the Scenario subclass.
9681e17
to
7ed032b
Compare
I think the review feedback has been addressed:
|
Goal
Streamline session delivery, ensuring requests are sent on the API client delivery queue.
Changeset
SessionTracker
Notifier
start()
methodSessionTrackingApiClient
Tests
shouldAutoCaptureSessions
is true.shouldAutoCaptureSessions
Discussion
BugsnagConfiguration
to start a session if no session has ever been started in the setter forshouldAutoCaptureSessions
because of a possible race condition. The inline docs are updated accordingly, but is this behavior needed?Alternative Approaches
SessionTrackingApiClient
change, however the larger changeset makes the flow easier to follow and removes the timer logic. This is still a possibility if reviewing a smaller changeset is preferable.Review
For the submitter, initial self-review:
For the pull request reviewer(s), this changeset has been reviewed for: