Skip to content

Commit 425fb0b

Browse files
authored
Make filters daemon friendly (#1681)
Filters are not daemon friendly; move everything under session. Components are singletons, and use of `RemoteRepository` as key across sessions is something not recommended. For that GURK is needed.
1 parent e767edc commit 425fb0b

File tree

2 files changed

+100
-44
lines changed

2 files changed

+100
-44
lines changed

maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/GroupIdRemoteRepositoryFilterSource.java

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.Set;
3434
import java.util.TreeSet;
3535
import java.util.concurrent.ConcurrentHashMap;
36+
import java.util.concurrent.ConcurrentMap;
3637
import java.util.concurrent.atomic.AtomicBoolean;
3738
import java.util.stream.Collectors;
3839
import java.util.stream.Stream;
@@ -154,23 +155,34 @@ public final class GroupIdRemoteRepositoryFilterSource extends RemoteRepositoryF
154155

155156
private final PathProcessor pathProcessor;
156157

157-
private final ConcurrentHashMap<RemoteRepository, GroupTree> rules;
158-
159-
private final ConcurrentHashMap<RemoteRepository, Path> ruleFiles;
160-
161-
private final ConcurrentHashMap<RemoteRepository, Set<String>> recordedRules;
162-
163-
private final AtomicBoolean onShutdownHandlerRegistered;
164-
165158
@Inject
166159
public GroupIdRemoteRepositoryFilterSource(
167160
RepositorySystemLifecycle repositorySystemLifecycle, PathProcessor pathProcessor) {
168161
this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle);
169162
this.pathProcessor = requireNonNull(pathProcessor);
170-
this.rules = new ConcurrentHashMap<>();
171-
this.ruleFiles = new ConcurrentHashMap<>();
172-
this.recordedRules = new ConcurrentHashMap<>();
173-
this.onShutdownHandlerRegistered = new AtomicBoolean(false);
163+
}
164+
165+
@SuppressWarnings("unchecked")
166+
private ConcurrentMap<RemoteRepository, GroupTree> rules(RepositorySystemSession session) {
167+
return (ConcurrentMap<RemoteRepository, GroupTree>)
168+
session.getData().computeIfAbsent(getClass().getName() + ".rules", ConcurrentHashMap::new);
169+
}
170+
171+
@SuppressWarnings("unchecked")
172+
private ConcurrentMap<RemoteRepository, Path> ruleFiles(RepositorySystemSession session) {
173+
return (ConcurrentMap<RemoteRepository, Path>)
174+
session.getData().computeIfAbsent(getClass().getName() + ".ruleFiles", ConcurrentHashMap::new);
175+
}
176+
177+
@SuppressWarnings("unchecked")
178+
private ConcurrentMap<RemoteRepository, Set<String>> recordedRules(RepositorySystemSession session) {
179+
return (ConcurrentMap<RemoteRepository, Set<String>>)
180+
session.getData().computeIfAbsent(getClass().getName() + ".recordedRules", ConcurrentHashMap::new);
181+
}
182+
183+
private AtomicBoolean onShutdownHandlerRegistered(RepositorySystemSession session) {
184+
return (AtomicBoolean) session.getData()
185+
.computeIfAbsent(getClass().getName() + ".onShutdownHandlerRegistered", AtomicBoolean::new);
174186
}
175187

176188
@Override
@@ -206,8 +218,8 @@ public RemoteRepositoryFilter getRemoteRepositoryFilter(RepositorySystemSession
206218
@Override
207219
public void postProcess(RepositorySystemSession session, List<ArtifactResult> artifactResults) {
208220
if (isEnabled(session) && isRecord(session)) {
209-
if (onShutdownHandlerRegistered.compareAndSet(false, true)) {
210-
repositorySystemLifecycle.addOnSystemEndedHandler(this::saveRecordedLines);
221+
if (onShutdownHandlerRegistered(session).compareAndSet(false, true)) {
222+
repositorySystemLifecycle.addOnSystemEndedHandler(() -> saveRecordedLines(session));
211223
}
212224
for (ArtifactResult artifactResult : artifactResults) {
213225
if (artifactResult.isResolved() && artifactResult.getRepository() instanceof RemoteRepository) {
@@ -216,10 +228,11 @@ public void postProcess(RepositorySystemSession session, List<ArtifactResult> ar
216228
ruleFile(session, remoteRepository); // populate it; needed for save
217229
String line = "=" + artifactResult.getArtifact().getGroupId();
218230
RemoteRepository normalized = normalizeRemoteRepository(session, remoteRepository);
219-
recordedRules
231+
recordedRules(session)
220232
.computeIfAbsent(normalized, k -> new TreeSet<>())
221233
.add(line);
222-
rules.compute(normalized, (k, v) -> {
234+
rules(session)
235+
.compute(normalized, (k, v) -> {
223236
if (v == null || v == GroupTree.SENTINEL) {
224237
v = new GroupTree("");
225238
}
@@ -233,16 +246,17 @@ public void postProcess(RepositorySystemSession session, List<ArtifactResult> ar
233246
}
234247

235248
private Path ruleFile(RepositorySystemSession session, RemoteRepository remoteRepository) {
236-
return ruleFiles.computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> getBasedir(
249+
return ruleFiles(session).computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> getBasedir(
237250
session, LOCAL_REPO_PREFIX_DIR, CONFIG_PROP_BASEDIR, false)
238251
.resolve(GROUP_ID_FILE_PREFIX
239252
+ RepositoryIdHelper.cachedIdToPathSegment(session).apply(remoteRepository)
240253
+ GROUP_ID_FILE_SUFFIX));
241254
}
242255

243256
private GroupTree cacheRules(RepositorySystemSession session, RemoteRepository remoteRepository) {
244-
return rules.computeIfAbsent(
245-
normalizeRemoteRepository(session, remoteRepository), r -> loadRepositoryRules(session, r));
257+
return rules(session)
258+
.computeIfAbsent(
259+
normalizeRemoteRepository(session, remoteRepository), r -> loadRepositoryRules(session, r));
246260
}
247261

248262
private GroupTree loadRepositoryRules(RepositorySystemSession session, RemoteRepository remoteRepository) {
@@ -315,10 +329,10 @@ private boolean isRecord(RepositorySystemSession session) {
315329
/**
316330
* On-close handler that saves recorded rules, if any.
317331
*/
318-
private void saveRecordedLines() {
332+
private void saveRecordedLines(RepositorySystemSession session) {
319333
ArrayList<Exception> exceptions = new ArrayList<>();
320-
for (Map.Entry<RemoteRepository, Path> entry : ruleFiles.entrySet()) {
321-
Set<String> recorded = recordedRules.get(entry.getKey());
334+
for (Map.Entry<RemoteRepository, Path> entry : ruleFiles(session).entrySet()) {
335+
Set<String> recorded = recordedRules(session).get(entry.getKey());
322336
if (recorded != null && !recorded.isEmpty()) {
323337
try {
324338
ArrayList<String> result = new ArrayList<>();

maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/filter/PrefixesRemoteRepositoryFilterSource.java

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
import javax.inject.Named;
2323
import javax.inject.Singleton;
2424

25+
import java.net.URI;
2526
import java.nio.file.Files;
2627
import java.nio.file.Path;
2728
import java.util.Collections;
29+
import java.util.List;
2830
import java.util.concurrent.ConcurrentHashMap;
31+
import java.util.concurrent.ConcurrentMap;
2932
import java.util.function.Supplier;
3033

3134
import org.eclipse.aether.DefaultRepositorySystemSession;
@@ -40,6 +43,7 @@
4043
import org.eclipse.aether.repository.RemoteRepository;
4144
import org.eclipse.aether.resolution.MetadataRequest;
4245
import org.eclipse.aether.resolution.MetadataResult;
46+
import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
4347
import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
4448
import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
4549
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
@@ -191,10 +195,6 @@ public final class PrefixesRemoteRepositoryFilterSource extends RemoteRepository
191195

192196
private final RepositoryLayoutProvider repositoryLayoutProvider;
193197

194-
private final ConcurrentHashMap<RemoteRepository, PrefixTree> prefixes;
195-
196-
private final ConcurrentHashMap<RemoteRepository, RepositoryLayout> layouts;
197-
198198
@Inject
199199
public PrefixesRemoteRepositoryFilterSource(
200200
Supplier<MetadataResolver> metadataResolver,
@@ -203,8 +203,18 @@ public PrefixesRemoteRepositoryFilterSource(
203203
this.metadataResolver = requireNonNull(metadataResolver);
204204
this.remoteRepositoryManager = requireNonNull(remoteRepositoryManager);
205205
this.repositoryLayoutProvider = requireNonNull(repositoryLayoutProvider);
206-
this.prefixes = new ConcurrentHashMap<>();
207-
this.layouts = new ConcurrentHashMap<>();
206+
}
207+
208+
@SuppressWarnings("unchecked")
209+
private ConcurrentMap<RemoteRepository, PrefixTree> prefixes(RepositorySystemSession session) {
210+
return (ConcurrentMap<RemoteRepository, PrefixTree>)
211+
session.getData().computeIfAbsent(getClass().getName() + ".prefixes", ConcurrentHashMap::new);
212+
}
213+
214+
@SuppressWarnings("unchecked")
215+
private ConcurrentMap<RemoteRepository, RepositoryLayout> layouts(RepositorySystemSession session) {
216+
return (ConcurrentMap<RemoteRepository, RepositoryLayout>)
217+
session.getData().computeIfAbsent(getClass().getName() + ".layouts", ConcurrentHashMap::new);
208218
}
209219

210220
@Override
@@ -238,25 +248,26 @@ public RemoteRepositoryFilter getRemoteRepositoryFilter(RepositorySystemSession
238248
}
239249

240250
/**
241-
* Caches layout instances for remote repository. In case of unknown layout it returns {@code null}.
251+
* Caches layout instances for remote repository. In case of unknown layout it returns {@link #NOT_SUPPORTED}.
242252
*
243-
* @return the layout instance of {@code null} if layout not supported.
253+
* @return the layout instance or {@link #NOT_SUPPORTED} if layout not supported.
244254
*/
245255
private RepositoryLayout cacheLayout(RepositorySystemSession session, RemoteRepository remoteRepository) {
246-
return layouts.computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> {
256+
return layouts(session).computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> {
247257
try {
248258
return repositoryLayoutProvider.newRepositoryLayout(session, remoteRepository);
249259
} catch (NoRepositoryLayoutException e) {
250-
return null;
260+
return NOT_SUPPORTED;
251261
}
252262
});
253263
}
254264

255265
private PrefixTree cachePrefixTree(
256266
RepositorySystemSession session, Path basedir, RemoteRepository remoteRepository) {
257-
return prefixes.computeIfAbsent(
258-
normalizeRemoteRepository(session, remoteRepository),
259-
r -> loadPrefixTree(session, basedir, remoteRepository));
267+
return prefixes(session)
268+
.computeIfAbsent(
269+
normalizeRemoteRepository(session, remoteRepository),
270+
r -> loadPrefixTree(session, basedir, remoteRepository));
260271
}
261272

262273
private PrefixTree loadPrefixTree(
@@ -339,16 +350,15 @@ private Path resolvePrefixesFromRemoteRepository(
339350
session, Collections.emptyList(), Collections.singletonList(remoteRepository), true)
340351
.get(0);
341352
// retrieve prefix as metadata from repository
342-
MetadataRequest request =
343-
new MetadataRequest(new DefaultMetadata(PREFIX_FILE_TYPE, Metadata.Nature.RELEASE_OR_SNAPSHOT));
344-
request.setRepository(prepared);
345-
request.setDeleteLocalCopyIfMissing(true);
346-
request.setFavorLocalRepository(true);
347353
MetadataResult result = mr.resolveMetadata(
348354
new DefaultRepositorySystemSession(session)
349355
.setTransferListener(null)
350356
.setConfigProperty(CONFIG_PROP_SKIPPED, Boolean.TRUE.toString()),
351-
Collections.singleton(request))
357+
Collections.singleton(new MetadataRequest(
358+
new DefaultMetadata(PREFIX_FILE_TYPE, Metadata.Nature.RELEASE_OR_SNAPSHOT))
359+
.setRepository(prepared)
360+
.setDeleteLocalCopyIfMissing(true)
361+
.setFavorLocalRepository(true)))
352362
.get(0);
353363
if (result.isResolved()) {
354364
return result.getMetadata().getPath();
@@ -371,7 +381,7 @@ private PrefixesFilter(RepositorySystemSession session, Path basedir) {
371381
@Override
372382
public Result acceptArtifact(RemoteRepository remoteRepository, Artifact artifact) {
373383
RepositoryLayout repositoryLayout = cacheLayout(session, remoteRepository);
374-
if (repositoryLayout == null) {
384+
if (repositoryLayout == NOT_SUPPORTED) {
375385
return new SimpleResult(true, "Unsupported layout: " + remoteRepository);
376386
}
377387
return acceptPrefix(
@@ -382,7 +392,7 @@ public Result acceptArtifact(RemoteRepository remoteRepository, Artifact artifac
382392
@Override
383393
public Result acceptMetadata(RemoteRepository remoteRepository, Metadata metadata) {
384394
RepositoryLayout repositoryLayout = cacheLayout(session, remoteRepository);
385-
if (repositoryLayout == null) {
395+
if (repositoryLayout == NOT_SUPPORTED) {
386396
return new SimpleResult(true, "Unsupported layout: " + remoteRepository);
387397
}
388398
return acceptPrefix(
@@ -392,7 +402,7 @@ public Result acceptMetadata(RemoteRepository remoteRepository, Metadata metadat
392402

393403
private Result acceptPrefix(RemoteRepository repository, String path) {
394404
PrefixTree prefixTree = cachePrefixTree(session, basedir, repository);
395-
if (PrefixTree.SENTINEL == prefixTree) {
405+
if (prefixTree == PrefixTree.SENTINEL) {
396406
return NOT_PRESENT_RESULT;
397407
}
398408
if (prefixTree.acceptedPath(path)) {
@@ -405,4 +415,36 @@ private Result acceptPrefix(RemoteRepository repository, String path) {
405415

406416
private static final RemoteRepositoryFilter.Result NOT_PRESENT_RESULT =
407417
new SimpleResult(true, "Prefix file not present");
418+
419+
private static final RepositoryLayout NOT_SUPPORTED = new RepositoryLayout() {
420+
@Override
421+
public List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
422+
throw new UnsupportedOperationException();
423+
}
424+
425+
@Override
426+
public boolean hasChecksums(Artifact artifact) {
427+
throw new UnsupportedOperationException();
428+
}
429+
430+
@Override
431+
public URI getLocation(Artifact artifact, boolean upload) {
432+
throw new UnsupportedOperationException();
433+
}
434+
435+
@Override
436+
public URI getLocation(Metadata metadata, boolean upload) {
437+
throw new UnsupportedOperationException();
438+
}
439+
440+
@Override
441+
public List<ChecksumLocation> getChecksumLocations(Artifact artifact, boolean upload, URI location) {
442+
throw new UnsupportedOperationException();
443+
}
444+
445+
@Override
446+
public List<ChecksumLocation> getChecksumLocations(Metadata metadata, boolean upload, URI location) {
447+
throw new UnsupportedOperationException();
448+
}
449+
};
408450
}

0 commit comments

Comments
 (0)