mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 15:10:23 +00:00
Improve beacon connection initialization and timeout
This commit is contained in:
parent
7a4e79af4f
commit
71e0ce35e8
9 changed files with 50 additions and 43 deletions
|
@ -78,7 +78,7 @@ public final class XPipeApiConnection extends BeaconConnection {
|
|||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
var s = BeaconClient.tryConnect(BeaconClient.ApiClientInformation.builder()
|
||||
var s = BeaconClient.tryEstablishConnection(BeaconClient.ApiClientInformation.builder()
|
||||
.version("?")
|
||||
.language("Java")
|
||||
.build());
|
||||
|
@ -96,7 +96,7 @@ public final class XPipeApiConnection extends BeaconConnection {
|
|||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
var r = BeaconServer.isRunning();
|
||||
var r = BeaconServer.isReachable();
|
||||
if (!r) {
|
||||
return;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ public final class XPipeApiConnection extends BeaconConnection {
|
|||
|
||||
@Override
|
||||
protected void constructSocket() {
|
||||
if (!BeaconServer.isRunning()) {
|
||||
if (!BeaconServer.isReachable()) {
|
||||
try {
|
||||
start();
|
||||
} catch (Exception ex) {
|
||||
|
@ -122,7 +122,7 @@ public final class XPipeApiConnection extends BeaconConnection {
|
|||
}
|
||||
|
||||
try {
|
||||
beaconClient = BeaconClient.connect(BeaconClient.ApiClientInformation.builder()
|
||||
beaconClient = BeaconClient.establishConnection(BeaconClient.ApiClientInformation.builder()
|
||||
.version("?")
|
||||
.language("Java")
|
||||
.build());
|
||||
|
|
|
@ -192,6 +192,9 @@ public class AppSocketServer {
|
|||
}
|
||||
var information =
|
||||
JacksonMapper.getDefault().treeToValue(informationNode, BeaconClient.ClientInformation.class);
|
||||
try (var blockOut = BeaconFormat.writeBlocks(clientSocket.getOutputStream())) {
|
||||
blockOut.write("\"ACK\"".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
TrackEvent.builder()
|
||||
.category("beacon")
|
||||
|
|
|
@ -139,7 +139,11 @@ public class ErrorHandlerComp extends SimpleComp {
|
|||
var r = JfxHelper.createNamedEntry(a.getName(), a.getDescription());
|
||||
var b = new ButtonComp(null, r, () -> {
|
||||
takenAction.setValue(a);
|
||||
if (a.handle(event)) {
|
||||
try {
|
||||
if (a.handle(event)) {
|
||||
stage.close();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
stage.close();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.launcher;
|
|||
|
||||
import io.xpipe.app.core.AppDataLock;
|
||||
import io.xpipe.app.core.AppLogs;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.LogErrorHandler;
|
||||
|
@ -18,6 +19,7 @@ import lombok.SneakyThrows;
|
|||
import picocli.CommandLine;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -69,7 +71,7 @@ public class LauncherCommand implements Callable<Integer> {
|
|||
|
||||
private void checkStart() {
|
||||
try {
|
||||
if (BeaconServer.isRunning()) {
|
||||
if (BeaconServer.isReachable()) {
|
||||
try (var con = new LauncherConnection()) {
|
||||
con.constructSocket();
|
||||
con.performSimpleExchange(FocusExchange.Request.builder().mode(getEffectiveMode()).build());
|
||||
|
@ -87,19 +89,18 @@ public class LauncherCommand implements Callable<Integer> {
|
|||
TrackEvent.info("Another instance is already running on this port. Quitting ...");
|
||||
OperationMode.halt(1);
|
||||
}
|
||||
|
||||
// Even in case we are unable to reach another beacon server
|
||||
// there might be another instance running, for example
|
||||
// starting up or listening on another port
|
||||
if (!AppDataLock.lock()) {
|
||||
throw new IOException("Data directory " + AppProperties.get().getDataDir().toString() + " is already locked");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
var cli = XPipeInstallation.getLocalDefaultCliExecutable();
|
||||
ErrorEvent.fromThrowable(ex).description("Unable to connect to existing running daemon instance as it did not respond." +
|
||||
ErrorEvent.fromThrowable(ex).term().description("Unable to connect to existing running daemon instance as it did not respond." +
|
||||
" Either try to kill the process xpiped manually or use the command " + cli + " daemon stop --force.").handle();
|
||||
}
|
||||
|
||||
// Even in case we are unable to reach another beacon server
|
||||
// there might be another instance running, for example
|
||||
// starting up or listening on another port
|
||||
if (!AppDataLock.lock()) {
|
||||
TrackEvent.info("Data directory is already locked. Quitting ...");
|
||||
OperationMode.halt(1);
|
||||
}
|
||||
}
|
||||
|
||||
private XPipeDaemonMode getEffectiveMode() {
|
||||
|
|
|
@ -9,7 +9,7 @@ public class LauncherConnection extends BeaconConnection {
|
|||
@Override
|
||||
protected void constructSocket() {
|
||||
try {
|
||||
beaconClient = BeaconClient.connect(
|
||||
beaconClient = BeaconClient.establishConnection(
|
||||
BeaconClient.DaemonInformation.builder().build());
|
||||
} catch (Exception ex) {
|
||||
throw new BeaconException("Unable to connect to running xpipe daemon", ex);
|
||||
|
|
|
@ -48,12 +48,17 @@ public class BeaconClient implements AutoCloseable {
|
|||
this.out = out;
|
||||
}
|
||||
|
||||
public static BeaconClient connect(ClientInformation information) throws Exception {
|
||||
public static BeaconClient establishConnection(ClientInformation information) throws Exception {
|
||||
var socket = new Socket();
|
||||
socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), BeaconConfig.getUsedPort()), 5000);
|
||||
socket.setSoTimeout(5000);
|
||||
var client = new BeaconClient(socket, socket.getInputStream(), socket.getOutputStream());
|
||||
client.sendObject(JacksonMapper.getDefault().valueToTree(information));
|
||||
var res = client.receiveObject();
|
||||
if (!res.isTextual() || !"ACK".equals(res.asText())) {
|
||||
throw new BeaconException("Daemon responded with invalid acknowledgement");
|
||||
}
|
||||
socket.setSoTimeout(0);
|
||||
return client;
|
||||
}
|
||||
|
||||
|
@ -102,9 +107,9 @@ public class BeaconClient implements AutoCloseable {
|
|||
};
|
||||
}
|
||||
|
||||
public static Optional<BeaconClient> tryConnect(ClientInformation information) {
|
||||
public static Optional<BeaconClient> tryEstablishConnection(ClientInformation information) {
|
||||
try {
|
||||
return Optional.of(connect(information));
|
||||
return Optional.of(establishConnection(information));
|
||||
} catch (Exception ex) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -190,6 +195,10 @@ public class BeaconClient implements AutoCloseable {
|
|||
}
|
||||
|
||||
public <T extends ResponseMessage> T receiveResponse() throws ConnectorException, ClientException, ServerException {
|
||||
return parseResponse(receiveObject());
|
||||
}
|
||||
|
||||
private JsonNode receiveObject() throws ConnectorException, ClientException, ServerException {
|
||||
JsonNode node;
|
||||
try (InputStream blockIn = BeaconFormat.readBlocks(in)) {
|
||||
node = JacksonMapper.getDefault().readTree(blockIn);
|
||||
|
@ -216,7 +225,7 @@ public class BeaconClient implements AutoCloseable {
|
|||
throw ce.get().throwException();
|
||||
}
|
||||
|
||||
return parseResponse(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
private Optional<ClientErrorMessage> parseClientError(JsonNode node) throws ConnectorException {
|
||||
|
@ -305,18 +314,6 @@ public class BeaconClient implements AutoCloseable {
|
|||
}
|
||||
}
|
||||
|
||||
@JsonTypeName("reachableCheck")
|
||||
@Value
|
||||
@Builder
|
||||
@Jacksonized
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public static class ReachableCheckInformation extends ClientInformation {
|
||||
|
||||
@Override
|
||||
public String toDisplayString() {
|
||||
return "Reachable check";
|
||||
}
|
||||
}
|
||||
|
||||
@JsonTypeName("daemon")
|
||||
@Value
|
||||
|
|
|
@ -10,7 +10,7 @@ public class BeaconDaemonController {
|
|||
private static boolean alreadyStarted;
|
||||
|
||||
public static void start(XPipeDaemonMode mode) throws Exception {
|
||||
if (BeaconServer.isRunning()) {
|
||||
if (BeaconServer.isReachable()) {
|
||||
alreadyStarted = true;
|
||||
return;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class BeaconDaemonController {
|
|||
}
|
||||
|
||||
waitForStartup(process, custom);
|
||||
if (!BeaconServer.isRunning()) {
|
||||
if (!BeaconServer.isReachable()) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
@ -35,11 +35,11 @@ public class BeaconDaemonController {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!BeaconServer.isRunning()) {
|
||||
if (!BeaconServer.isReachable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var client = BeaconClient.connect(BeaconClient.ApiClientInformation.builder()
|
||||
var client = BeaconClient.establishConnection(BeaconClient.ApiClientInformation.builder()
|
||||
.version("?")
|
||||
.language("Java API Test")
|
||||
.build());
|
||||
|
@ -65,7 +65,7 @@ public class BeaconDaemonController {
|
|||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
var s = BeaconClient.tryConnect(BeaconClient.ApiClientInformation.builder()
|
||||
var s = BeaconClient.tryEstablishConnection(BeaconClient.ApiClientInformation.builder()
|
||||
.version("?")
|
||||
.language("Java")
|
||||
.build());
|
||||
|
@ -84,7 +84,7 @@ public class BeaconDaemonController {
|
|||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
var r = BeaconServer.isRunning();
|
||||
var r = BeaconServer.isReachable();
|
||||
if (!r) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ public class BeaconJacksonModule extends SimpleModule {
|
|||
context.registerSubtypes(
|
||||
new NamedType(BeaconClient.ApiClientInformation.class),
|
||||
new NamedType(BeaconClient.CliClientInformation.class),
|
||||
new NamedType(BeaconClient.DaemonInformation.class),
|
||||
new NamedType(BeaconClient.ReachableCheckInformation.class));
|
||||
new NamedType(BeaconClient.DaemonInformation.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ import io.xpipe.core.util.XPipeInstallation;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -15,9 +18,9 @@ import java.util.List;
|
|||
*/
|
||||
public class BeaconServer {
|
||||
|
||||
public static boolean isRunning() {
|
||||
try (var ignored = BeaconClient.connect(
|
||||
BeaconClient.ReachableCheckInformation.builder().build())) {
|
||||
public static boolean isReachable() {
|
||||
try (var socket = new Socket()) {
|
||||
socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), BeaconConfig.getUsedPort()), 5000);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue