From 44a2aff38e00227f6ba1c64e7bf9bb1c7cf10781 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 8 Jan 2024 12:51:17 -0500 Subject: [PATCH] Restart server on general settings change --- .../dataflow/DataChangeDestination.java | 1 + .../common/networking/NetworkManager.java | 12 ++++++ .../src/main/java/org/photonvision/Main.java | 2 +- .../server/DataSocketHandler.java | 11 +++-- .../java/org/photonvision/server/Server.java | 43 ++++++++++++++++++- 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/photon-core/src/main/java/org/photonvision/common/dataflow/DataChangeDestination.java b/photon-core/src/main/java/org/photonvision/common/dataflow/DataChangeDestination.java index 16a69dfe4f..c342be7cc0 100644 --- a/photon-core/src/main/java/org/photonvision/common/dataflow/DataChangeDestination.java +++ b/photon-core/src/main/java/org/photonvision/common/dataflow/DataChangeDestination.java @@ -26,6 +26,7 @@ public enum DataChangeDestination { DCD_ACTIVEPIPELINESETTINGS, DCD_GENSETTINGS, DCD_UI, + DCD_WEBSERVER, DCD_OTHER; public static final List AllDestinations = diff --git a/photon-core/src/main/java/org/photonvision/common/networking/NetworkManager.java b/photon-core/src/main/java/org/photonvision/common/networking/NetworkManager.java index 3268b73296..0ce9b169c5 100644 --- a/photon-core/src/main/java/org/photonvision/common/networking/NetworkManager.java +++ b/photon-core/src/main/java/org/photonvision/common/networking/NetworkManager.java @@ -19,6 +19,10 @@ import org.photonvision.common.configuration.ConfigManager; import org.photonvision.common.configuration.NetworkConfig; +import org.photonvision.common.dataflow.DataChangeDestination; +import org.photonvision.common.dataflow.DataChangeService; +import org.photonvision.common.dataflow.DataChangeSource; +import org.photonvision.common.dataflow.events.DataChangeEvent; import org.photonvision.common.hardware.Platform; import org.photonvision.common.logging.LogGroup; import org.photonvision.common.logging.Logger; @@ -148,5 +152,13 @@ public void initialize(boolean shouldManage) { public void reinitialize() { initialize(ConfigManager.getInstance().getConfig().getNetworkConfig().shouldManage()); + + DataChangeService.getInstance() + .publishEvent( + new DataChangeEvent( + DataChangeSource.DCS_OTHER, + DataChangeDestination.DCD_WEBSERVER, + "restartServer", + true)); } } diff --git a/photon-server/src/main/java/org/photonvision/Main.java b/photon-server/src/main/java/org/photonvision/Main.java index 65921ec02c..e7db45c1f2 100644 --- a/photon-server/src/main/java/org/photonvision/Main.java +++ b/photon-server/src/main/java/org/photonvision/Main.java @@ -385,6 +385,6 @@ public static void main(String[] args) { logger.info("Starting server..."); HardwareManager.getInstance().setRunning(true); - Server.start(DEFAULT_WEBPORT); + Server.initialize(DEFAULT_WEBPORT); } } diff --git a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java index 9fe6189f45..4282bd332d 100644 --- a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java @@ -82,9 +82,14 @@ public void onConnect(WsConnectContext context) { protected void onClose(WsCloseContext context) { users.remove(context); var remote = (InetSocketAddress) context.session.getRemoteAddress(); - var host = remote.getAddress().toString() + ":" + remote.getPort(); - var reason = context.reason() != null ? context.reason() : "Connection closed by client"; - logger.info("Closing websocket connection from " + host + " for reason: " + reason); + // Remote can be null if server is being closed for restart + if (remote != null) { + var host = remote.getAddress().toString() + ":" + remote.getPort(); + var reason = context.reason() != null ? context.reason() : "Connection closed by client"; + logger.info("Closing websocket connection from " + host + " for reason: " + reason); + } else { + logger.info("Closing websockets for user " + context.getSessionId()); + } } @SuppressWarnings({"unchecked"}) diff --git a/photon-server/src/main/java/org/photonvision/server/Server.java b/photon-server/src/main/java/org/photonvision/server/Server.java index a393c880e9..f78d80d3cb 100644 --- a/photon-server/src/main/java/org/photonvision/server/Server.java +++ b/photon-server/src/main/java/org/photonvision/server/Server.java @@ -20,15 +20,42 @@ import io.javalin.Javalin; import io.javalin.plugin.bundled.CorsPluginConfig; import java.net.InetSocketAddress; +import java.util.List; import java.util.StringJoiner; +import org.photonvision.common.dataflow.DataChangeDestination; +import org.photonvision.common.dataflow.DataChangeService; +import org.photonvision.common.dataflow.DataChangeSource; +import org.photonvision.common.dataflow.DataChangeSubscriber; +import org.photonvision.common.dataflow.events.DataChangeEvent; import org.photonvision.common.logging.LogGroup; import org.photonvision.common.logging.Logger; public class Server { private static final Logger logger = new Logger(Server.class, LogGroup.WebServer); - public static void start(int port) { - var app = + private static Javalin app = null; + + static class RestartSubscriber extends DataChangeSubscriber { + private RestartSubscriber() { + super(DataChangeSource.AllSources, List.of(DataChangeDestination.DCD_WEBSERVER)); + } + + @Override + public void onDataChangeEvent(DataChangeEvent event) { + if (event.propertyName.equals("restartServer")) { + Server.restart(); + } + } + } + + public static void initialize(int port) { + DataChangeService.getInstance().addSubscriber(new RestartSubscriber()); + + start(port); + } + + private static void start(int port) { + app = Javalin.create( javalinConfig -> { javalinConfig.showJavalinBanner = false; @@ -111,5 +138,17 @@ public static void start(int port) { app.post("/api/calibration/importFromData", RequestHandler::onDataCalibrationImportRequest); app.start(port); + System.out.println("hi"); + } + + /** + * Seems like if we change the static IP of this device, Javalin refuses to tell us when new + * Websocket clients connect. As a hack, we can restart the server every time we change static IPs + */ + public static void restart() { + logger.info("Web server going down for restart"); + int oldPort = app.port(); + app.stop(); + start(oldPort); } }