mirror of
https://github.com/apache/maven-mvnd.git
synced 2026-01-13 07:04:14 +08:00
Implement build cancelation, fixes #127
This commit is contained in:
committed by
Peter Palaga
parent
02ef4a2fc2
commit
0800aeb791
@@ -88,6 +88,10 @@ class ProjectExecutorService {
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
// hook to allow pausing executor during unit tests
|
||||
protected void beforeExecute(Thread t, Runnable r) {
|
||||
}
|
||||
|
||||
@@ -70,16 +70,41 @@ public class SmartBuilder implements Builder {
|
||||
|
||||
private final LifecycleModuleBuilder moduleBuilder;
|
||||
|
||||
private volatile SmartBuilderImpl builder;
|
||||
private volatile boolean canceled;
|
||||
|
||||
private static SmartBuilder INSTANCE;
|
||||
|
||||
public static SmartBuilder cancel() {
|
||||
SmartBuilder builder = INSTANCE;
|
||||
if (builder != null) {
|
||||
builder.doCancel();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public SmartBuilder(LifecycleModuleBuilder moduleBuilder) {
|
||||
this.moduleBuilder = moduleBuilder;
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
void doCancel() {
|
||||
canceled = true;
|
||||
SmartBuilderImpl b = builder;
|
||||
if (b != null) {
|
||||
b.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public void doneCancel() {
|
||||
canceled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(final MavenSession session, final ReactorContext reactorContext,
|
||||
public synchronized void build(final MavenSession session, final ReactorContext reactorContext,
|
||||
ProjectBuildList projectBuilds, final List<TaskSegment> taskSegments,
|
||||
ReactorBuildStatus reactorBuildStatus) throws ExecutionException, InterruptedException {
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
String providerScript = null;
|
||||
@@ -165,9 +190,16 @@ public class SmartBuilder implements Builder {
|
||||
List<Map.Entry<TaskSegment, ReactorBuildStats>> allstats = new ArrayList<>();
|
||||
for (TaskSegment taskSegment : taskSegments) {
|
||||
Set<MavenProject> projects = projectBuilds.getByTaskSegment(taskSegment).getProjects();
|
||||
ReactorBuildStats stats = new SmartBuilderImpl(moduleBuilder, session, reactorContext, taskSegment, projects, graph)
|
||||
.build();
|
||||
allstats.add(new AbstractMap.SimpleEntry<>(taskSegment, stats));
|
||||
if (canceled) {
|
||||
return;
|
||||
}
|
||||
builder = new SmartBuilderImpl(moduleBuilder, session, reactorContext, taskSegment, projects, graph);
|
||||
try {
|
||||
ReactorBuildStats stats = builder.build();
|
||||
allstats.add(new AbstractMap.SimpleEntry<>(taskSegment, stats));
|
||||
} finally {
|
||||
builder = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (session.getResult().hasExceptions()) {
|
||||
|
||||
@@ -157,6 +157,10 @@ class SmartBuilderImpl {
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
executor.cancel();
|
||||
}
|
||||
|
||||
private void submitAll(Set<MavenProject> readyProjects) {
|
||||
List<ProjectBuildTask> tasks = new ArrayList<>();
|
||||
for (MavenProject project : readyProjects) {
|
||||
|
||||
@@ -41,6 +41,7 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.maven.cli.DaemonMavenCli;
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.jboss.fuse.mvnd.builder.SmartBuilder;
|
||||
import org.jboss.fuse.mvnd.common.DaemonConnection;
|
||||
import org.jboss.fuse.mvnd.common.DaemonException;
|
||||
import org.jboss.fuse.mvnd.common.DaemonExpirationStatus;
|
||||
@@ -61,7 +62,9 @@ import org.jboss.fuse.mvnd.logging.smart.AbstractLoggingSpy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.jboss.fuse.mvnd.common.DaemonState.Broken;
|
||||
import static org.jboss.fuse.mvnd.common.DaemonState.Busy;
|
||||
import static org.jboss.fuse.mvnd.common.DaemonState.Canceled;
|
||||
import static org.jboss.fuse.mvnd.common.DaemonState.StopRequested;
|
||||
import static org.jboss.fuse.mvnd.common.DaemonState.Stopped;
|
||||
|
||||
@@ -267,7 +270,6 @@ public class Server implements AutoCloseable, Runnable {
|
||||
condition.await();
|
||||
break;
|
||||
case Canceled:
|
||||
LOGGER.debug("cancel requested.");
|
||||
cancelNow();
|
||||
break;
|
||||
case Broken:
|
||||
@@ -355,17 +357,12 @@ public class Server implements AutoCloseable, Runnable {
|
||||
private void cancelNow() {
|
||||
long time = System.currentTimeMillis() + CANCEL_TIMEOUT;
|
||||
|
||||
// LOGGER.debug("Cancel requested: will wait for daemon to become idle.");
|
||||
// try {
|
||||
// cancellationToken.cancel();
|
||||
// } catch (Exception ex) {
|
||||
// LOGGER.error("Cancel processing failed. Will continue.", ex);
|
||||
// }
|
||||
|
||||
LOGGER.debug("Cancel requested: will wait for daemon to become idle.");
|
||||
final SmartBuilder builder = SmartBuilder.cancel();
|
||||
stateLock.lock();
|
||||
try {
|
||||
long rem;
|
||||
while ((rem = System.currentTimeMillis() - time) > 0) {
|
||||
while ((rem = time - System.currentTimeMillis()) > 0) {
|
||||
try {
|
||||
switch (getState()) {
|
||||
case Idle:
|
||||
@@ -391,6 +388,9 @@ public class Server implements AutoCloseable, Runnable {
|
||||
stopNow("cancel requested but timed out");
|
||||
} finally {
|
||||
stateLock.unlock();
|
||||
if (builder != null) {
|
||||
builder.doneCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,12 +447,20 @@ public class Server implements AutoCloseable, Runnable {
|
||||
break;
|
||||
}
|
||||
LOGGER.info("Received message: {}", message);
|
||||
synchronized (recvQueue) {
|
||||
recvQueue.put(message);
|
||||
recvQueue.notifyAll();
|
||||
if (message == Message.CANCEL_BUILD_SINGLETON) {
|
||||
updateState(DaemonState.Canceled);
|
||||
return;
|
||||
} else {
|
||||
synchronized (recvQueue) {
|
||||
recvQueue.put(message);
|
||||
recvQueue.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (DaemonException.RecoverableMessageIOException t) {
|
||||
updateState(Canceled);
|
||||
} catch (Throwable t) {
|
||||
updateState(Broken);
|
||||
LOGGER.error("Error receiving events", t);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.IOError;
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildEvent;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildStarted;
|
||||
import org.jboss.fuse.mvnd.common.logging.TerminalOutput;
|
||||
|
||||
public class MavenLoggingSpy extends AbstractLoggingSpy {
|
||||
@@ -32,7 +33,7 @@ public class MavenLoggingSpy extends AbstractLoggingSpy {
|
||||
protected void onStartSession(MavenSession session) {
|
||||
try {
|
||||
output = new TerminalOutput(null);
|
||||
output.accept(new Message.BuildStarted(
|
||||
output.accept(new BuildStarted(
|
||||
session.getTopLevelProject().getName(),
|
||||
session.getAllProjects().size(),
|
||||
session.getRequest().getDegreeOfConcurrency()));
|
||||
|
||||
Reference in New Issue
Block a user