Skip to content

Commit be73e59

Browse files
authored
Merge 35f3261 into 4f41bde
2 parents 4f41bde + 35f3261 commit be73e59

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

docs/executors.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Intro
2+
3+
OS threads are a limited resource that needs to be used with care. In order to minimize the number of threads used by Firebase
4+
as a whole and to increase resource sharing Firebase Common provides a set of standard
5+
[executors](https://developer.android.com/reference/java/util/concurrent/Executor)
6+
and [coroutine dispatchers](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/)
7+
for use by all Firebase SDKs.
8+
9+
These executors are available as components and can be requested by product SDKs as component dependencies.
10+
11+
Example:
12+
```java
13+
public class MyRegistrar implements ComponentRegistrar {
14+
public List<Component<?>> getComponents() {
15+
Qualified<Executor> backgroundExecutor = Qualified.qualified(Background.class, Executor.class);
16+
Qualified<ExecutorService> liteExecutorService = Qualified.qualified(Lightweight.class, ExecutorService.class);
17+
18+
return Collections.singletonList(
19+
Component.builder(MyComponent.class)
20+
.add(Dependency.required(backgroundExecutor))
21+
.add(Dependency.required(liteExecutorService))
22+
.factory(c -> new MyComponent(c.get(backgroundExecutor), c.get(liteExecutorService)))
23+
.build());
24+
}
25+
}
26+
```
27+
28+
All executors(with the exception of `@UiThread`) are available as the following interfaces:
29+
30+
* `Executor`
31+
* `ExecutorService`
32+
* `ScheduledExecutorService`
33+
* `CoroutineDispatcher`
34+
35+
`@UiThread` is provided only as a plain `Executor`.
36+
37+
## Validation
38+
39+
All SDKs have a custom linter check that detects creation of thread pools and threads,
40+
this is to ensure SDKs use the above executors instead of creating their own.
41+
42+
# Choose the right executor
43+
44+
Use the following diagram to pick the right executor for the task you have at hand.
45+
46+
```mermaid
47+
flowchart TD
48+
Start[Start] --> DoesBlock{Does it block?}
49+
DoesBlock -->|No| NeedUi{Does it need to run\n on UI thread?}
50+
NeedUi --> |Yes| UiExecutor[[UiThread Executor]]
51+
NeedUi --> |No| TakesLong{Does it take more than\n 10ms to execute?}
52+
TakesLong --> |No| LiteExecutor[[Lightweight Executor]]
53+
TakesLong --> |Yes| BgExecutor[[Background Executor]]
54+
DoesBlock --> |Yes| DiskIO{Does it block only\n on disk IO?}
55+
DiskIO --> |Yes| BgExecutor
56+
DiskIO --> |No| BlockExecutor[[Blocking Executor]]
57+
58+
59+
classDef start fill:#4db6ac,stroke:#4db6ac,color:#000;
60+
class Start start
61+
62+
classDef condition fill:#f8f9fa,stroke:#bdc1c6,color:#000;
63+
class DoesBlock condition;
64+
class NeedUi condition;
65+
class TakesLong condition;
66+
class DiskIO condition;
67+
68+
classDef executor fill:#1a73e8,stroke:#7baaf7,color:#fff;
69+
class UiExecutor executor;
70+
class LiteExecutor executor;
71+
class BgExecutor executor;
72+
class BlockExecutor executor;
73+
```
74+
75+
## UiThread
76+
77+
Used to schedule tasks on application's UI thread, internally it uses a Handler to post runnables onto the main looper.
78+
79+
Example:
80+
81+
```java
82+
Qualified<Executor> uiExecutor = Qualified.qualified(UiThread.class, Executor.class);
83+
```
84+
85+
```kotlin
86+
Qualified<CoroutineDispatcher> dispatcher = Qualified.qualified(UiThread.class, CoroutineDispatcher.class);
87+
```
88+
89+
## Lightweight
90+
91+
Use for tasks that never block and don't take to long to execute. Backed by a thread pool of N threads
92+
where N is the amount of parallelism available on the device(number of CPU cores)
93+
94+
Example:
95+
96+
```java
97+
Qualified<Executor> liteExecutor = Qualified.qualified(Lightweight.class, Executor.class);
98+
```
99+
100+
```kotlin
101+
Qualified<CoroutineDispatcher> dispatcher = Qualified.qualified(Lightweight.class, CoroutineDispatcher.class);
102+
```
103+
104+
## Background
105+
106+
Use for tasks that may block on disk IO(use `@Blocking` for network IO or blocking on other threads).
107+
Backed by 4 threads.
108+
109+
Example:
110+
111+
```java
112+
Qualified<Executor> bgExecutor = Qualified.qualified(Background.class, Executor.class);
113+
```
114+
115+
```kotlin
116+
Qualified<CoroutineDispatcher> dispatcher = Qualified.qualified(Background.class, CoroutineDispatcher.class);
117+
```
118+
119+
## Blocking
120+
121+
Use for tasks that can block for arbitrary amounts of time, this includes network IO.
122+
123+
Example:
124+
125+
```java
126+
Qualified<Executor> blockingExecutor = Qualified.qualified(Blocking.class, Executor.class);
127+
```
128+
129+
```kotlin
130+
Qualified<CoroutineDispatcher> dispatcher = Qualified.qualified(Blocking.class, CoroutineDispatcher.class);
131+
```

0 commit comments

Comments
 (0)