diff --git a/nodel-framework/src/main/java/org/nodel/core/Nodel.java b/nodel-framework/src/main/java/org/nodel/core/Nodel.java index 5671e5d8..29083774 100644 --- a/nodel-framework/src/main/java/org/nodel/core/Nodel.java +++ b/nodel-framework/src/main/java/org/nodel/core/Nodel.java @@ -370,36 +370,7 @@ public static String[] getHTTPAddresses() { public static String[] getHTTPNodeAddress() { return s_httpNodeAddresses; } - - /** - * (see public getter / setter) - */ - private static int webSocketPort; - /** - * The WebSocket port for this environment. - */ - public static int getWebSocketPort() { - return webSocketPort; - } - - /** - * Sets the WebSocket port for this environment. - */ - public static void setWebSocketPort(int value) { - webSocketPort = value; - } - - public static String s_webSocketAddress; - - public static void updateWebSocketAddress(String webSocketAddress) { - s_webSocketAddress = webSocketAddress; - } - - public static String getWebSocketAddress() { - return s_webSocketAddress; - } - /** * The default HTTP suffix (e.g. '/nodes/%NODE%/') */ diff --git a/nodel-framework/src/main/java/org/nodel/diagnostics/Diagnostics.java b/nodel-framework/src/main/java/org/nodel/diagnostics/Diagnostics.java index 76ae4f40..2acd314f 100644 --- a/nodel-framework/src/main/java/org/nodel/diagnostics/Diagnostics.java +++ b/nodel-framework/src/main/java/org/nodel/diagnostics/Diagnostics.java @@ -187,12 +187,7 @@ public String hostname() { return "UNKNOWN"; } } - - @Value(name = "webSocketPort", title = "Web socket port") - public int webSocketPort() { - return Nodel.getWebSocketPort(); - } - + /** * Where this host is running from. */ diff --git a/nodel-framework/src/main/java/org/nodel/discovery/TopologyWatcher.java b/nodel-framework/src/main/java/org/nodel/discovery/TopologyWatcher.java index f5868d3c..18365bb7 100644 --- a/nodel-framework/src/main/java/org/nodel/discovery/TopologyWatcher.java +++ b/nodel-framework/src/main/java/org/nodel/discovery/TopologyWatcher.java @@ -130,6 +130,10 @@ public void removeOnChangeHandler(ChangeHandler handler) { synchronized (_removedOnChangeHandlers) { _removedOnChangeHandlers.add(handler); } + // in case of 'add' then immediate 'remove' + synchronized (_newOnChangeHandlers) { + _newOnChangeHandlers.remove(handler); + } } /** @@ -251,8 +255,10 @@ private void monitorInterfaces() { // remove previous handlers synchronized (_removedOnChangeHandlers) { if (_removedOnChangeHandlers.size() > 0) { - for (ChangeHandler handler : _removedOnChangeHandlers) + for (ChangeHandler handler : _removedOnChangeHandlers) { _onChangeHandlers.remove(handler); + } + _removedOnChangeHandlers.clear(); } } diff --git a/nodel-framework/src/main/java/org/nodel/host/BootstrapConfig.java b/nodel-framework/src/main/java/org/nodel/host/BootstrapConfig.java index 5dc76f25..06f3680a 100644 --- a/nodel-framework/src/main/java/org/nodel/host/BootstrapConfig.java +++ b/nodel-framework/src/main/java/org/nodel/host/BootstrapConfig.java @@ -50,22 +50,7 @@ public int getNodelHostPort() { public void setPyNodePort(int value) { this.nodelHostPort = value; } - - - public final static int DEFAULT_NODELHOST_WSPORT = 0; - - @Value(name = "NodelHostWSPort", title = "NodelHost websocket port", order = 200, required = true, desc = "(command-line arg '--wsPort')") - private int nodelHostWSPort = DEFAULT_NODELHOST_WSPORT; - - public int getNodelHostWSPort() { - return this.nodelHostWSPort; - } - public void setNodelHostWSPort(int value) { - this.nodelHostWSPort = value; - } - - public final static int DEFAULT_MESSAGING_PORT = 0; @Value(name = "messagingPort", title = "Messaging Port", order = 210, required = true, @@ -246,9 +231,6 @@ public void overrideWith(String[] args) { } else if ("-l".equals(arg) || "--enableProgramLogging".equalsIgnoreCase(arg)) { this.enableProgramLogging = true; - } else if ("--wsPort".equalsIgnoreCase(arg)) { - this.nodelHostWSPort = Integer.parseInt(nextArg); - } else if ("--contentDirectory".equalsIgnoreCase(arg)) { this.contentDirectory = nextArg; diff --git a/nodel-jyhost/_API_schema.json b/nodel-jyhost/_API_schema.json index 6cd539f7..6b30a2a7 100644 --- a/nodel-jyhost/_API_schema.json +++ b/nodel-jyhost/_API_schema.json @@ -1590,11 +1590,6 @@ "title": "VM arguments", "desc": "The arguments supplied to this instance of the VM.", "items": {"type": "object"} - }, - "webSocketPort": { - "type": "integer", - "required": true, - "title": "Web socket port" } }, "services": { diff --git a/nodel-jyhost/src/main/java/org/nodel/jyhost/Launch.java b/nodel-jyhost/src/main/java/org/nodel/jyhost/Launch.java index e5fce090..0bd19ce3 100644 --- a/nodel-jyhost/src/main/java/org/nodel/jyhost/Launch.java +++ b/nodel-jyhost/src/main/java/org/nodel/jyhost/Launch.java @@ -11,6 +11,7 @@ import java.io.InputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; +import java.net.BindException; import java.net.ServerSocket; import java.nio.channels.FileLock; @@ -309,12 +310,27 @@ private void start() throws IOException { // kick off the HTTPDs nodelHostHTTPD.start(); // throws exception if any + + // update with actual listening port + Nodel.setHTTPPort(nodelHostHTTPD.getListeningPort()); + } catch (Exception exc) { // port would be in use - + + // need to clear all registered callbacks + if (nodelHostHTTPD != null) { + nodelHostHTTPD.stop(); + nodelHostHTTPD = null; + } + // specific port was requested? - if (requestedPort > 0) - throw exc; + if (requestedPort > 0) { + if (exc instanceof BindException) + // provide instructive feedback if possible + throw new BindException("Cannot bind to TCP port " + requestedPort + "; another process must already be bound to the port; use '-p 0' if \"any port\" binding is preferred"); + else + throw exc; + } // try any port tryPort = 0; @@ -361,11 +377,6 @@ private void start() throws IOException { Stream.writeFully(versionFile, VERSION); } - // update with actual listening port - // Note: Socket binding happens later than expected due to a new NanoHTTPD. - Nodel.setHTTPPort(nodelHostHTTPD.getListeningPort()); - Nodel.setWebSocketPort(nodelHostHTTPD.getListeningPort()); - // stamp the cache if it's a different port if (lastHTTPPort != Nodel.getHTTPPort()) { Stream.writeFully(lastHTTPPortCache, String.valueOf(Nodel.getHTTPPort())); diff --git a/nodel-jyhost/src/main/java/org/nodel/jyhost/NodelHostHTTPD.java b/nodel-jyhost/src/main/java/org/nodel/jyhost/NodelHostHTTPD.java index b05eadfe..f833aa4a 100644 --- a/nodel-jyhost/src/main/java/org/nodel/jyhost/NodelHostHTTPD.java +++ b/nodel-jyhost/src/main/java/org/nodel/jyhost/NodelHostHTTPD.java @@ -188,19 +188,19 @@ public static class Info { * Holds the object bound to the REST layer */ private RESTModel _restModel = new RESTModel(); - + + private final TopologyWatcher.ChangeHandler _topologyWatcherChangeHandler = new TopologyWatcher.ChangeHandler() { + @Override + public void handle(List appeared, List disappeared) { + handleTopologyChange(appeared, disappeared); + } + }; + public NodelHostHTTPD(int port, File directory) throws IOException { super(port, directory, false); // and watch for future interface changes - TopologyWatcher.shared().addOnChangeHandler(new TopologyWatcher.ChangeHandler() { - - @Override - public void handle(List appeared, List disappeared) { - handleTopologyChange(appeared, disappeared); - } - - }); + TopologyWatcher.shared().addOnChangeHandler(_topologyWatcherChangeHandler); // do more things init(); @@ -235,6 +235,14 @@ private void init() { addHTTPInterceptor(wsInterceptor); } + @Override + public void stop() { + super.stop(); + if (_topologyWatcherChangeHandler != null) { + TopologyWatcher.shared().removeOnChangeHandler(_topologyWatcherChangeHandler); + } + } + /** * Sets the host. */ diff --git a/nodel-jyhost/src/main/java/org/nodel/jyhost/PyNode.java b/nodel-jyhost/src/main/java/org/nodel/jyhost/PyNode.java index de16a9f9..188e4bf2 100644 --- a/nodel-jyhost/src/main/java/org/nodel/jyhost/PyNode.java +++ b/nodel-jyhost/src/main/java/org/nodel/jyhost/PyNode.java @@ -137,13 +137,7 @@ public class PyNode extends BaseDynamicNode { * The general purpose toolkit related to this node. */ protected ManagedToolkit _toolkit; - - /** - * Holds the web-socket port - */ - @Value(name = "webSocketPort", title = "WebSocket port", order = 10000) - private int webSocketPort = Nodel.getWebSocketPort(); - + /** * (init. in constructor) */