initWithContext synchronization fix#1903
Conversation
|
Could you fix the linting errors in OneSignalImplTests? |
|
Done, also renamed OneSignalImplTests to OneSignalImpTests to align with OneSignalImp |
jennantilla
left a comment
There was a problem hiding this comment.
Makes sense to add additional synchronization here, great work!
| @@ -172,126 +173,160 @@ internal class OneSignalImp : IOneSignal, IServiceProvider { | |||
|
|
|||
| // do not do this again if already initialized | |||
| if (isInitialized) { | |||
There was a problem hiding this comment.
A if (isInitialized) check was added in this PR in the new synchronized block, so we can remove this one.
|
Previously, jkasten2 (Josh Kasten) wrote…
The check is done twice intentionally. Most post-initialization callers will hit this if block and can do so without lock contention. We need to check |
jkasten2
left a comment
There was a problem hiding this comment.
Reviewed 2 of 2 files at r2, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @brismithers, @emawby, @nan-li, and @shepherd-l)
OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt line 175 at r2 (raw file):
Previously, brismithers (Brian Smith) wrote…
The check is done twice intentionally. Most post-initialization callers will hit this if block and can do so without lock contention. We need to check
isInitializedagain after obtaining the lock to ensure there wasn't someone else (that had the lock, but didn't finish initialization).
Gotcha, I have seen this before, it trades performance (in-most cases) over less code. Since init isn't normally called more than not sure if I like that trade off. However it's more of a nit so I'll unblock the PR and leave that up to you.
Fix linting errors with OneSignalImp and OneSignalImpTests
986adfa to
6b958ec
Compare
|
Previously, jkasten2 (Josh Kasten) wrote…
that makes sense. I've removed the extra check before obtaining the lock. If we notice high contention cases this can always be added in the future! |
Description
One Line Summary
Synchronize initWithContext so initialization occurs once, and prevent login/logout from being called before
initWithContext.Details
It is possible for an app to call
initWithContexton different threads at the same time, causing the initialization logic to run more than once. If this were to happen, the internal state of the SDK will not be correct. For example, the initialization code drives callingregisterActivityLifecycleCallbacks, we don't want to have 2 of those!This change synchronizes the initialization logic so the SDK can only go through
initWithContextonce. Additionally, theloginandlogoutfunctions now throw exceptions rather than log an error, if called beforeinitWithContext. This is done to raise programming errors to the caller, rather than swallow them in the logs.Motivation
No specific issues to point to, although the belief is this is a concurrency issue that needs to be resolved.
Scope
This change is limited to initialization and login/logout flows.
Testing
Unit testing
2 additional unit tests were added to demonstrate the expected behavior of calling login/logout before calling
initWithContext.Manual testing
Run the OneSignal Example App on an emulator to ensure initialization of the SDK continues to operate successfully.
Affected code checklist
Checklist
Overview
Testing
Final pass
This change is