Skip to content

Commit 95dc494

Browse files
falhassenglide-copybara-robot
authored andcommitted
Add an experimental method to GlideExecutor.Builder to optionally add a decorator to all Runnables executed on that executor.
PiperOrigin-RevId: 807916271
1 parent ebbf7e2 commit 95dc494

File tree

2 files changed

+106
-9
lines changed

2 files changed

+106
-9
lines changed

library/src/main/java/com/bumptech/glide/load/engine/executor/GlideExecutor.java

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.concurrent.TimeUnit;
2222
import java.util.concurrent.TimeoutException;
2323
import java.util.concurrent.atomic.AtomicInteger;
24+
import java.util.function.Function;
2425

2526
/** A prioritized {@link ThreadPoolExecutor} for running jobs in Glide. */
2627
public final class GlideExecutor implements ExecutorService {
@@ -456,6 +457,7 @@ public static final class Builder {
456457

457458
private String name;
458459
private long threadTimeoutMillis;
460+
private Function<? super Runnable, ? extends Runnable> onExecuteDecorator;
459461

460462
@Synthetic
461463
Builder(boolean preventNetworkOperations) {
@@ -514,21 +516,51 @@ public Builder setName(String name) {
514516
return this;
515517
}
516518

519+
/**
520+
* Sets the decorator to be applied to each runnable executed by the executor.
521+
*
522+
* <p>This is an experimental method that may be removed without warning in a future version.
523+
*/
524+
public Builder experimentalSetOnExecuteDecorator(
525+
Function<? super Runnable, ? extends Runnable> onExecuteDecorator) {
526+
this.onExecuteDecorator = onExecuteDecorator;
527+
return this;
528+
}
529+
517530
/** Builds a new {@link GlideExecutor} with any previously specified options. */
518531
public GlideExecutor build() {
519532
if (TextUtils.isEmpty(name)) {
520533
throw new IllegalArgumentException(
521534
"Name must be non-null and non-empty, but given: " + name);
522535
}
523-
ThreadPoolExecutor executor =
524-
new ThreadPoolExecutor(
525-
corePoolSize,
526-
maximumPoolSize,
527-
/* keepAliveTime= */ threadTimeoutMillis,
528-
TimeUnit.MILLISECONDS,
529-
new PriorityBlockingQueue<Runnable>(),
530-
new DefaultThreadFactory(
531-
threadFactory, name, uncaughtThrowableStrategy, preventNetworkOperations));
536+
ThreadFactory factory =
537+
new DefaultThreadFactory(
538+
threadFactory, name, uncaughtThrowableStrategy, preventNetworkOperations);
539+
ThreadPoolExecutor executor;
540+
if (onExecuteDecorator != null) {
541+
executor =
542+
new ThreadPoolExecutor(
543+
corePoolSize,
544+
maximumPoolSize,
545+
/* keepAliveTime= */ threadTimeoutMillis,
546+
TimeUnit.MILLISECONDS,
547+
new PriorityBlockingQueue<>(),
548+
factory) {
549+
@Override
550+
public void execute(@NonNull Runnable command) {
551+
super.execute(onExecuteDecorator.apply(command));
552+
}
553+
};
554+
} else {
555+
executor =
556+
new ThreadPoolExecutor(
557+
corePoolSize,
558+
maximumPoolSize,
559+
/* keepAliveTime= */ threadTimeoutMillis,
560+
TimeUnit.MILLISECONDS,
561+
new PriorityBlockingQueue<>(),
562+
factory);
563+
}
532564

533565
if (threadTimeoutMillis != NO_THREAD_TIMEOUT) {
534566
executor.allowCoreThreadTimeOut(true);

library/test/src/test/java/com/bumptech/glide/load/engine/executor/GlideExecutorTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.List;
1010
import java.util.concurrent.CountDownLatch;
1111
import java.util.concurrent.TimeUnit;
12+
import java.util.function.Function;
1213
import org.junit.Test;
1314
import org.junit.runner.RunWith;
1415
import org.robolectric.RobolectricTestRunner;
@@ -18,6 +19,70 @@
1819
@Config(sdk = ROBOLECTRIC_SDK)
1920
public class GlideExecutorTest {
2021

22+
@Test
23+
public void testOnExecuteDecorator_isCalledAndCanDecorateRunnable() throws InterruptedException {
24+
final CountDownLatch decoratorCalled = new CountDownLatch(1);
25+
final CountDownLatch decoratedRunnableExecuted = new CountDownLatch(1);
26+
27+
GlideExecutor executor =
28+
GlideExecutor.newDiskCacheBuilder()
29+
.experimentalSetOnExecuteDecorator(
30+
new Function<Runnable, Runnable>() {
31+
@Override
32+
public Runnable apply(Runnable runnable) {
33+
decoratorCalled.countDown();
34+
return new Runnable() {
35+
@Override
36+
public void run() {
37+
decoratedRunnableExecuted.countDown();
38+
runnable.run();
39+
}
40+
};
41+
}
42+
})
43+
.build();
44+
45+
final CountDownLatch originalRunnableExecuted = new CountDownLatch(1);
46+
executor.execute(
47+
new Runnable() {
48+
@Override
49+
public void run() {
50+
originalRunnableExecuted.countDown();
51+
}
52+
});
53+
54+
assertThat(decoratorCalled.await(100, TimeUnit.MILLISECONDS)).isTrue();
55+
assertThat(decoratedRunnableExecuted.await(100, TimeUnit.MILLISECONDS)).isTrue();
56+
assertThat(originalRunnableExecuted.await(100, TimeUnit.MILLISECONDS)).isTrue();
57+
58+
executor.shutdown();
59+
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
60+
}
61+
62+
@Test
63+
public void testOnExecuteDecorator_notDecorated_decoratorNotCalled() throws InterruptedException {
64+
final CountDownLatch decoratorCalled = new CountDownLatch(1);
65+
final CountDownLatch decoratedRunnableExecuted = new CountDownLatch(1);
66+
67+
GlideExecutor executor = GlideExecutor.newDiskCacheBuilder().build();
68+
69+
final CountDownLatch originalRunnableExecuted = new CountDownLatch(1);
70+
executor.execute(
71+
new Runnable() {
72+
@Override
73+
public void run() {
74+
originalRunnableExecuted.countDown();
75+
}
76+
});
77+
78+
assertThat(decoratorCalled.await(100, TimeUnit.MILLISECONDS)).isFalse();
79+
assertThat(decoratedRunnableExecuted.await(100, TimeUnit.MILLISECONDS)).isFalse();
80+
assertThat(originalRunnableExecuted.await(100, TimeUnit.MILLISECONDS)).isTrue();
81+
82+
executor.shutdown();
83+
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
84+
}
85+
2186
@Test
2287
public void testLoadsAreExecutedInOrder() throws InterruptedException {
2388
final List<Integer> resultPriorities = Collections.synchronizedList(new ArrayList<Integer>());

0 commit comments

Comments
 (0)