-
Notifications
You must be signed in to change notification settings - Fork 123
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
Make Glean init in Kotlin fully async #672
Conversation
// the @MainThread decorator and the `assertOnUiThread` call. | ||
MainScope().launch { | ||
ProcessLifecycleOwner.get().lifecycle.addObserver(gleanLifecycleObserver) | ||
} |
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.
Do we need to do this here, or could we do it outside of the coroutine (near the top where things like applicationContext
are set?)
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'm not sure yet, I don't think there's anything preventing us from moving it there, before the glean init even starts.
The only two reasons for not doing that would be:
- we don't want to register this if the glean init fails;
- we really want to test this in Fenix before making a call!
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.
Fair enough on both points. I think I was just coming at it from the angle of -- going off the main thread only to come back to it is more complicated. But, as you say, we don't really know until we try it in the context of Fenix.
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'll make sure to try that first once I get rid of the failing test and have a proper Fenix build for testing!
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 tested that, but I think we should retain the current behaviour even just to make sure that we don't mistakenly register observers if init fails. Thoughts?
Note that this would also protect us against sudden/immediate going to background while initializing.
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.
That's a good point about not registering if we exit early for some other error during init. 👍 on this, then!
588d246
to
9d7eadf
Compare
Our test code relies on `withTimeout*` and `while(true)` in a few places to wait for things to happen. However, having a timeout is not enough: if the coroutine is busy, even if the timeout elapses, the work will not be interrupted. That's because cancellation in Kotlin coroutines is cooperative, see [the docs](https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/cancellation-and-timeouts.md#cancellation-is-cooperative) for more details. This commit uses cooperative cancellation so that tests will break, instead of hanging forever.
Without the context, the Glean init would throw an exception which would "hang" the dispatchers in the next async tests.
fddbb8c
to
6f1fd24
Compare
I tested this both using Fenix and the Glean SDK sample app: this seem to work as expected. Accumulated data is correctly accounted for and any pre-init dispatched piece of information is sent.
This PR additionally fixes some weird bugs we had in our testing code that made our tests hang forever under certain circumstances. Se the indivudual commit messages.
TODO
flushQueuedInitialTasks
implies