Skip to content

Commit a19adf2

Browse files
committed
parallel library downloads
1 parent da1ef6c commit a19adf2

File tree

4 files changed

+278
-18
lines changed

4 files changed

+278
-18
lines changed

src/main/java/com/falsepattern/lib/dependencies/DependencyLoader.java

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
*/
2121
package com.falsepattern.lib.dependencies;
2222

23+
import com.falsepattern.lib.DeprecationDetails;
2324
import com.falsepattern.lib.StableAPI;
25+
import com.falsepattern.lib.internal.FalsePatternLib;
2426
import com.falsepattern.lib.internal.impl.dependencies.DependencyLoaderImpl;
25-
import lombok.Builder;
2627
import lombok.NonNull;
2728

29+
import java.util.concurrent.CompletableFuture;
30+
2831

2932
@StableAPI(since = "0.6.0")
3033
public class DependencyLoader {
@@ -34,10 +37,117 @@ public static void addMavenRepo(String url) {
3437
DependencyLoaderImpl.addMavenRepo(url);
3538
}
3639

37-
@Builder
40+
@StableAPI.Expose(since = "0.10.0")
41+
public static CompletableFuture<Void> loadLibrariesAsync(Library... libraries) {
42+
return DependencyLoaderImpl.loadLibrariesAsync(libraries);
43+
}
44+
45+
@StableAPI.Expose(since = "0.10.0")
46+
public static void loadLibraries(Library... libraries) {
47+
DependencyLoaderImpl.loadLibraries(libraries);
48+
}
49+
50+
@Deprecated
51+
@DeprecationDetails(deprecatedSince = "0.10.0")
3852
@StableAPI.Expose
3953
public static void loadLibrary(@NonNull String loadingModId, @NonNull String groupId, @NonNull String artifactId, @NonNull Version minVersion, Version maxVersion, @NonNull Version preferredVersion, String regularSuffix, String devSuffix) {
54+
FalsePatternLib.getLog().warn(DependencyLoader.class.getName() + ".loadLibrary is deprecated and will be removed in FalsePatternLib 0.11! Use loadLibraries instead!");
4055
DependencyLoaderImpl.loadLibrary(loadingModId, groupId, artifactId, minVersion, maxVersion, preferredVersion,
4156
regularSuffix, devSuffix);
4257
}
58+
59+
@DeprecationDetails(deprecatedSince = "0.10.0")
60+
@StableAPI.Expose
61+
@Deprecated
62+
public static VoidBuilder builder() {
63+
return new VoidBuilder();
64+
}
65+
66+
@StableAPI(since = "0.6.0")
67+
@DeprecationDetails(deprecatedSince = "0.10.0")
68+
public static class VoidBuilder {
69+
private String loadingModId;
70+
private String groupId;
71+
private String artifactId;
72+
private Version minVersion;
73+
private Version maxVersion;
74+
private Version preferredVersion;
75+
private String regularSuffix;
76+
private String devSuffix;
77+
78+
@Deprecated
79+
VoidBuilder() {
80+
}
81+
82+
@StableAPI.Expose
83+
@Deprecated
84+
public VoidBuilder loadingModId(@NonNull String loadingModId) {
85+
this.loadingModId = loadingModId;
86+
return this;
87+
}
88+
89+
@StableAPI.Expose
90+
@Deprecated
91+
public VoidBuilder groupId(@NonNull String groupId) {
92+
this.groupId = groupId;
93+
return this;
94+
}
95+
96+
@StableAPI.Expose
97+
@Deprecated
98+
public VoidBuilder artifactId(@NonNull String artifactId) {
99+
this.artifactId = artifactId;
100+
return this;
101+
}
102+
103+
@StableAPI.Expose
104+
@Deprecated
105+
public VoidBuilder minVersion(@NonNull Version minVersion) {
106+
this.minVersion = minVersion;
107+
return this;
108+
}
109+
110+
@StableAPI.Expose
111+
@Deprecated
112+
public VoidBuilder maxVersion(Version maxVersion) {
113+
this.maxVersion = maxVersion;
114+
return this;
115+
}
116+
117+
@StableAPI.Expose
118+
@Deprecated
119+
public VoidBuilder preferredVersion(@NonNull Version preferredVersion) {
120+
this.preferredVersion = preferredVersion;
121+
return this;
122+
}
123+
124+
@StableAPI.Expose
125+
@Deprecated
126+
public VoidBuilder regularSuffix(String regularSuffix) {
127+
this.regularSuffix = regularSuffix;
128+
return this;
129+
}
130+
131+
@StableAPI.Expose
132+
@Deprecated
133+
public VoidBuilder devSuffix(String devSuffix) {
134+
this.devSuffix = devSuffix;
135+
return this;
136+
}
137+
138+
@StableAPI.Expose
139+
@Deprecated
140+
public void build() {
141+
DependencyLoader.loadLibrary(loadingModId, groupId, artifactId, minVersion, maxVersion, preferredVersion,
142+
regularSuffix, devSuffix);
143+
}
144+
145+
@Override
146+
public String toString() {
147+
return "DependencyLoader.VoidBuilder(loadingModId=" + this.loadingModId + ", groupId=" + this.groupId +
148+
", artifactId=" + this.artifactId + ", minVersion=" + this.minVersion + ", maxVersion=" +
149+
this.maxVersion + ", preferredVersion=" + this.preferredVersion + ", regularSuffix=" +
150+
this.regularSuffix + ", devSuffix=" + this.devSuffix + ")";
151+
}
152+
}
43153
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.falsepattern.lib.dependencies;
2+
3+
import com.falsepattern.lib.StableAPI;
4+
import lombok.NonNull;
5+
6+
@StableAPI(since = "0.10.0")
7+
public class Library {
8+
@StableAPI.Expose
9+
@NonNull public final String loadingModId;
10+
@StableAPI.Expose
11+
@NonNull public final String groupId;
12+
@StableAPI.Expose
13+
@NonNull public final String artifactId;
14+
@StableAPI.Expose
15+
@NonNull public final Version minVersion;
16+
@StableAPI.Expose
17+
public final Version maxVersion;
18+
@StableAPI.Expose
19+
@NonNull public final Version preferredVersion;
20+
@StableAPI.Expose
21+
public final String regularSuffix;
22+
@StableAPI.Expose
23+
public final String devSuffix;
24+
25+
@StableAPI.Expose
26+
public Library(@NonNull String loadingModId, @NonNull String groupId, @NonNull String artifactId, @NonNull Version minVersion, Version maxVersion, @NonNull Version preferredVersion, String regularSuffix, String devSuffix) {
27+
this.loadingModId = loadingModId;
28+
this.groupId = groupId;
29+
this.artifactId = artifactId;
30+
this.minVersion = minVersion;
31+
this.maxVersion = maxVersion;
32+
this.preferredVersion = preferredVersion;
33+
this.regularSuffix = regularSuffix;
34+
this.devSuffix = devSuffix;
35+
}
36+
37+
@StableAPI.Expose
38+
public static LibraryBuilder builder() {
39+
return new LibraryBuilder();
40+
}
41+
42+
@StableAPI(since = "0.10.0")
43+
public static class LibraryBuilder {
44+
private String loadingModId;
45+
private String groupId;
46+
private String artifactId;
47+
private Version minVersion;
48+
private Version maxVersion;
49+
private Version preferredVersion;
50+
private String regularSuffix;
51+
private String devSuffix;
52+
53+
@StableAPI.Internal
54+
LibraryBuilder() {
55+
}
56+
57+
@StableAPI.Expose
58+
public LibraryBuilder loadingModId(@NonNull String loadingModId) {
59+
this.loadingModId = loadingModId;
60+
return this;
61+
}
62+
63+
@StableAPI.Expose
64+
public LibraryBuilder groupId(@NonNull String groupId) {
65+
this.groupId = groupId;
66+
return this;
67+
}
68+
69+
@StableAPI.Expose
70+
public LibraryBuilder artifactId(@NonNull String artifactId) {
71+
this.artifactId = artifactId;
72+
return this;
73+
}
74+
75+
@StableAPI.Expose
76+
public LibraryBuilder minVersion(@NonNull Version minVersion) {
77+
this.minVersion = minVersion;
78+
return this;
79+
}
80+
81+
@StableAPI.Expose
82+
public LibraryBuilder maxVersion(Version maxVersion) {
83+
this.maxVersion = maxVersion;
84+
return this;
85+
}
86+
87+
@StableAPI.Expose
88+
public LibraryBuilder preferredVersion(@NonNull Version preferredVersion) {
89+
this.preferredVersion = preferredVersion;
90+
return this;
91+
}
92+
93+
@StableAPI.Expose
94+
public LibraryBuilder regularSuffix(String regularSuffix) {
95+
this.regularSuffix = regularSuffix;
96+
return this;
97+
}
98+
99+
@StableAPI.Expose
100+
public LibraryBuilder devSuffix(String devSuffix) {
101+
this.devSuffix = devSuffix;
102+
return this;
103+
}
104+
105+
@StableAPI.Expose
106+
public Library build() {
107+
return new Library(loadingModId, groupId, artifactId, minVersion, maxVersion, preferredVersion,
108+
regularSuffix, devSuffix);
109+
}
110+
111+
@Override
112+
public String toString() {
113+
return "Library.LibraryBuilder(loadingModId=" + this.loadingModId + ", groupId=" + this.groupId +
114+
", artifactId=" + this.artifactId + ", minVersion=" + this.minVersion + ", maxVersion=" +
115+
this.maxVersion + ", preferredVersion=" + this.preferredVersion + ", regularSuffix=" +
116+
this.regularSuffix + ", devSuffix=" + this.devSuffix + ")";
117+
}
118+
}
119+
}

src/main/java/com/falsepattern/lib/internal/impl/dependencies/DependencyLoaderImpl.java

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
package com.falsepattern.lib.internal.impl.dependencies;
2222

2323
import com.falsepattern.lib.dependencies.DependencyLoader;
24+
import com.falsepattern.lib.dependencies.Library;
2425
import com.falsepattern.lib.dependencies.Version;
2526
import com.falsepattern.lib.internal.FalsePatternLib;
2627
import com.falsepattern.lib.internal.Internet;
2728
import com.falsepattern.lib.internal.Tags;
2829
import com.falsepattern.lib.internal.config.LibraryConfig;
2930
import com.falsepattern.lib.util.FileUtil;
31+
import io.netty.util.internal.ConcurrentSet;
3032
import lombok.NonNull;
3133
import lombok.RequiredArgsConstructor;
3234
import lombok.SneakyThrows;
@@ -45,27 +47,40 @@
4547
import java.nio.file.Files;
4648
import java.nio.file.Paths;
4749
import java.security.MessageDigest;
48-
import java.util.HashMap;
49-
import java.util.HashSet;
50+
import java.util.ArrayList;
5051
import java.util.Map;
5152
import java.util.Set;
53+
import java.util.concurrent.CompletableFuture;
54+
import java.util.concurrent.ConcurrentHashMap;
55+
import java.util.concurrent.ExecutorService;
56+
import java.util.concurrent.Executors;
5257
import java.util.concurrent.atomic.AtomicBoolean;
58+
import java.util.concurrent.atomic.AtomicLong;
5359

5460
public class DependencyLoaderImpl {
5561

5662
/**
57-
* Dependency checksum formats in a decreasing order of quality.
63+
* Library checksum formats in a decreasing order of quality.
5864
*/
5965
private static final String[] CHECKSUM_TYPES = new String[]{"sha512", "sha256", "sha1", "md5"};
60-
private static final Map<String, Version> loadedLibraries = new HashMap<>();
61-
private static final Map<String, String> loadedLibraryMods = new HashMap<>();
62-
private static final Set<String> mavenRepositories = new HashSet<>();
63-
private static final Logger log = LogManager.getLogger(Tags.MODNAME + " Dependency Downloader");
66+
private static final Map<String, Version> loadedLibraries = new ConcurrentHashMap<>();
67+
private static final Map<String, String> loadedLibraryMods = new ConcurrentHashMap<>();
68+
private static final Set<String> mavenRepositories = new ConcurrentSet<>();
69+
private static final Logger log = LogManager.getLogger(Tags.MODNAME + " Library Downloader");
70+
71+
private static final AtomicLong counter = new AtomicLong(0);
72+
private static final ExecutorService executor = Executors.newCachedThreadPool(r -> {
73+
val thread = new Thread(r);
74+
thread.setDaemon(true);
75+
thread.setName("Dependency Download Thread " + counter.incrementAndGet());
76+
return thread;
77+
});
6478

6579
public static void addMavenRepo(String url) {
6680
mavenRepositories.add(url);
6781
}
6882

83+
@Deprecated
6984
public static void loadLibrary(@NonNull String loadingModId, @NonNull String groupId, @NonNull String artifactId, @NonNull Version minVersion, Version maxVersion, @NonNull Version preferredVersion, String regularSuffix, String devSuffix) {
7085
new DependencyLoadTask(loadingModId, groupId, artifactId, minVersion, maxVersion, preferredVersion,
7186
regularSuffix, devSuffix).load();
@@ -115,7 +130,7 @@ private static void checkedDelete(File file) {
115130
}
116131
}
117132

118-
private static void addToClasspath(File file) {
133+
private static synchronized void addToClasspath(File file) {
119134
try {
120135
val cl = (LaunchClassLoader) DependencyLoader.class.getClassLoader();
121136
cl.addURL(file.toURI().toURL());
@@ -133,6 +148,21 @@ private static void download(InputStream is, File target) {
133148
Internet.transferAndClose(is, new BufferedOutputStream(Files.newOutputStream(target.toPath())));
134149
}
135150

151+
public static void loadLibraries(Library... libraries) {
152+
loadLibrariesAsync(libraries).join();
153+
}
154+
155+
public static CompletableFuture<Void> loadLibrariesAsync(Library... libraries) {
156+
val futures = new ArrayList<CompletableFuture<Void>>();
157+
for (val library: libraries) {
158+
val task = new DependencyLoadTask(library.loadingModId, library.groupId, library.artifactId,
159+
library.minVersion, library.maxVersion, library.preferredVersion,
160+
library.regularSuffix, library.devSuffix);
161+
futures.add(CompletableFuture.runAsync(task::load, executor));
162+
}
163+
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
164+
}
165+
136166
@RequiredArgsConstructor
137167
private static class DependencyLoadTask {
138168
@NonNull

src/main/java/com/falsepattern/lib/updates/UpdateChecker.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.falsepattern.json.node.JsonNode;
2424
import com.falsepattern.lib.StableAPI;
2525
import com.falsepattern.lib.dependencies.DependencyLoader;
26+
import com.falsepattern.lib.dependencies.Library;
2627
import com.falsepattern.lib.dependencies.SemanticVersion;
2728
import com.falsepattern.lib.internal.Internet;
2829
import com.falsepattern.lib.internal.Tags;
@@ -88,14 +89,14 @@ public static CompletableFuture<List<ModUpdateInfo>> fetchUpdatesAsync(String ur
8889
if (!jsonLibraryLoaded.get()) {
8990
try {
9091
DependencyLoader.addMavenRepo("https://maven.falsepattern.com/");
91-
DependencyLoader.builder()
92-
.loadingModId(Tags.MODID)
93-
.groupId("com.falsepattern")
94-
.artifactId("json")
95-
.minVersion(new SemanticVersion(0, 4, 0))
96-
.maxVersion(new SemanticVersion(0, Integer.MAX_VALUE, Integer.MAX_VALUE))
97-
.preferredVersion(new SemanticVersion(0, 4, 1))
98-
.build();
92+
DependencyLoader.loadLibraries(Library.builder()
93+
.loadingModId(Tags.MODID)
94+
.groupId("com.falsepattern")
95+
.artifactId("json")
96+
.minVersion(new SemanticVersion(0, 4, 0))
97+
.maxVersion(new SemanticVersion(0, Integer.MAX_VALUE, Integer.MAX_VALUE))
98+
.preferredVersion(new SemanticVersion(0, 4, 1))
99+
.build());
99100
} catch (Exception e) {
100101
throw new CompletionException(
101102
new UpdateCheckException("Failed to load json library for update checker!", e));

0 commit comments

Comments
 (0)