Fix running many session duration timers at once#272
Fix running many session duration timers at once#272Cykelero wants to merge 2 commits intoTelemetryDeck:mainfrom
Conversation
|
This PR also reduces the frequency of the update timer, to further reduce power usage. In most situations, this doesn't affect at all the accuracy of the duration measurement, as far as I understand, because elapsed time is tallied up whenever the app is defocused. Also, ideally, the code would be updated to more defensively prevent duplicate timers, by always checking for a running timer before overriding the |
If TelemetryDeck.initialize() is called while the app is in the background, then the SessionManager creates a new session update timer in startNewSession(), that is ultimately never invalidated. These runaway timers can add up, and consume significant resources. This commit prevents this from happening, by always checking for foreground state before creating the timer.
Elapsed time is counted anyway, whenever updateSessionDuration() is called. This includes when switching away from the app.
0de7717 to
ab774f3
Compare
|
Hi @Cykelero! Thanks a lot for this PR and the bug report. You're definitely right that this can be made more defensive. To give some context: In the meantime, you can affect changes to configuration via one of the provided helpers. For example, to reset the session id, you can call |
|
Thank you for the details, and the fix suggestion! Switching to |
Bug
If user code changes the SDK configuration while the app is in the background, then the SDK can create a
SessionManager.updateSessionDuration()timer that it never invalidates. After a while, these runaway timers add up, and can trigger many times a second, consuming problematic amounts of CPU power.When I first noticed this behavior, it was causing Retcon.app to use 15-25% CPU while in the background, as it was trying to persist 2,834 sessions, extremely frequently.
Fix
This commit adds a check for foreground state before creating the timer.
Cause
Changing SDK configuration (by calling
TelemetryDeck.initialize()), or even just by setting a new value onTelemetryManagerConfiguration.sessionID, causes TelemetryDeck to create a new session update timer, regardless of foreground state. This is a problem, because the SDK only invalidates the session update timer when going back to a background state. As such, the reference to the timer created in the background is silently replaced when creating a new timer, instead of first invalidating the former timer.Calling
TelemetryDeck.initialize()actually causes the timer to be created after a fixed 0.5s delay, making the bug very likely to occur if a macOS app updates its TelemetryDeck configuration upon being focused.The following code reliably triggers the issue, if the user switches to the app, then quickly switches away: