Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements #169

Merged
merged 5 commits into from Oct 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions client/pom.xml
Expand Up @@ -120,8 +120,6 @@
--no-fallback
--allow-incomplete-classpath
-H:IncludeResources=org/jboss/fuse/mvnd/.*
-H:IncludeResources=org/jline/utils/.*
-H:IncludeResources=org/fusesource/jansi/jansi.properties
-H:-ParseRuntimeOptions
</buildArgs>
</configuration>
Expand Down
Expand Up @@ -25,10 +25,12 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.jboss.fuse.mvnd.common.DaemonConnection;
import org.jboss.fuse.mvnd.common.DaemonDiagnostics;
import org.jboss.fuse.mvnd.common.DaemonException;
import org.jboss.fuse.mvnd.common.DaemonException.ConnectException;
import org.jboss.fuse.mvnd.common.DaemonException.StaleAddressException;
import org.jboss.fuse.mvnd.common.DaemonInfo;
import org.jboss.fuse.mvnd.common.Layout;
import org.jboss.fuse.mvnd.common.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -52,16 +54,18 @@ public class DaemonClientConnection implements Closeable {
private final Thread receiver;
private final AtomicBoolean running = new AtomicBoolean(true);
private final AtomicReference<Exception> exception = new AtomicReference<>();
private final Layout layout;

public DaemonClientConnection(DaemonConnection connection, DaemonInfo daemon,
StaleAddressDetector staleAddressDetector, boolean newDaemon, int maxKeepAliveMs) {
StaleAddressDetector staleAddressDetector, boolean newDaemon, int maxKeepAliveMs, Layout layout) {
this.connection = connection;
this.daemon = daemon;
this.staleAddressDetector = staleAddressDetector;
this.newDaemon = newDaemon;
this.maxKeepAliveMs = maxKeepAliveMs;
this.receiver = new Thread(this::doReceive);
this.receiver.start();
this.layout = layout;
}

public DaemonInfo getDaemon() {
Expand Down Expand Up @@ -101,11 +105,12 @@ public Message receive() throws ConnectException, StaleAddressException {
+ "ms, daemon may have crashed. You may want to check its status using mvnd --status");
}
} catch (Exception e) {
DaemonDiagnostics diag = new DaemonDiagnostics(daemon.getUid(), layout);
LOG.debug("Problem receiving message to the daemon. Performing 'on failure' operation...");
if (!hasReceived && newDaemon) {
throw new ConnectException("Could not receive a message from the daemon.", e);
throw new ConnectException("Could not receive a message from the daemon.\n" + diag.describe(), e);
} else if (staleAddressDetector.maybeStaleAddress(e)) {
throw new StaleAddressException("Could not receive a message from the daemon.", e);
throw new StaleAddressException("Could not receive a message from the daemon.\n" + diag.describe(), e);
}
} finally {
hasReceived = true;
Expand Down
Expand Up @@ -237,7 +237,7 @@ public DaemonClientConnection startDaemon(DaemonCompatibilitySpec constraint) {
throw new DaemonException.InterruptedException(e);
}
} while (System.currentTimeMillis() - start < DEFAULT_CONNECT_TIMEOUT);
DaemonDiagnostics diag = new DaemonDiagnostics(daemon, layout.daemonLog(daemon));
DaemonDiagnostics diag = new DaemonDiagnostics(daemon, layout);
throw new DaemonException.ConnectException("Timeout waiting to connect to the Maven daemon.\n" + diag.describe());
}

Expand Down Expand Up @@ -272,7 +272,7 @@ private String startDaemon() {
command = String.join(" ", args);

LOGGER.debug("Starting daemon process: uid = {}, workingDir = {}, daemonArgs: {}", uid, workingDir, command);
ProcessBuilder.Redirect redirect = ProcessBuilder.Redirect.appendTo(layout.daemonLog(uid + ".out").toFile());
ProcessBuilder.Redirect redirect = ProcessBuilder.Redirect.appendTo(layout.daemonOutLog(uid).toFile());
new ProcessBuilder()
.directory(workingDir.toFile())
.command(args)
Expand All @@ -297,7 +297,7 @@ private DaemonClientConnection connectToDaemonWithId(String daemon, boolean newD
try {
return connectToDaemon(daemonInfo, new CleanupOnStaleAddress(daemonInfo), newDaemon);
} catch (DaemonException.ConnectException e) {
DaemonDiagnostics diag = new DaemonDiagnostics(daemon, layout.daemonLog(daemon));
DaemonDiagnostics diag = new DaemonDiagnostics(daemon, layout);
throw new DaemonException.ConnectException("Could not connect to the Maven daemon.\n" + diag.describe(), e);
}
}
Expand All @@ -311,7 +311,7 @@ private DaemonClientConnection connectToDaemon(DaemonInfo daemon,
try {
int maxKeepAliveMs = layout.getKeepAliveMs() * layout.getMaxLostKeepAlive();
DaemonConnection connection = connect(daemon.getAddress());
return new DaemonClientConnection(connection, daemon, staleAddressDetector, newDaemon, maxKeepAliveMs);
return new DaemonClientConnection(connection, daemon, staleAddressDetector, newDaemon, maxKeepAliveMs, layout);
} catch (DaemonException.ConnectException e) {
staleAddressDetector.maybeStaleAddress(e);
throw e;
Expand Down
Expand Up @@ -18,6 +18,7 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.ArrayList;
Expand All @@ -34,39 +35,53 @@ public class DaemonDiagnostics {
private final static int TAIL_SIZE = 20;

private final String uid;
private final Path daemonLog;
private final Layout layout;

public DaemonDiagnostics(String uid, Path daemonLog) {
public DaemonDiagnostics(String uid, Layout layout) {
this.uid = uid;
this.daemonLog = daemonLog;
this.layout = layout;
}

@Override
public String toString() {
return "{"
+ "uid=" + uid
+ ", daemonLog=" + daemonLog
+ ", layout=" + layout
+ '}';
}

private String tailDaemonLog() {
public String describe() {
StringBuilder sb = new StringBuilder();
sb.append("Daemon uid: ").append(uid).append("\n");
tail(sb, "log file", layout.daemonLog(uid));
tail(sb, "output", layout.daemonOutLog(uid));
return sb.toString();
}

static void tail(StringBuilder sb, String name, Path log) {
try {
String tail = tail(daemonLog, TAIL_SIZE);
return formatTail(tail);
String tail = tail(log);
sb.append(" ").append(name).append(": ").append(log).append("\n");
sb.append("----- Last " + TAIL_SIZE + " lines from daemon ").append(name).append(" - ").append(log)
.append(" -----\n");
sb.append(tail);
sb.append("----- End of the daemon ").append(name).append(" -----\n");
} catch (NoSuchFileException e) {
sb.append(" no ").append(name).append(" at: ").append(log).append("\n");
} catch (IOException e) {
return "Unable to read from the daemon log file: " + daemonLog + ", because of: " + e.getCause();
sb.append(" unable to read from the daemon ").append(name).append(": ").append(log).append(", because of: ")
.append(e);
}
}

/**
* @param path to read from tail
* @param maxLines max lines to read
* @return tail content
* @throws IOException when reading failed
*/
static String tail(Path path, int maxLines) throws IOException {
static String tail(Path path) throws IOException {
try (BufferedReader r = Files.newBufferedReader(path)) {
return String.join("\n", r.lines().collect(lastN(maxLines)));
return String.join("\n", r.lines().collect(lastN(TAIL_SIZE))) + "\n";
}
}

Expand All @@ -83,15 +98,4 @@ static String tail(Path path, int maxLines) throws IOException {
}, ArrayList::new);
}

private String formatTail(String tail) {
return "----- Last " + TAIL_SIZE + " lines from daemon log file - " + daemonLog + " -----\n"
+ tail
+ "----- End of the daemon log -----\n";
}

public String describe() {
return "Daemon uid: " + uid + "\n"
+ " log file: " + daemonLog + "\n"
+ tailDaemonLog();
}
}
4 changes: 4 additions & 0 deletions common/src/main/java/org/jboss/fuse/mvnd/common/Layout.java
Expand Up @@ -56,6 +56,10 @@ public Path daemonLog(String daemon) {
return mavenHome.resolve("daemon/daemon-" + daemon + ".log");
}

public Path daemonOutLog(String daemon) {
return mavenHome.resolve("daemon/daemon-" + daemon + ".out.log");
}

public Path multiModuleProjectDirectory() {
return multiModuleProjectDirectory;
}
Expand Down
Expand Up @@ -190,7 +190,7 @@ void readInputLoop() {
break;
}
if (c == '+' || c == '-' || c == CTRL_L || c == CTRL_M) {
queue.add(new Event(EventType.INPUT, null, Character.toString(c)));
queue.add(new Event(EventType.INPUT, null, Character.toString((char) c)));
}
}
} catch (InterruptedIOException e) {
Expand Down Expand Up @@ -257,7 +257,7 @@ void displayLoop() {
linesPerProject = Math.max(0, linesPerProject - 1);
break;
case CTRL_L:
display.update(List.of(), 0);
display.update(Collections.emptyList(), 0);
break;
case CTRL_M:
displayDone = !displayDone;
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -40,7 +40,7 @@
<graalvm.version>20.2.0</graalvm.version>
<groovy.version>3.0.0</groovy.version>
<jakarta.inject.version>1.0</jakarta.inject.version>
<jline.version>3.17.0</jline.version>
<jline.version>3.17.1</jline.version>
<junit.jupiter.version>5.6.0</junit.jupiter.version>
<logback.version>1.2.3</logback.version>
<maven.version>3.6.3</maven.version>
Expand Down