@@ -66,7 +66,7 @@ public final class Registry extends OCI<ContainerRef> {
6666 /**
6767 * The executor service for parallel operations
6868 */
69- private ExecutorService executors ;
69+ private ExecutorService executorService ;
7070
7171 /**
7272 * The registries configuration loaded from the environment
@@ -139,6 +139,14 @@ private void setParallelism(int maxConcurrentDownloads) {
139139 this .maxConcurrentDownloads = maxConcurrentDownloads ;
140140 }
141141
142+ /**
143+ * Allow consumer to set custom executor service for parallel operations. If not set, a default one will be created with the given parallelism
144+ * @param executorService The executor service
145+ */
146+ private void setExecutorService (ExecutorService executorService ) {
147+ this .executorService = executorService ;
148+ }
149+
142150 /**
143151 * Return if this registry is insecure
144152 * @return True if insecure
@@ -177,11 +185,13 @@ private void setSkipTlsVerify(boolean skipTlsVerify) {
177185 */
178186 private Registry build () {
179187 client = HttpClient .Builder .builder ().withSkipTlsVerify (skipTlsVerify ).build ();
180- executors = Executors .newFixedThreadPool (maxConcurrentDownloads , r -> {
181- Thread t = new Thread (r );
182- t .setName ("layer-transfer-worker-%d" .formatted (t .getId ()));
183- return t ;
184- });
188+ if (executorService == null ) {
189+ executorService = Executors .newFixedThreadPool (maxConcurrentDownloads , r -> {
190+ Thread t = new Thread (r );
191+ t .setName ("layer-transfer-worker-%d" .formatted (t .getId ()));
192+ return t ;
193+ });
194+ }
185195 return this ;
186196 }
187197
@@ -220,7 +230,7 @@ public Registry asInsecure() {
220230
221231 @ Override
222232 public ExecutorService getExecutorService () {
223- return executors ;
233+ return executorService ;
224234 }
225235
226236 @ Override
@@ -1108,6 +1118,7 @@ public Builder from(Registry registry) {
11081118 this .registry .setInsecure (registry .insecure );
11091119 this .registry .setRegistry (registry .registry );
11101120 this .registry .setSkipTlsVerify (registry .skipTlsVerify );
1121+ this .registry .setExecutorService (registry .executorService );
11111122 this .registry .setParallelism (registry .maxConcurrentDownloads );
11121123 return this ;
11131124 }
@@ -1195,6 +1206,17 @@ public Builder withParallelism(int parallelism) {
11951206 return this ;
11961207 }
11971208
1209+ /**
1210+ * Set the executor service to use for parallel uploads/downloads. By default it uses a parallelism level given by withParallelism() and a fixed thread pool.
1211+ * Only uses for layers upload/download, not for manifest or index upload/download.
1212+ * @param executorService The executor service
1213+ * @return The builder
1214+ */
1215+ public Builder withExecutorService (ExecutorService executorService ) {
1216+ registry .setExecutorService (executorService );
1217+ return this ;
1218+ }
1219+
11981220 /**
11991221 * Set the insecure flag
12001222 * @param insecure Insecure
0 commit comments