Skip to content

Commit 0e71e08

Browse files
authored
Put files in ResolutionResult (#1484)
This will allow an optimisation for when the resolver has already downloaded all the files so we can avoid a "double download"
1 parent fb9c549 commit 0e71e08

11 files changed

Lines changed: 78 additions & 22 deletions

File tree

private/rules/coursier.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,9 +456,11 @@ def get_direct_dependencies(all_artifacts, input_artifacts):
456456
if coords:
457457
full_key = to_key(coords)
458458
resolved_lookup[full_key] = coords
459+
459460
# Also store by simple group:artifact for fallback matching
460461
unpacked = unpack_coordinates(coords)
461462
simple_key = "%s:%s" % (unpacked.group, unpacked.artifact)
463+
462464
# Only use simple key if no classifier (classifiers are intentional)
463465
classifier = getattr(unpacked, "classifier", None)
464466
if not classifier:

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/ResolutionResult.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
import com.github.bazelbuild.rules_jvm_external.Coordinates;
1818
import com.google.common.graph.Graph;
19+
import java.nio.file.Path;
20+
import java.util.Map;
1921
import java.util.Set;
2022

2123
/**
@@ -26,10 +28,15 @@ public class ResolutionResult {
2628

2729
private final Graph<Coordinates> resolution;
2830
private final Set<Conflict> conflicts;
31+
private final Map<Coordinates, Path> paths;
2932

30-
public ResolutionResult(Graph<Coordinates> resolution, Set<Conflict> conflicts) {
33+
public ResolutionResult(
34+
Graph<Coordinates> resolution,
35+
Set<Conflict> conflicts,
36+
Map<Coordinates, Path> artifactPaths) {
3137
this.resolution = resolution;
32-
this.conflicts = conflicts;
38+
this.conflicts = Set.copyOf(conflicts);
39+
this.paths = artifactPaths != null ? Map.copyOf(artifactPaths) : Map.of();
3340
}
3441

3542
public Graph<Coordinates> getResolution() {
@@ -39,4 +46,8 @@ public Graph<Coordinates> getResolution() {
3946
public Set<Conflict> getConflicts() {
4047
return conflicts;
4148
}
49+
50+
public Map<Coordinates, Path> getPaths() {
51+
return paths;
52+
}
4253
}

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/cmd/AbstractMain.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void doMain(String[] args) {
7070

7171
ResolutionResult resolutionResult = resolver.resolve(request);
7272

73-
infos = fulfillDependencyInfos(resolver, listener, config, resolutionResult.getResolution());
73+
infos = fulfillDependencyInfos(resolver, listener, config, resolutionResult);
7474

7575
writeLockFile(listener, config, request, infos, resolutionResult.getConflicts());
7676

@@ -87,7 +87,7 @@ private static Set<DependencyInfo> fulfillDependencyInfos(
8787
Resolver resolver,
8888
EventListener listener,
8989
ResolverConfig config,
90-
Graph<Coordinates> resolved) {
90+
ResolutionResult resolutionResult) {
9191
listener.onEvent(new PhaseEvent("Downloading dependencies"));
9292

9393
ResolutionRequest request = config.getResolutionRequest();
@@ -103,10 +103,13 @@ private static Set<DependencyInfo> fulfillDependencyInfos(
103103
request.getLocalCache(resolver.getName()),
104104
request.getRepositories(),
105105
listener,
106-
cacheResults);
106+
cacheResults,
107+
resolutionResult.getPaths());
107108

108109
List<CompletableFuture<Set<DependencyInfo>>> futures = new LinkedList<>();
109110

111+
Graph<Coordinates> resolved = resolutionResult.getResolution();
112+
110113
ExecutorService downloadService =
111114
Executors.newFixedThreadPool(
112115
config.getMaxThreads(),

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/events/DownloadEvent.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,16 @@ public class DownloadEvent implements Event {
2020

2121
private final Stage stage;
2222
private final String target;
23+
private final String method;
2324

2425
public DownloadEvent(Stage stage, String target) {
26+
this(stage, null, target);
27+
}
28+
29+
public DownloadEvent(Stage stage, String method, String target) {
2530
this.stage = stage;
2631
this.target = Objects.requireNonNull(target);
32+
this.method = method;
2733
}
2834

2935
public Stage getStage() {
@@ -34,6 +40,10 @@ public String getTarget() {
3440
return target;
3541
}
3642

43+
public String getMethod() {
44+
return method;
45+
}
46+
3747
public enum Stage {
3848
STARTING,
3949
COMPLETE,

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,11 @@ private ResolutionResult parseDependencies(
172172
Map<Coordinates, String> coordinateHashes = new HashMap<>();
173173
// Track artifacts per node so we can inspect POM files for relocation later
174174
Map<Coordinates, List<GradleResolvedArtifact>> artifactsByNode = new HashMap<>();
175+
Map<Coordinates, Path> paths = new HashMap<>();
175176
List<GradleResolvedDependency> implementationDependencies = resolved.getResolvedDependencies();
176177
List<GradleUnresolvedDependency> unresolvedDependencies = resolved.getUnresolvedDependencies();
177178
if (implementationDependencies == null) {
178-
return new ResolutionResult(graph, null);
179+
return new ResolutionResult(graph, Set.of(), Map.of());
179180
}
180181

181182
for (GradleResolvedDependency dependency : implementationDependencies) {
@@ -203,6 +204,12 @@ private ResolutionResult parseDependencies(
203204
gradleCoordinates.getVersion());
204205
// Track artifact for this node
205206
artifactsByNode.computeIfAbsent(coordinates, k -> new ArrayList<>()).add(artifact);
207+
208+
File artifactFile = artifact.getFile();
209+
if (artifactFile != null && artifactFile.exists()) {
210+
paths.put(coordinates, artifactFile.toPath());
211+
}
212+
206213
addDependency(
207214
graph, coordinates, dependency, conflicts, requestedDepKeys, visited, artifactsByNode);
208215
// if there's a conflict and the conflicting version isn't one that's actually requested
@@ -270,7 +277,7 @@ private ResolutionResult parseDependencies(
270277
// After building the graph, contract relocation stubs (keep aggregating POMs)
271278
collapseRelocations(graph, coordinateHashes, conflicts, artifactsByNode);
272279

273-
return new ResolutionResult(graph, conflicts);
280+
return new ResolutionResult(graph, conflicts, paths);
274281
}
275282

276283
private String makeDepKey(String group, String artifact, String version) {

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/maven/MavenResolver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ public ResolutionResult resolve(ResolutionRequest request) {
267267
getConflicts(request.getDependencies(), resolvedDependencies),
268268
graphNormalizationResult.getConflicts());
269269

270-
return new ResolutionResult(graphNormalizationResult.getNormalizedGraph(), conflicts);
270+
return new ResolutionResult(graphNormalizationResult.getNormalizedGraph(), conflicts, Map.of());
271271
}
272272

273273
private GraphNormalizationResult makeVersionsConsistent(Graph<Coordinates> dependencyGraph) {

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/remote/Downloader.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.nio.file.Paths;
3333
import java.util.Collection;
3434
import java.util.LinkedHashSet;
35+
import java.util.Map;
3536
import java.util.Set;
3637
import java.util.logging.Logger;
3738
import org.apache.maven.model.Model;
@@ -53,17 +54,20 @@ public class Downloader {
5354
private final Set<URI> repos;
5455
private final boolean cacheDownloads;
5556
private final HttpDownloader httpDownloader;
57+
private final Map<Coordinates, Path> knownPaths;
5658

5759
public Downloader(
5860
Netrc netrc,
5961
Path localRepository,
6062
Collection<URI> repositories,
6163
EventListener listener,
62-
boolean cacheDownloads) {
64+
boolean cacheDownloads,
65+
Map<Coordinates, Path> knownPaths) {
6366
this.localRepository = localRepository;
6467
this.repos = Set.copyOf(repositories);
6568
this.cacheDownloads = cacheDownloads;
6669
this.httpDownloader = new HttpDownloader(netrc, listener);
70+
this.knownPaths = knownPaths != null ? Map.copyOf(knownPaths) : Map.of();
6771
}
6872

6973
public DownloadResult download(Coordinates coords) {
@@ -119,11 +123,16 @@ private DownloadResult performDownload(Coordinates coordsToUse, String path) {
119123
Set<URI> repos = new LinkedHashSet<>();
120124

121125
Path pathInRepo = null;
122-
123-
// Check the local cache for the path first
124-
Path cachedResult = localRepository.resolve(path);
125-
if (Files.exists(cachedResult)) {
126-
pathInRepo = cachedResult;
126+
Path knownPath = knownPaths.get(coordsToUse);
127+
128+
if (knownPath != null && Files.exists(knownPath)) {
129+
pathInRepo = knownPath;
130+
} else {
131+
// Check the local cache for the path first
132+
Path cachedResult = localRepository.resolve(path);
133+
if (Files.exists(cachedResult)) {
134+
pathInRepo = cachedResult;
135+
}
127136
}
128137

129138
String rjeAssumePresent = System.getenv("RJE_ASSUME_PRESENT");
@@ -141,6 +150,7 @@ private DownloadResult performDownload(Coordinates coordsToUse, String path) {
141150
repos.add(repo);
142151
downloaded = true;
143152

153+
Path cachedResult = localRepository.resolve(path);
144154
if (cacheDownloads && !cachedResult.equals(pathInRepo)) {
145155
try {
146156
Files.createDirectories(cachedResult.getParent());
@@ -150,10 +160,10 @@ private DownloadResult performDownload(Coordinates coordsToUse, String path) {
150160
}
151161
}
152162
}
153-
} else if (assumedDownloaded) { // path is set
163+
} else if (assumedDownloaded) {
154164
LOG.fine(String.format("Assuming %s is cached%n", coordsToUse));
155165
downloaded = true;
156-
} else if (httpDownloader.head(buildUri(repo, path))) { // path is set
166+
} else if (httpDownloader.head(buildUri(repo, path))) {
157167
LOG.fine(String.format("Checking head of %s%n", coordsToUse));
158168
repos.add(repo);
159169
downloaded = true;

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/remote/HttpDownloader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ private <X> HttpResponse<X> makeRequest(
159159

160160
private <X> HttpResponse<X> doRequest(
161161
int attemptCount, HttpRequest request, HttpResponse.BodyHandler<X> handler) {
162-
listener.onEvent(new DownloadEvent(STARTING, request.uri().toString()));
162+
listener.onEvent(new DownloadEvent(STARTING, request.method(), request.uri().toString()));
163163
LOG.fine(String.format("Downloading (attempt %d): %s", attemptCount, request.uri()));
164164

165165
// Slight pause, in case a previous attempt overwhelmed a server. We may be about to do it
@@ -209,7 +209,7 @@ private <X> HttpResponse<X> doRequest(
209209
// Don't panic. Just have another go.
210210

211211
if (attemptCount < MAX_RETRY_COUNT) {
212-
listener.onEvent(new DownloadEvent(COMPLETE, request.uri().toString()));
212+
listener.onEvent(new DownloadEvent(COMPLETE, request.method(), request.uri().toString()));
213213
return doRequest(++attemptCount, request, handler);
214214
}
215215

@@ -221,7 +221,7 @@ private <X> HttpResponse<X> doRequest(
221221
throw new RuntimeException(e);
222222
} finally {
223223
LOG.fine(String.format("Downloaded (attempt %d): %s", attemptCount, request.uri()));
224-
listener.onEvent(new DownloadEvent(COMPLETE, request.uri().toString()));
224+
listener.onEvent(new DownloadEvent(COMPLETE, request.method(), request.uri().toString()));
225225
}
226226
}
227227

private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/ui/PlainConsoleListener.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ public void onEvent(Event event) {
2929
if (event instanceof DownloadEvent) {
3030
DownloadEvent de = (DownloadEvent) event;
3131
if (de.getStage() == STARTING) {
32-
System.err.println("Downloading: " + de.getTarget());
32+
String method = de.getMethod();
33+
String prefix = method != null ? method + " " : "";
34+
System.err.println(prefix + de.getTarget());
3335
}
3436
}
3537

tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,12 @@ public void shouldHandlePackagingPomsInDependencies() throws IOException {
252252

253253
DownloadResult parentDownload =
254254
new Downloader(
255-
Netrc.fromUserHome(), localRepo, Set.of(repo.toUri()), new NullListener(), false)
255+
Netrc.fromUserHome(),
256+
localRepo,
257+
Set.of(repo.toUri()),
258+
new NullListener(),
259+
false,
260+
Map.of())
256261
.download(parentCoords);
257262

258263
assertTrue(parentDownload.getPath().isEmpty());

0 commit comments

Comments
 (0)