Skip to content

Commit

Permalink
Speed up parallel plugin setup, fixes #310
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet authored Jan 14, 2021
2 parents ade8708 + a846ccb commit 4b35613
Show file tree
Hide file tree
Showing 16 changed files with 1,295 additions and 2 deletions.
3 changes: 3 additions & 0 deletions daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.plugin.ExtensionRealmCache;
import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.PluginArtifactsCache;
import org.apache.maven.plugin.PluginRealmCache;
import org.apache.maven.project.MavenProject;
Expand Down Expand Up @@ -102,6 +103,7 @@
import org.mvndaemon.mvnd.logging.smart.BuildEventListener;
import org.mvndaemon.mvnd.logging.smart.LoggingExecutionListener;
import org.mvndaemon.mvnd.logging.smart.LoggingOutputStream;
import org.mvndaemon.mvnd.plugin.CliMavenPluginManager;
import org.mvndaemon.mvnd.transfer.DaemonMavenTransferListener;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
Expand Down Expand Up @@ -505,6 +507,7 @@ protected void configure() {
bind(PluginArtifactsCache.class).to(CliPluginArtifactsCache.class);
bind(PluginRealmCache.class).to(CliPluginRealmCache.class);
bind(ProjectArtifactsCache.class).to(CliProjectArtifactsCache.class);
bind(MavenPluginManager.class).to(CliMavenPluginManager.class);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.mvndaemon.mvnd.cache.factory;

import java.util.function.BiPredicate;
import java.util.function.Function;

/**
* Cache containing records that can be invalidated.
Expand Down Expand Up @@ -53,4 +54,9 @@ public interface Cache<K, V extends CacheRecord> {
*/
void removeIf(BiPredicate<K, V> predicate);

/**
* Get or compute the cached value if absent and return it.
*/
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction);

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.inject.Named;
import javax.inject.Singleton;
Expand Down Expand Up @@ -145,5 +146,22 @@ public void removeIf(BiPredicate<K, V> predicate) {
}
}

@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
return map.compute(key, (k, v) -> {
if (v != null) {
try {
if (Objects.equals(v.timestamp, v.current())) {
return v;
}
} catch (RuntimeException e) {
// ignore and invalidate the record
}
v.record.invalidate();
v = null;
}
return new Record<>(mappingFunction.apply(k));
}).record;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiPredicate;
import java.util.function.Function;
import javax.inject.Named;
import javax.inject.Singleton;
import org.codehaus.plexus.logging.AbstractLogEnabled;
Expand Down Expand Up @@ -241,5 +242,14 @@ public void removeIf(BiPredicate<K, V> predicate) {
}
}

@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
validateRecords();
return map.computeIfAbsent(key, k -> {
V v = mappingFunction.apply(k);
add(v);
return v;
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import javax.inject.Singleton;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.DefaultPluginDescriptorCache;
import org.apache.maven.plugin.InvalidPluginDescriptorException;
import org.apache.maven.plugin.PluginDescriptorParsingException;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
Expand All @@ -38,6 +41,12 @@
@Named
public class CliPluginDescriptorCache extends DefaultPluginDescriptorCache {

@FunctionalInterface
public interface PluginDescriptorSupplier {
PluginDescriptor load()
throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException;
}

protected static class Record implements CacheRecord {

private final PluginDescriptor descriptor;
Expand Down Expand Up @@ -81,6 +90,31 @@ public PluginDescriptor get(Key key) {
return r != null ? clone(r.descriptor) : null;
}

public PluginDescriptor get(Key key, PluginDescriptorSupplier supplier)
throws PluginDescriptorParsingException, PluginResolutionException, InvalidPluginDescriptorException {
try {
Record r = cache.computeIfAbsent(key, k -> {
try {
return new Record(clone(supplier.load()));
} catch (PluginDescriptorParsingException | PluginResolutionException | InvalidPluginDescriptorException e) {
throw new RuntimeException(e);
}
});
return clone(r.descriptor);
} catch (RuntimeException e) {
if (e.getCause() instanceof PluginDescriptorParsingException) {
throw (PluginDescriptorParsingException) e.getCause();
}
if (e.getCause() instanceof PluginResolutionException) {
throw (PluginResolutionException) e.getCause();
}
if (e.getCause() instanceof InvalidPluginDescriptorException) {
throw (InvalidPluginDescriptorException) e.getCause();
}
throw e;
}
}

@Override
public void put(Key key, PluginDescriptor descriptor) {
cache.put(key, new Record(clone(descriptor)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import javax.inject.Singleton;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.DefaultPluginRealmCache;
import org.apache.maven.plugin.PluginContainerException;
import org.apache.maven.plugin.PluginRealmCache;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
Expand All @@ -38,6 +40,11 @@
@Typed(PluginRealmCache.class)
public class CliPluginRealmCache extends DefaultPluginRealmCache {

@FunctionalInterface
public interface PluginRealmSupplier {
CacheRecord load() throws PluginResolutionException, PluginContainerException;
}

protected static class Record implements org.mvndaemon.mvnd.cache.factory.CacheRecord {

final CacheRecord record;
Expand Down Expand Up @@ -75,6 +82,28 @@ public CacheRecord get(Key key) {
return r != null ? r.record : null;
}

public CacheRecord get(Key key, PluginRealmSupplier supplier)
throws PluginResolutionException, PluginContainerException {
try {
Record r = cache.computeIfAbsent(key, k -> {
try {
return new Record(supplier.load());
} catch (PluginResolutionException | PluginContainerException e) {
throw new RuntimeException(e);
}
});
return r.record;
} catch (RuntimeException e) {
if (e.getCause() instanceof PluginResolutionException) {
throw (PluginResolutionException) e.getCause();
}
if (e.getCause() instanceof PluginContainerException) {
throw (PluginContainerException) e.getCause();
}
throw e;
}
}

@Override
public CacheRecord put(Key key, ClassRealm pluginRealm, List<Artifact> pluginArtifacts) {
CacheRecord record = super.put(key, pluginRealm, pluginArtifacts);
Expand Down
Loading

0 comments on commit 4b35613

Please sign in to comment.