imagesToPull)
imageName,
e.getMessage());
}
- }))
+ }, this.executorServiceForPrePull()))
.toList()
.forEach(CompletableFuture::join);
}
+ protected ExecutorService executorServiceForPrePull()
+ {
+ return ImageBuilderExecutorServiceHolder.instance();
+ }
+
protected boolean canImageNameBePulled(final String imageName)
{
// scratch is reserved
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/DefaultExecutorServiceCreator.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/DefaultExecutorServiceCreator.java
new file mode 100644
index 0000000..4238f5e
--- /dev/null
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/DefaultExecutorServiceCreator.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2024 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.testcontainers.imagebuilder.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+public class DefaultExecutorServiceCreator implements ExecutorServiceCreator
+{
+ @Override
+ public ExecutorService createUnlimited(final String threadNamePrefix)
+ {
+ return Executors.newCachedThreadPool(factory(threadNamePrefix));
+ }
+
+ private static ThreadFactory factory(final String threadNamePrefix)
+ {
+ final AtomicInteger nextThreadId = new AtomicInteger(0);
+ return r -> {
+ final Thread t = new Thread(r, threadNamePrefix + "-" + nextThreadId.getAndIncrement());
+ t.setDaemon(true);
+ return t;
+ };
+ }
+}
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ExecutorServiceCreator.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ExecutorServiceCreator.java
new file mode 100644
index 0000000..1f9ae2c
--- /dev/null
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ExecutorServiceCreator.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2024 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.testcontainers.imagebuilder.concurrent;
+
+import java.util.concurrent.ExecutorService;
+
+
+public interface ExecutorServiceCreator
+{
+ ExecutorService createUnlimited(final String threadNamePrefix);
+}
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ExecutorServiceCreatorHolder.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ExecutorServiceCreatorHolder.java
new file mode 100644
index 0000000..a67b048
--- /dev/null
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ExecutorServiceCreatorHolder.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2024 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.testcontainers.imagebuilder.concurrent;
+
+public final class ExecutorServiceCreatorHolder
+{
+ private static ExecutorServiceCreator instance;
+
+ public static ExecutorServiceCreator instance()
+ {
+ if(instance == null)
+ {
+ init();
+ }
+ return instance;
+ }
+
+ private static synchronized void init()
+ {
+ if(instance != null)
+ {
+ return;
+ }
+ instance = new DefaultExecutorServiceCreator();
+ }
+
+ public static void setInstance(final ExecutorServiceCreator instance)
+ {
+ ExecutorServiceCreatorHolder.instance = instance;
+ }
+
+ private ExecutorServiceCreatorHolder()
+ {
+ }
+}
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ImageBuilderExecutorServiceHolder.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ImageBuilderExecutorServiceHolder.java
new file mode 100644
index 0000000..966d8d5
--- /dev/null
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/concurrent/ImageBuilderExecutorServiceHolder.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2024 XDEV Software (https://xdev.software)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.xdev.testcontainers.imagebuilder.concurrent;
+
+import java.util.concurrent.ExecutorService;
+
+
+/**
+ * Holds the {@link ExecutorService} that will be used for ImageBuilder related work.
+ *
+ * This {@link ExecutorService} should be used in favor of {@link java.util.concurrent.ForkJoinPool#commonPool()} as it
+ * guarantees better scalability.
+ *
+ */
+public final class ImageBuilderExecutorServiceHolder
+{
+ private static ExecutorService instance;
+
+ public static ExecutorService instance()
+ {
+ if(instance == null)
+ {
+ init();
+ }
+ return instance;
+ }
+
+ private static synchronized void init()
+ {
+ if(instance != null)
+ {
+ return;
+ }
+ instance = ExecutorServiceCreatorHolder.instance().createUnlimited("ImageBuilder");
+ }
+
+ public static void setInstance(final ExecutorService instance)
+ {
+ ImageBuilderExecutorServiceHolder.instance = instance;
+ }
+
+ private ImageBuilderExecutorServiceHolder()
+ {
+ }
+}
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/FastIgnoreRule.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/FastIgnoreRule.java
index 433b452..02a20fa 100644
--- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/FastIgnoreRule.java
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/FastIgnoreRule.java
@@ -199,17 +199,9 @@ public boolean isEmpty()
@Override
public String toString()
{
- final StringBuilder sb = new StringBuilder();
- if(this.inverse)
- {
- sb.append('!');
- }
- sb.append(this.matcher);
- if(this.dirOnly)
- {
- sb.append(PATH_SEPARATOR);
- }
- return sb.toString();
+ return (this.inverse ? "!" : "")
+ + this.matcher
+ + (this.dirOnly ? PATH_SEPARATOR : "");
}
@Override
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/internal/Strings.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/internal/Strings.java
index 60620ec..d539cc9 100644
--- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/internal/Strings.java
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/jgit/ignore/internal/Strings.java
@@ -301,7 +301,8 @@ enum PatternState
"java:S3776",
"PMD.CognitiveComplexity",
"PMD.CyclomaticComplexity",
- "java:S6541"}) // Eclipse code = Big brain required
+ "java:S6541",
+ "PMD.AvoidStringBuilderOrBuffer"}) // Eclipse code = Big brain required
public static Pattern convertGlob(final String pattern)
throws InvalidPatternException
{
@@ -581,7 +582,7 @@ private static String checkPosixCharClass(final char[] buffer)
return null;
}
- @SuppressWarnings({"java:S135", "java:S127"})
+ @SuppressWarnings({"java:S135", "java:S127", "PMD.AvoidStringBuilderOrBuffer"})
static String deleteBackslash(final String s)
{
if(s.indexOf('\\') < 0)
diff --git a/testcontainers-advanced-imagebuilder/src/main/java21/software/xdev/testcontainers/imagebuilder/concurrent/DefaultExecutorServiceCreator.java b/testcontainers-advanced-imagebuilder/src/main/java21/software/xdev/testcontainers/imagebuilder/concurrent/DefaultExecutorServiceCreator.java
new file mode 100644
index 0000000..6802090
--- /dev/null
+++ b/testcontainers-advanced-imagebuilder/src/main/java21/software/xdev/testcontainers/imagebuilder/concurrent/DefaultExecutorServiceCreator.java
@@ -0,0 +1,22 @@
+package software.xdev.testcontainers.imagebuilder.concurrent;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+
+public class DefaultExecutorServiceCreator implements ExecutorServiceCreator
+{
+ @Override
+ public ExecutorService createUnlimited(final String threadNamePrefix)
+ {
+ return Executors.newCachedThreadPool(factory(threadNamePrefix));
+ }
+
+ private static ThreadFactory factory(final String threadNamePrefix)
+ {
+ return Thread.ofVirtual()
+ .name(threadNamePrefix + "-", 0)
+ .factory();
+ }
+}
diff --git a/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerfileTest.java b/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerfileTest.java
index 5e2a503..802187d 100644
--- a/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerfileTest.java
+++ b/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerfileTest.java
@@ -18,6 +18,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.junit.jupiter.api.Assertions;
@@ -99,6 +100,6 @@ public boolean isIdentical(final List original, final List creat
}
));
- Assertions.assertDoesNotThrow(() -> builder.get());
+ Assertions.assertDoesNotThrow(() -> builder.get(5, TimeUnit.MINUTES));
}
}