-
Notifications
You must be signed in to change notification settings - Fork 523
Kotlin Coroutines
The team leverages Kotlin coroutines for background processing, however we never launch a new dispatcher or use any of the built-in dispatchers. Instead, we use one of our existing dispatchers:
- BackgroundDispatcher: for executing expensive operations
- BlockingDispatcher: for executing operations that need to be done in parallel (generally, don't use this--prefer InMemoryBlockingCache, instead)
New operations should create a separate scope using one of the existing dispatchers & perform their execution using that. Note that failures in operations will cause the scope itself to enter a failed state, so scopes shouldn't be kept long-term for correctness.
One major benefit in consolidating all execution on the same coroutine dispatchers is that facilitates easy thread synchronization boundaries in tests. TestCoroutineDispatchers is a test-injectable utility with a number of useful API functions:
-
(un)registerIdlingResource
: ensures background operations finish automatically before performing Espresso UI interactions -
runCurrent
: run all background tasks that can be completed now without advancing the clock (Robolectric tests run with a fake clock that has to be manually advanced) -
advanceTimeBy
/advanceUntilIdle
: functions for running tasks scheduled in the future
Generally, registering an idling resource for shared Espresso/Robolectric tests and calling runCurrent
after performing any operations in the bodies of tests is sufficient to guarantee no test flakes for nearly all scenarios. There are many examples of using both throughout the codebase.
advanceTimeBy
/advanceUntilIdle
should only be used in cases where they are specifically needed (prefer runCurrent
where possible since advanceUntilIdle
is more of a "sledgehammer" solution and should rarely be necessary).
Have an idea for how to improve the wiki? Please help make our documentation better by following our instructions for contributing to the wiki.
Core documentation
Developing Oppia
- Contributing to Oppia Android
- Bazel
- Key Workflows
- Testing
- Developing Skills
- Frequent Errors and Solutions
- RTL Guidelines
- Working on UI
- Writing Design Docs
Developer Reference
- Code style
- Background Processing
- Dark mode
- Buf Guide
- Firebase Console Guide
- Platform Parameters & Feature Flags
- Work Manager
- Dependency Injection with Dagger
- Revert & regression policy
- Upgrading target SDK version
- Spotlight Guide
- Triaging Process
- Bazel
- Internationalization
- Terminology in Oppia
- Past Events