mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-09-10 21:22:03 +00:00
Remove the superfluous Serializer interface and its implemetation
This commit is contained in:
@@ -41,7 +41,7 @@ public class DaemonClientConnection implements Closeable {
|
|||||||
|
|
||||||
private final static Logger LOG = LoggerFactory.getLogger(DaemonClientConnection.class);
|
private final static Logger LOG = LoggerFactory.getLogger(DaemonClientConnection.class);
|
||||||
|
|
||||||
private final DaemonConnection<Message> connection;
|
private final DaemonConnection connection;
|
||||||
private final DaemonInfo daemon;
|
private final DaemonInfo daemon;
|
||||||
private final StaleAddressDetector staleAddressDetector;
|
private final StaleAddressDetector staleAddressDetector;
|
||||||
private final boolean newDaemon;
|
private final boolean newDaemon;
|
||||||
@@ -53,7 +53,7 @@ public class DaemonClientConnection implements Closeable {
|
|||||||
private final AtomicBoolean running = new AtomicBoolean(true);
|
private final AtomicBoolean running = new AtomicBoolean(true);
|
||||||
private final AtomicReference<Exception> exception = new AtomicReference<>();
|
private final AtomicReference<Exception> exception = new AtomicReference<>();
|
||||||
|
|
||||||
public DaemonClientConnection(DaemonConnection<Message> connection, DaemonInfo daemon,
|
public DaemonClientConnection(DaemonConnection connection, DaemonInfo daemon,
|
||||||
StaleAddressDetector staleAddressDetector, boolean newDaemon, int maxKeepAliveMs) {
|
StaleAddressDetector staleAddressDetector, boolean newDaemon, int maxKeepAliveMs) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.daemon = daemon;
|
this.daemon = daemon;
|
||||||
|
@@ -48,9 +48,7 @@ import org.jboss.fuse.mvnd.common.DaemonState;
|
|||||||
import org.jboss.fuse.mvnd.common.DaemonStopEvent;
|
import org.jboss.fuse.mvnd.common.DaemonStopEvent;
|
||||||
import org.jboss.fuse.mvnd.common.Environment;
|
import org.jboss.fuse.mvnd.common.Environment;
|
||||||
import org.jboss.fuse.mvnd.common.MavenDaemon;
|
import org.jboss.fuse.mvnd.common.MavenDaemon;
|
||||||
import org.jboss.fuse.mvnd.common.Message;
|
|
||||||
import org.jboss.fuse.mvnd.common.Os;
|
import org.jboss.fuse.mvnd.common.Os;
|
||||||
import org.jboss.fuse.mvnd.common.Serializer;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -71,15 +69,12 @@ public class DaemonConnector {
|
|||||||
|
|
||||||
private final DaemonRegistry registry;
|
private final DaemonRegistry registry;
|
||||||
private final ClientLayout layout;
|
private final ClientLayout layout;
|
||||||
private final Serializer<Message> serializer;
|
|
||||||
private final BuildProperties buildProperties;
|
private final BuildProperties buildProperties;
|
||||||
|
|
||||||
public DaemonConnector(ClientLayout layout, DaemonRegistry registry, BuildProperties buildProperties,
|
public DaemonConnector(ClientLayout layout, DaemonRegistry registry, BuildProperties buildProperties) {
|
||||||
Serializer<Message> serializer) {
|
|
||||||
this.layout = layout;
|
this.layout = layout;
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
this.buildProperties = buildProperties;
|
this.buildProperties = buildProperties;
|
||||||
this.serializer = serializer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DaemonClientConnection maybeConnect(DaemonCompatibilitySpec constraint) {
|
public DaemonClientConnection maybeConnect(DaemonCompatibilitySpec constraint) {
|
||||||
@@ -331,7 +326,7 @@ public class DaemonConnector {
|
|||||||
LOGGER.debug("Connecting to Daemon");
|
LOGGER.debug("Connecting to Daemon");
|
||||||
try {
|
try {
|
||||||
int maxKeepAliveMs = layout.getKeepAliveMs() * layout.getMaxLostKeepAlive();
|
int maxKeepAliveMs = layout.getKeepAliveMs() * layout.getMaxLostKeepAlive();
|
||||||
DaemonConnection<Message> connection = connect(daemon.getAddress());
|
DaemonConnection connection = connect(daemon.getAddress());
|
||||||
return new DaemonClientConnection(connection, daemon, staleAddressDetector, newDaemon, maxKeepAliveMs);
|
return new DaemonClientConnection(connection, daemon, staleAddressDetector, newDaemon, maxKeepAliveMs);
|
||||||
} catch (DaemonException.ConnectException e) {
|
} catch (DaemonException.ConnectException e) {
|
||||||
staleAddressDetector.maybeStaleAddress(e);
|
staleAddressDetector.maybeStaleAddress(e);
|
||||||
@@ -360,7 +355,7 @@ public class DaemonConnector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DaemonConnection<Message> connect(int port) throws DaemonException.ConnectException {
|
public DaemonConnection connect(int port) throws DaemonException.ConnectException {
|
||||||
InetSocketAddress address = new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
|
InetSocketAddress address = new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
|
||||||
try {
|
try {
|
||||||
LOGGER.debug("Trying to connect to address {}.", address);
|
LOGGER.debug("Trying to connect to address {}.", address);
|
||||||
@@ -372,7 +367,7 @@ public class DaemonConnector {
|
|||||||
throw new DaemonException.ConnectException(String.format("Socket connected to itself on %s.", address));
|
throw new DaemonException.ConnectException(String.format("Socket connected to itself on %s.", address));
|
||||||
}
|
}
|
||||||
LOGGER.debug("Connected to address {}.", socket.getRemoteSocketAddress());
|
LOGGER.debug("Connected to address {}.", socket.getRemoteSocketAddress());
|
||||||
return new DaemonConnection<>(socketChannel, serializer);
|
return new DaemonConnection(socketChannel);
|
||||||
} catch (DaemonException.ConnectException e) {
|
} catch (DaemonException.ConnectException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@@ -36,7 +36,6 @@ import org.jboss.fuse.mvnd.common.Message.BuildEvent;
|
|||||||
import org.jboss.fuse.mvnd.common.Message.BuildException;
|
import org.jboss.fuse.mvnd.common.Message.BuildException;
|
||||||
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
||||||
import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage;
|
import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage;
|
||||||
import org.jboss.fuse.mvnd.common.Message.MessageSerializer;
|
|
||||||
import org.jboss.fuse.mvnd.common.OsUtils;
|
import org.jboss.fuse.mvnd.common.OsUtils;
|
||||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||||
import org.jboss.fuse.mvnd.common.logging.TerminalOutput;
|
import org.jboss.fuse.mvnd.common.logging.TerminalOutput;
|
||||||
@@ -184,7 +183,7 @@ public class DefaultClient implements Client {
|
|||||||
args.add("-Dmaven.repo.local=" + localMavenRepository.toString());
|
args.add("-Dmaven.repo.local=" + localMavenRepository.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
final DaemonConnector connector = new DaemonConnector(layout, registry, buildProperties, new MessageSerializer());
|
final DaemonConnector connector = new DaemonConnector(layout, registry, buildProperties);
|
||||||
List<String> opts = new ArrayList<>();
|
List<String> opts = new ArrayList<>();
|
||||||
try (DaemonClientConnection daemon = connector.connect(new DaemonCompatibilitySpec(javaHome, opts),
|
try (DaemonClientConnection daemon = connector.connect(new DaemonCompatibilitySpec(javaHome, opts),
|
||||||
s -> output.accept(null, s))) {
|
s -> output.accept(null, s))) {
|
||||||
|
@@ -40,26 +40,24 @@ import org.slf4j.LoggerFactory;
|
|||||||
* https://github.com/gradle/gradle/blob/v5.6.2/subprojects/messaging/src/main/java/org/gradle/internal/remote/internal/inet/SocketConnection.java
|
* https://github.com/gradle/gradle/blob/v5.6.2/subprojects/messaging/src/main/java/org/gradle/internal/remote/internal/inet/SocketConnection.java
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DaemonConnection<T> implements AutoCloseable {
|
public class DaemonConnection implements AutoCloseable {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(DaemonConnection.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(DaemonConnection.class);
|
||||||
|
|
||||||
private final SocketChannel socket;
|
private final SocketChannel socket;
|
||||||
private final Serializer<T> serializer;
|
private final DataInputStream input;
|
||||||
|
private final DataOutputStream output;
|
||||||
private final InetSocketAddress localAddress;
|
private final InetSocketAddress localAddress;
|
||||||
private final InetSocketAddress remoteAddress;
|
private final InetSocketAddress remoteAddress;
|
||||||
private final DataInputStream instr;
|
|
||||||
private final DataOutputStream outstr;
|
|
||||||
|
|
||||||
public DaemonConnection(SocketChannel socket, Serializer<T> serializer) {
|
public DaemonConnection(SocketChannel socket) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.serializer = serializer;
|
|
||||||
try {
|
try {
|
||||||
// NOTE: we use non-blocking IO as there is no reliable way when using blocking IO to shutdown reads while
|
// NOTE: we use non-blocking IO as there is no reliable way when using blocking IO to shutdown reads while
|
||||||
// keeping writes active. For example, Socket.shutdownInput() does not work on Windows.
|
// keeping writes active. For example, Socket.shutdownInput() does not work on Windows.
|
||||||
socket.configureBlocking(false);
|
socket.configureBlocking(false);
|
||||||
outstr = new DataOutputStream(new SocketOutputStream(socket));
|
this.output = new DataOutputStream(new SocketOutputStream(socket));
|
||||||
instr = new DataInputStream(new SocketInputStream(socket));
|
this.input = new DataInputStream(new SocketInputStream(socket));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new DaemonException.InterruptedException(e);
|
throw new DaemonException.InterruptedException(e);
|
||||||
}
|
}
|
||||||
@@ -72,15 +70,15 @@ public class DaemonConnection<T> implements AutoCloseable {
|
|||||||
return "socket connection from " + localAddress + " to " + remoteAddress;
|
return "socket connection from " + localAddress + " to " + remoteAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T receive() throws DaemonException.MessageIOException {
|
public Message receive() throws DaemonException.MessageIOException {
|
||||||
try {
|
try {
|
||||||
return serializer.read(instr);
|
return Message.read(input);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("Discarding EOFException: {}", e.toString());
|
LOGGER.debug("Discarding EOFException: {}", e.toString());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} catch (ClassNotFoundException | IOException e) {
|
} catch (IOException e) {
|
||||||
throw new DaemonException.RecoverableMessageIOException(
|
throw new DaemonException.RecoverableMessageIOException(
|
||||||
String.format("Could not read message from '%s'.", remoteAddress), e);
|
String.format("Could not read message from '%s'.", remoteAddress), e);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -109,11 +107,11 @@ public class DaemonConnection<T> implements AutoCloseable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispatch(T message) throws DaemonException.MessageIOException {
|
public void dispatch(Message message) throws DaemonException.MessageIOException {
|
||||||
try {
|
try {
|
||||||
serializer.write(outstr, message);
|
message.write(output);
|
||||||
outstr.flush();
|
output.flush();
|
||||||
} catch (ClassNotFoundException | IOException e) {
|
} catch (IOException e) {
|
||||||
throw new DaemonException.RecoverableMessageIOException(
|
throw new DaemonException.RecoverableMessageIOException(
|
||||||
String.format("Could not write message %s to '%s'.", message, remoteAddress), e);
|
String.format("Could not write message %s to '%s'.", message, remoteAddress), e);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -124,7 +122,7 @@ public class DaemonConnection<T> implements AutoCloseable {
|
|||||||
|
|
||||||
public void flush() throws DaemonException.MessageIOException {
|
public void flush() throws DaemonException.MessageIOException {
|
||||||
try {
|
try {
|
||||||
outstr.flush();
|
output.flush();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new DaemonException.MessageIOException(String.format("Could not write '%s'.", remoteAddress), e);
|
throw new DaemonException.MessageIOException(String.format("Could not write '%s'.", remoteAddress), e);
|
||||||
}
|
}
|
||||||
@@ -132,7 +130,7 @@ public class DaemonConnection<T> implements AutoCloseable {
|
|||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
Throwable failure = null;
|
Throwable failure = null;
|
||||||
List<Closeable> elements = Arrays.asList(this::flush, instr, outstr, socket);
|
List<Closeable> elements = Arrays.asList(this::flush, input, output, socket);
|
||||||
for (Closeable element : elements) {
|
for (Closeable element : elements) {
|
||||||
try {
|
try {
|
||||||
element.close();
|
element.close();
|
||||||
|
@@ -17,17 +17,43 @@ package org.jboss.fuse.mvnd.common;
|
|||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.UTFDataFormatException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class Message {
|
public abstract class Message {
|
||||||
|
static final int BUILD_REQUEST = 0;
|
||||||
|
static final int BUILD_EVENT = 1;
|
||||||
|
static final int BUILD_MESSAGE = 2;
|
||||||
|
static final int BUILD_EXCEPTION = 3;
|
||||||
|
static final int KEEP_ALIVE = 4;
|
||||||
|
static final int STOP = 5;
|
||||||
|
|
||||||
|
public static Message read(DataInputStream input) throws IOException {
|
||||||
|
int type = input.read();
|
||||||
|
if (type == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
case BUILD_REQUEST:
|
||||||
|
return BuildRequest.read(input);
|
||||||
|
case BUILD_EVENT:
|
||||||
|
return BuildEvent.read(input);
|
||||||
|
case BUILD_MESSAGE:
|
||||||
|
return BuildMessage.read(input);
|
||||||
|
case BUILD_EXCEPTION:
|
||||||
|
return BuildException.read(input);
|
||||||
|
case KEEP_ALIVE:
|
||||||
|
return KeepAliveMessage.SINGLETON;
|
||||||
|
case STOP:
|
||||||
|
return StopMessage.SINGLETON;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Unexpected message type: " + type);
|
||||||
|
}
|
||||||
|
|
||||||
final long timestamp = System.nanoTime();
|
final long timestamp = System.nanoTime();
|
||||||
|
|
||||||
@@ -35,12 +61,57 @@ public abstract class Message {
|
|||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void write(DataOutputStream output) throws IOException;
|
||||||
|
|
||||||
|
static void writeStringList(DataOutputStream output, List<String> value) throws IOException {
|
||||||
|
output.writeInt(value.size());
|
||||||
|
for (String v : value) {
|
||||||
|
output.writeUTF(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeStringMap(DataOutputStream output, Map<String, String> value) throws IOException {
|
||||||
|
output.writeInt(value.size());
|
||||||
|
for (Map.Entry<String, String> e : value.entrySet()) {
|
||||||
|
output.writeUTF(e.getKey());
|
||||||
|
output.writeUTF(e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<String> readStringList(DataInputStream input) throws IOException {
|
||||||
|
ArrayList<String> l = new ArrayList<>();
|
||||||
|
int nb = input.readInt();
|
||||||
|
for (int i = 0; i < nb; i++) {
|
||||||
|
l.add(input.readUTF());
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, String> readStringMap(DataInputStream input) throws IOException {
|
||||||
|
LinkedHashMap<String, String> m = new LinkedHashMap<>();
|
||||||
|
int nb = input.readInt();
|
||||||
|
for (int i = 0; i < nb; i++) {
|
||||||
|
String k = input.readUTF();
|
||||||
|
String v = input.readUTF();
|
||||||
|
m.put(k, v);
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
public static class BuildRequest extends Message {
|
public static class BuildRequest extends Message {
|
||||||
final List<String> args;
|
final List<String> args;
|
||||||
final String workingDir;
|
final String workingDir;
|
||||||
final String projectDir;
|
final String projectDir;
|
||||||
final Map<String, String> env;
|
final Map<String, String> env;
|
||||||
|
|
||||||
|
public static Message read(DataInputStream input) throws IOException {
|
||||||
|
List<String> args = readStringList(input);
|
||||||
|
String workingDir = input.readUTF();
|
||||||
|
String projectDir = input.readUTF();
|
||||||
|
Map<String, String> env = readStringMap(input);
|
||||||
|
return new BuildRequest(args, workingDir, projectDir, env);
|
||||||
|
}
|
||||||
|
|
||||||
public BuildRequest(List<String> args, String workingDir, String projectDir, Map<String, String> env) {
|
public BuildRequest(List<String> args, String workingDir, String projectDir, Map<String, String> env) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
this.workingDir = workingDir;
|
this.workingDir = workingDir;
|
||||||
@@ -72,6 +143,15 @@ public abstract class Message {
|
|||||||
", projectDir='" + projectDir + '\'' +
|
", projectDir='" + projectDir + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream output) throws IOException {
|
||||||
|
output.write(BUILD_REQUEST);
|
||||||
|
writeStringList(output, args);
|
||||||
|
output.writeUTF(workingDir);
|
||||||
|
output.writeUTF(projectDir);
|
||||||
|
writeStringMap(output, env);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BuildException extends Message {
|
public static class BuildException extends Message {
|
||||||
@@ -79,6 +159,13 @@ public abstract class Message {
|
|||||||
final String className;
|
final String className;
|
||||||
final String stackTrace;
|
final String stackTrace;
|
||||||
|
|
||||||
|
public static Message read(DataInputStream input) throws IOException {
|
||||||
|
String message = input.readUTF();
|
||||||
|
String className = input.readUTF();
|
||||||
|
String stackTrace = input.readUTF();
|
||||||
|
return new BuildException(message, className, stackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
public BuildException(Throwable t) {
|
public BuildException(Throwable t) {
|
||||||
this(t.getMessage(), t.getClass().getName(), getStackTrace(t));
|
this(t.getMessage(), t.getClass().getName(), getStackTrace(t));
|
||||||
}
|
}
|
||||||
@@ -115,6 +202,14 @@ public abstract class Message {
|
|||||||
", stackTrace='" + stackTrace + '\'' +
|
", stackTrace='" + stackTrace + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream output) throws IOException {
|
||||||
|
output.write(BUILD_EXCEPTION);
|
||||||
|
output.writeUTF(message);
|
||||||
|
output.writeUTF(className);
|
||||||
|
output.writeUTF(stackTrace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BuildEvent extends Message {
|
public static class BuildEvent extends Message {
|
||||||
@@ -126,6 +221,13 @@ public abstract class Message {
|
|||||||
final String projectId;
|
final String projectId;
|
||||||
final String display;
|
final String display;
|
||||||
|
|
||||||
|
public static Message read(DataInputStream input) throws IOException {
|
||||||
|
BuildEvent.Type type = BuildEvent.Type.values()[input.read()];
|
||||||
|
String projectId = input.readUTF();
|
||||||
|
String display = input.readUTF();
|
||||||
|
return new BuildEvent(type, projectId, display);
|
||||||
|
}
|
||||||
|
|
||||||
public BuildEvent(Type type, String projectId, String display) {
|
public BuildEvent(Type type, String projectId, String display) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
@@ -152,12 +254,26 @@ public abstract class Message {
|
|||||||
", display='" + display + '\'' +
|
", display='" + display + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream output) throws IOException {
|
||||||
|
output.write(BUILD_EVENT);
|
||||||
|
output.write(type.ordinal());
|
||||||
|
output.writeUTF(projectId);
|
||||||
|
output.writeUTF(display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BuildMessage extends Message {
|
public static class BuildMessage extends Message {
|
||||||
final String projectId;
|
final String projectId;
|
||||||
final String message;
|
final String message;
|
||||||
|
|
||||||
|
public static Message read(DataInputStream input) throws IOException {
|
||||||
|
String projectId = input.readUTF();
|
||||||
|
String message = input.readUTF();
|
||||||
|
return new BuildMessage(projectId.isEmpty() ? null : projectId, message);
|
||||||
|
}
|
||||||
|
|
||||||
public BuildMessage(String projectId, String message) {
|
public BuildMessage(String projectId, String message) {
|
||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
@@ -178,245 +294,52 @@ public abstract class Message {
|
|||||||
", message='" + message + '\'' +
|
", message='" + message + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream output) throws IOException {
|
||||||
|
output.write(BUILD_MESSAGE);
|
||||||
|
output.writeUTF(projectId != null ? projectId : "");
|
||||||
|
output.writeUTF(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class KeepAliveMessage extends Message {
|
public static class KeepAliveMessage extends Message {
|
||||||
|
public static final KeepAliveMessage SINGLETON = new KeepAliveMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use {@link #SINGLETON}
|
||||||
|
*/
|
||||||
|
private KeepAliveMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "KeepAliveMessage{}";
|
return "KeepAliveMessage{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream output) throws IOException {
|
||||||
|
output.write(KEEP_ALIVE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MessageSerializer implements Serializer<Message> {
|
public static class StopMessage extends Message {
|
||||||
|
public static final KeepAliveMessage SINGLETON = new KeepAliveMessage();
|
||||||
|
|
||||||
final int BUILD_REQUEST = 0;
|
/**
|
||||||
final int BUILD_EVENT = 1;
|
* Use {@link #SINGLETON}
|
||||||
final int BUILD_MESSAGE = 2;
|
*/
|
||||||
final int BUILD_EXCEPTION = 3;
|
private StopMessage() {
|
||||||
final int KEEP_ALIVE = 4;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Message read(DataInputStream input) throws EOFException, Exception {
|
|
||||||
int type = input.read();
|
|
||||||
if (type == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
switch (type) {
|
|
||||||
case BUILD_REQUEST:
|
|
||||||
return readBuildRequest(input);
|
|
||||||
case BUILD_EVENT:
|
|
||||||
return readBuildEvent(input);
|
|
||||||
case BUILD_MESSAGE:
|
|
||||||
return readBuildMessage(input);
|
|
||||||
case BUILD_EXCEPTION:
|
|
||||||
return readBuildException(input);
|
|
||||||
case KEEP_ALIVE:
|
|
||||||
return new KeepAliveMessage();
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Unexpected message type: " + type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutputStream output, Message value) throws Exception {
|
public String toString() {
|
||||||
if (value instanceof BuildRequest) {
|
return "StopMessage{}";
|
||||||
output.write(BUILD_REQUEST);
|
|
||||||
writeBuildRequest(output, (BuildRequest) value);
|
|
||||||
} else if (value instanceof BuildEvent) {
|
|
||||||
output.write(BUILD_EVENT);
|
|
||||||
writeBuildEvent(output, (BuildEvent) value);
|
|
||||||
} else if (value instanceof BuildMessage) {
|
|
||||||
output.write(BUILD_MESSAGE);
|
|
||||||
writeBuildMessage(output, (BuildMessage) value);
|
|
||||||
} else if (value instanceof BuildException) {
|
|
||||||
output.write(BUILD_EXCEPTION);
|
|
||||||
writeBuildException(output, (BuildException) value);
|
|
||||||
} else if (value instanceof KeepAliveMessage) {
|
|
||||||
output.write(KEEP_ALIVE);
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BuildRequest readBuildRequest(DataInputStream input) throws IOException {
|
@Override
|
||||||
List<String> args = readStringList(input);
|
public void write(DataOutputStream output) throws IOException {
|
||||||
String workingDir = readUTF(input);
|
output.write(STOP);
|
||||||
String projectDir = readUTF(input);
|
|
||||||
Map<String, String> env = readStringMap(input);
|
|
||||||
return new BuildRequest(args, workingDir, projectDir, env);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeBuildRequest(DataOutputStream output, BuildRequest value) throws IOException {
|
|
||||||
writeStringList(output, value.args);
|
|
||||||
writeUTF(output, value.workingDir);
|
|
||||||
writeUTF(output, value.projectDir);
|
|
||||||
writeStringMap(output, value.env);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BuildEvent readBuildEvent(DataInputStream input) throws IOException {
|
|
||||||
BuildEvent.Type type = BuildEvent.Type.values()[input.read()];
|
|
||||||
String projectId = readUTF(input);
|
|
||||||
String display = readUTF(input);
|
|
||||||
return new BuildEvent(type, projectId, display);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeBuildEvent(DataOutputStream output, BuildEvent value) throws IOException {
|
|
||||||
output.write(value.type.ordinal());
|
|
||||||
writeUTF(output, value.projectId);
|
|
||||||
writeUTF(output, value.display);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BuildMessage readBuildMessage(DataInputStream input) throws IOException {
|
|
||||||
String projectId = readUTF(input);
|
|
||||||
String message = readUTF(input);
|
|
||||||
return new BuildMessage(projectId.isEmpty() ? null : projectId, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeBuildMessage(DataOutputStream output, BuildMessage value) throws IOException {
|
|
||||||
writeUTF(output, value.projectId != null ? value.projectId : "");
|
|
||||||
writeUTF(output, value.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BuildException readBuildException(DataInputStream input) throws IOException {
|
|
||||||
String message = readUTF(input);
|
|
||||||
String className = readUTF(input);
|
|
||||||
String stackTrace = readUTF(input);
|
|
||||||
return new BuildException(message, className, stackTrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeBuildException(DataOutputStream output, BuildException value) throws IOException {
|
|
||||||
writeUTF(output, value.message);
|
|
||||||
writeUTF(output, value.className);
|
|
||||||
writeUTF(output, value.stackTrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> readStringList(DataInputStream input) throws IOException {
|
|
||||||
ArrayList<String> l = new ArrayList<>();
|
|
||||||
int nb = input.readInt();
|
|
||||||
for (int i = 0; i < nb; i++) {
|
|
||||||
l.add(readUTF(input));
|
|
||||||
}
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeStringList(DataOutputStream output, List<String> value) throws IOException {
|
|
||||||
output.writeInt(value.size());
|
|
||||||
for (String v : value) {
|
|
||||||
writeUTF(output, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> readStringMap(DataInputStream input) throws IOException {
|
|
||||||
LinkedHashMap<String, String> m = new LinkedHashMap<>();
|
|
||||||
int nb = input.readInt();
|
|
||||||
for (int i = 0; i < nb; i++) {
|
|
||||||
String k = readUTF(input);
|
|
||||||
String v = readUTF(input);
|
|
||||||
m.put(k, v);
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeStringMap(DataOutputStream output, Map<String, String> value) throws IOException {
|
|
||||||
output.writeInt(value.size());
|
|
||||||
for (Map.Entry<String, String> e : value.entrySet()) {
|
|
||||||
writeUTF(output, e.getKey());
|
|
||||||
writeUTF(output, e.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String INVALID_BYTE = "Invalid byte";
|
|
||||||
private static final int UTF_BUFS_CHAR_CNT = 256;
|
|
||||||
private static final int UTF_BUFS_BYTE_CNT = UTF_BUFS_CHAR_CNT * 3;
|
|
||||||
final byte[] byteBuf = new byte[UTF_BUFS_BYTE_CNT];
|
|
||||||
|
|
||||||
String readUTF(DataInputStream input) throws IOException {
|
|
||||||
int len = input.readInt();
|
|
||||||
final char[] chars = new char[len];
|
|
||||||
int i = 0, cnt = 0, charIdx = 0;
|
|
||||||
while (charIdx < len) {
|
|
||||||
if (i == cnt) {
|
|
||||||
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
|
|
||||||
if (cnt < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
final int a = byteBuf[i++] & 0xff;
|
|
||||||
if (a < 0x80) {
|
|
||||||
// low bit clear
|
|
||||||
chars[charIdx++] = (char) a;
|
|
||||||
} else if (a < 0xc0) {
|
|
||||||
throw new UTFDataFormatException(INVALID_BYTE);
|
|
||||||
} else if (a < 0xe0) {
|
|
||||||
if (i == cnt) {
|
|
||||||
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
|
|
||||||
if (cnt < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
final int b = byteBuf[i++] & 0xff;
|
|
||||||
if ((b & 0xc0) != 0x80) {
|
|
||||||
throw new UTFDataFormatException(INVALID_BYTE);
|
|
||||||
}
|
|
||||||
chars[charIdx++] = (char) ((a & 0x1f) << 6 | b & 0x3f);
|
|
||||||
} else if (a < 0xf0) {
|
|
||||||
if (i == cnt) {
|
|
||||||
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
|
|
||||||
if (cnt < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
final int b = byteBuf[i++] & 0xff;
|
|
||||||
if ((b & 0xc0) != 0x80) {
|
|
||||||
throw new UTFDataFormatException(INVALID_BYTE);
|
|
||||||
}
|
|
||||||
if (i == cnt) {
|
|
||||||
cnt = input.read(byteBuf, 0, Math.min(UTF_BUFS_BYTE_CNT, len - charIdx));
|
|
||||||
if (cnt < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
final int c = byteBuf[i++] & 0xff;
|
|
||||||
if ((c & 0xc0) != 0x80) {
|
|
||||||
throw new UTFDataFormatException(INVALID_BYTE);
|
|
||||||
}
|
|
||||||
chars[charIdx++] = (char) ((a & 0x0f) << 12 | (b & 0x3f) << 6 | c & 0x3f);
|
|
||||||
} else {
|
|
||||||
throw new UTFDataFormatException(INVALID_BYTE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return String.valueOf(chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeUTF(DataOutputStream output, String s) throws IOException {
|
|
||||||
final int length = s.length();
|
|
||||||
output.writeInt(length);
|
|
||||||
int strIdx = 0;
|
|
||||||
int byteIdx = 0;
|
|
||||||
while (strIdx < length) {
|
|
||||||
final char c = s.charAt(strIdx++);
|
|
||||||
if (c > 0 && c <= 0x7f) {
|
|
||||||
byteBuf[byteIdx++] = (byte) c;
|
|
||||||
} else if (c <= 0x07ff) {
|
|
||||||
byteBuf[byteIdx++] = (byte) (0xc0 | 0x1f & c >> 6);
|
|
||||||
byteBuf[byteIdx++] = (byte) (0x80 | 0x3f & c);
|
|
||||||
} else {
|
|
||||||
byteBuf[byteIdx++] = (byte) (0xe0 | 0x0f & c >> 12);
|
|
||||||
byteBuf[byteIdx++] = (byte) (0x80 | 0x3f & c >> 6);
|
|
||||||
byteBuf[byteIdx++] = (byte) (0x80 | 0x3f & c);
|
|
||||||
}
|
|
||||||
if (byteIdx > UTF_BUFS_BYTE_CNT - 4) {
|
|
||||||
output.write(byteBuf, 0, byteIdx);
|
|
||||||
byteIdx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (byteIdx > 0) {
|
|
||||||
output.write(byteBuf, 0, byteIdx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jboss.fuse.mvnd.common;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File origin:
|
|
||||||
* https://github.com/gradle/gradle/blob/v5.6.2/subprojects/messaging/src/main/java/org/gradle/internal/serialize/Serializer.java
|
|
||||||
*/
|
|
||||||
public interface Serializer<T> {
|
|
||||||
/**
|
|
||||||
* Reads the next object from the given stream. The implementation must not perform any buffering, so that it reads only
|
|
||||||
* those bytes from the input stream that are
|
|
||||||
* required to deserialize the next object.
|
|
||||||
*
|
|
||||||
* @throws EOFException When the next object cannot be fully read due to reaching the end of stream.
|
|
||||||
*/
|
|
||||||
T read(DataInputStream input) throws EOFException, Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the given object to the given stream. The implementation must not perform any buffering.
|
|
||||||
*/
|
|
||||||
void write(DataOutputStream output, T value) throws Exception;
|
|
||||||
}
|
|
@@ -58,7 +58,7 @@ import org.jboss.fuse.mvnd.common.Message.BuildException;
|
|||||||
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
||||||
import org.jboss.fuse.mvnd.common.Message.BuildRequest;
|
import org.jboss.fuse.mvnd.common.Message.BuildRequest;
|
||||||
import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage;
|
import org.jboss.fuse.mvnd.common.Message.KeepAliveMessage;
|
||||||
import org.jboss.fuse.mvnd.common.Message.MessageSerializer;
|
import org.jboss.fuse.mvnd.common.Message.StopMessage;
|
||||||
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationResult;
|
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationResult;
|
||||||
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationStrategy;
|
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationStrategy;
|
||||||
import org.jboss.fuse.mvnd.logging.smart.AbstractLoggingSpy;
|
import org.jboss.fuse.mvnd.logging.smart.AbstractLoggingSpy;
|
||||||
@@ -187,7 +187,7 @@ public class Server implements AutoCloseable, Runnable {
|
|||||||
|
|
||||||
private void client(SocketChannel socket) {
|
private void client(SocketChannel socket) {
|
||||||
LOGGER.info("Client connected");
|
LOGGER.info("Client connected");
|
||||||
try (DaemonConnection<Message> connection = new DaemonConnection<Message>(socket, new MessageSerializer())) {
|
try (DaemonConnection connection = new DaemonConnection(socket)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
LOGGER.info("Waiting for request");
|
LOGGER.info("Waiting for request");
|
||||||
Message message = connection.receive();
|
Message message = connection.receive();
|
||||||
@@ -383,10 +383,7 @@ public class Server implements AutoCloseable, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final Message STOP = new Message() {
|
private void handle(DaemonConnection connection, BuildRequest buildRequest) {
|
||||||
};
|
|
||||||
|
|
||||||
private void handle(DaemonConnection<Message> connection, BuildRequest buildRequest) {
|
|
||||||
updateState(Busy);
|
updateState(Busy);
|
||||||
try {
|
try {
|
||||||
int keepAlive = Environment.DAEMON_KEEP_ALIVE_MS.systemProperty().asInt();
|
int keepAlive = Environment.DAEMON_KEEP_ALIVE_MS.systemProperty().asInt();
|
||||||
@@ -411,7 +408,7 @@ public class Server implements AutoCloseable, Runnable {
|
|||||||
if (flushed) {
|
if (flushed) {
|
||||||
m = queue.poll(keepAlive, TimeUnit.MILLISECONDS);
|
m = queue.poll(keepAlive, TimeUnit.MILLISECONDS);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
m = new KeepAliveMessage();
|
m = KeepAliveMessage.SINGLETON;
|
||||||
}
|
}
|
||||||
flushed = false;
|
flushed = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -422,7 +419,7 @@ public class Server implements AutoCloseable, Runnable {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m == STOP) {
|
if (m == StopMessage.SINGLETON) {
|
||||||
connection.flush();
|
connection.flush();
|
||||||
LOGGER.info("No more message to dispatch");
|
LOGGER.info("No more message to dispatch");
|
||||||
return;
|
return;
|
||||||
@@ -473,7 +470,7 @@ public class Server implements AutoCloseable, Runnable {
|
|||||||
return 96;
|
return 96;
|
||||||
} else if (m instanceof BuildException) {
|
} else if (m instanceof BuildException) {
|
||||||
return 97;
|
return 97;
|
||||||
} else if (m == STOP) {
|
} else if (m == StopMessage.SINGLETON) {
|
||||||
return 99;
|
return 99;
|
||||||
} else if (m instanceof KeepAliveMessage) {
|
} else if (m instanceof KeepAliveMessage) {
|
||||||
return 100;
|
return 100;
|
||||||
@@ -537,12 +534,12 @@ public class Server implements AutoCloseable, Runnable {
|
|||||||
|
|
||||||
public void finish() throws Exception {
|
public void finish() throws Exception {
|
||||||
queue.add(new BuildEvent(Type.BuildStopped, "", ""));
|
queue.add(new BuildEvent(Type.BuildStopped, "", ""));
|
||||||
queue.add(STOP);
|
queue.add(StopMessage.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fail(Throwable t) throws Exception {
|
public void fail(Throwable t) throws Exception {
|
||||||
queue.add(new BuildException(t));
|
queue.add(new BuildException(t));
|
||||||
queue.add(STOP);
|
queue.add(StopMessage.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user