diff --git a/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionToggleExchangeImpl.java b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionToggleExchangeImpl.java index 6025ce0eb..9377ec9db 100644 --- a/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionToggleExchangeImpl.java +++ b/app/src/main/java/io/xpipe/app/beacon/impl/ConnectionToggleExchangeImpl.java @@ -3,7 +3,7 @@ package io.xpipe.app.beacon.impl; import io.xpipe.app.storage.DataStorage; import io.xpipe.beacon.BeaconClientException; import io.xpipe.beacon.api.ConnectionToggleExchange; -import io.xpipe.core.store.SingletonSessionStore; +import io.xpipe.app.ext.SingletonSessionStore; import com.sun.net.httpserver.HttpExchange; diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java index 58fafac38..bd3e20bc6 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java @@ -12,7 +12,7 @@ import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.PlatformThread; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.SingletonSessionStore; +import io.xpipe.app.ext.SingletonSessionStore; import javafx.beans.binding.Bindings; import javafx.beans.property.*; diff --git a/app/src/main/java/io/xpipe/app/ext/LocalStore.java b/app/src/main/java/io/xpipe/app/ext/LocalStore.java index 9120280e6..fd5f4bf79 100644 --- a/app/src/main/java/io/xpipe/app/ext/LocalStore.java +++ b/app/src/main/java/io/xpipe/app/ext/LocalStore.java @@ -3,8 +3,6 @@ package io.xpipe.app.ext; import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.ShellStoreState; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.NetworkTunnelSession; -import io.xpipe.core.store.NetworkTunnelStore; import io.xpipe.core.store.StatefulDataStore; import com.fasterxml.jackson.annotation.JsonTypeName; diff --git a/core/src/main/java/io/xpipe/core/store/NetworkTunnelSession.java b/app/src/main/java/io/xpipe/app/ext/NetworkTunnelSession.java similarity index 66% rename from core/src/main/java/io/xpipe/core/store/NetworkTunnelSession.java rename to app/src/main/java/io/xpipe/app/ext/NetworkTunnelSession.java index d0bdd46b0..9e1ca06cf 100644 --- a/core/src/main/java/io/xpipe/core/store/NetworkTunnelSession.java +++ b/app/src/main/java/io/xpipe/app/ext/NetworkTunnelSession.java @@ -1,13 +1,9 @@ -package io.xpipe.core.store; +package io.xpipe.app.ext; import io.xpipe.core.process.ShellControl; public abstract class NetworkTunnelSession extends Session { - protected NetworkTunnelSession(SessionListener listener) { - super(listener); - } - public abstract int getLocalPort(); public abstract int getRemotePort(); diff --git a/core/src/main/java/io/xpipe/core/store/NetworkTunnelStore.java b/app/src/main/java/io/xpipe/app/ext/NetworkTunnelStore.java similarity index 91% rename from core/src/main/java/io/xpipe/core/store/NetworkTunnelStore.java rename to app/src/main/java/io/xpipe/app/ext/NetworkTunnelStore.java index 1e6317df1..09ca48a12 100644 --- a/core/src/main/java/io/xpipe/core/store/NetworkTunnelStore.java +++ b/app/src/main/java/io/xpipe/app/ext/NetworkTunnelStore.java @@ -1,4 +1,6 @@ -package io.xpipe.core.store; +package io.xpipe.app.ext; + +import io.xpipe.core.store.DataStore; public interface NetworkTunnelStore extends DataStore { diff --git a/app/src/main/java/io/xpipe/app/ext/Session.java b/app/src/main/java/io/xpipe/app/ext/Session.java new file mode 100644 index 000000000..b3152d1f0 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/ext/Session.java @@ -0,0 +1,59 @@ +package io.xpipe.app.ext; + +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.GlobalTimer; +import io.xpipe.app.util.ThreadHelper; + +import java.time.Duration; + +public abstract class Session implements AutoCloseable { + + protected SessionListener listener = running -> {}; + + public synchronized void addListener(SessionListener n) { + var current = this.listener; + this.listener = running -> { + current.onStateChange(running); + n.onStateChange(running); + }; + } + + protected void startAliveListener() { + GlobalTimer.scheduleUntil(Duration.ofMillis(5000), () -> { + if (!isRunning()) { + return true; + } + + ThreadHelper.runAsync(() -> { + try { + var r = checkAlive(); + if (r) { + return; + } + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + } + + try { + stop(); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + } + }); + return false; + }); + } + + public abstract boolean isRunning(); + + public abstract void start() throws Exception; + + public abstract void stop() throws Exception; + + public abstract boolean checkAlive() throws Exception; + + @Override + public void close() throws Exception { + stop(); + } +} diff --git a/core/src/main/java/io/xpipe/core/store/SessionListener.java b/app/src/main/java/io/xpipe/app/ext/SessionListener.java similarity index 73% rename from core/src/main/java/io/xpipe/core/store/SessionListener.java rename to app/src/main/java/io/xpipe/app/ext/SessionListener.java index 45e241e1a..08db9516d 100644 --- a/core/src/main/java/io/xpipe/core/store/SessionListener.java +++ b/app/src/main/java/io/xpipe/app/ext/SessionListener.java @@ -1,4 +1,4 @@ -package io.xpipe.core.store; +package io.xpipe.app.ext; public interface SessionListener { diff --git a/app/src/main/java/io/xpipe/app/ext/ShellSession.java b/app/src/main/java/io/xpipe/app/ext/ShellSession.java index 91d519426..683d66e80 100644 --- a/app/src/main/java/io/xpipe/app/ext/ShellSession.java +++ b/app/src/main/java/io/xpipe/app/ext/ShellSession.java @@ -1,8 +1,7 @@ package io.xpipe.app.ext; +import io.xpipe.core.process.CommandBuilder; import io.xpipe.core.process.ShellControl; -import io.xpipe.core.store.Session; -import io.xpipe.core.store.SessionListener; import io.xpipe.core.util.FailableSupplier; import lombok.Getter; @@ -13,8 +12,7 @@ public class ShellSession extends Session { private final FailableSupplier supplier; private final ShellControl shellControl; - public ShellSession(SessionListener listener, FailableSupplier supplier) throws Exception { - super(listener); + public ShellSession(FailableSupplier supplier) throws Exception { this.supplier = supplier; this.shellControl = createControl(); } @@ -28,6 +26,7 @@ public class ShellSession extends Session { try { shellControl.start(); + startAliveListener(); } catch (Exception ex) { try { stop(); @@ -56,6 +55,9 @@ public class ShellSession extends Session { listener.onStateChange(false); }); }); + pc.onExit(shellControl -> { + listener.onStateChange(false); + }); return pc; } @@ -66,4 +68,9 @@ public class ShellSession extends Session { public void stop() throws Exception { shellControl.shutdown(); } + + @Override + public boolean checkAlive() throws Exception { + return shellControl.command(CommandBuilder.of().add("echo", "xpipetest")).executeAndCheck(); + } } diff --git a/app/src/main/java/io/xpipe/app/ext/ShellStore.java b/app/src/main/java/io/xpipe/app/ext/ShellStore.java index 199eb971b..f315efbbd 100644 --- a/app/src/main/java/io/xpipe/app/ext/ShellStore.java +++ b/app/src/main/java/io/xpipe/app/ext/ShellStore.java @@ -1,6 +1,5 @@ package io.xpipe.app.ext; -import io.xpipe.app.core.AppProperties; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.StubShellControl; @@ -66,7 +65,9 @@ public interface ShellStore extends DataStore, FileSystemStore, ValidatableStore default ShellSession newSession() throws Exception { var func = shellFunction(); var c = func.control(); - return new ShellSession(this, () -> c); + var session = new ShellSession(() -> c); + session.addListener(this); + return session; } @Override diff --git a/core/src/main/java/io/xpipe/core/store/SingletonSessionStore.java b/app/src/main/java/io/xpipe/app/ext/SingletonSessionStore.java similarity index 89% rename from core/src/main/java/io/xpipe/core/store/SingletonSessionStore.java rename to app/src/main/java/io/xpipe/app/ext/SingletonSessionStore.java index 00b15054d..7d8c24569 100644 --- a/core/src/main/java/io/xpipe/core/store/SingletonSessionStore.java +++ b/app/src/main/java/io/xpipe/app/ext/SingletonSessionStore.java @@ -1,4 +1,7 @@ -package io.xpipe.core.store; +package io.xpipe.app.ext; + +import io.xpipe.core.store.ExpandedLifecycleStore; +import io.xpipe.core.store.InternalCacheDataStore; public interface SingletonSessionStore extends ExpandedLifecycleStore, InternalCacheDataStore, SessionListener { @@ -51,6 +54,9 @@ public interface SingletonSessionStore setSessionEnabled(true); s = newSession(); if (s != null) { + s.addListener(running -> { + onStateChange(running); + }); s.start(); setCache("session", s); onStateChange(true); diff --git a/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java index de8f06777..fcd808091 100644 --- a/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/SingletonSessionStoreProvider.java @@ -4,7 +4,6 @@ import io.xpipe.app.comp.Comp; import io.xpipe.app.comp.store.*; import io.xpipe.app.util.LabelGraphic; import io.xpipe.app.util.ThreadHelper; -import io.xpipe.core.store.SingletonSessionStore; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; diff --git a/core/src/main/java/io/xpipe/core/store/Session.java b/core/src/main/java/io/xpipe/core/store/Session.java deleted file mode 100644 index 0351a49d2..000000000 --- a/core/src/main/java/io/xpipe/core/store/Session.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.xpipe.core.store; - -public abstract class Session implements AutoCloseable { - - protected SessionListener listener; - - protected Session(SessionListener listener) { - this.listener = listener; - } - - public void addListener(SessionListener n) { - var current = this.listener; - this.listener = running -> { - current.onStateChange(running); - n.onStateChange(running); - }; - } - - public abstract boolean isRunning() throws Exception; - - public abstract void start() throws Exception; - - public abstract void stop() throws Exception; - - @Override - public void close() throws Exception { - stop(); - } -} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java index e522684f4..3b17b7f19 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java @@ -6,9 +6,9 @@ import io.xpipe.app.util.HostHelper; import io.xpipe.app.util.LicenseProvider; import io.xpipe.app.util.Validators; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.NetworkTunnelSession; -import io.xpipe.core.store.NetworkTunnelStore; -import io.xpipe.core.store.SingletonSessionStore; +import io.xpipe.app.ext.NetworkTunnelSession; +import io.xpipe.app.ext.NetworkTunnelStore; +import io.xpipe.app.ext.SingletonSessionStore; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java index 2e1eb75cc..24549a0fb 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java @@ -1,7 +1,7 @@ package io.xpipe.ext.base.service; import io.xpipe.app.storage.DataStoreEntryRef; -import io.xpipe.core.store.NetworkTunnelStore; +import io.xpipe.app.ext.NetworkTunnelStore; import com.fasterxml.jackson.annotation.JsonTypeName; import lombok.EqualsAndHashCode; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java index e0a96902b..bdb9ce96b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java @@ -8,7 +8,7 @@ import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.NetworkTunnelStore; +import io.xpipe.app.ext.NetworkTunnelStore; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java index 146483068..0246e299f 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java @@ -4,7 +4,7 @@ import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.Validators; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.FixedChildStore; -import io.xpipe.core.store.NetworkTunnelStore; +import io.xpipe.app.ext.NetworkTunnelStore; import com.fasterxml.jackson.annotation.JsonTypeName; import lombok.EqualsAndHashCode; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java index f5b27aeaf..74b75e440 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java @@ -7,7 +7,7 @@ import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.NetworkTunnelStore; +import io.xpipe.app.ext.NetworkTunnelStore; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java index 807654798..edd4fff3d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java @@ -7,7 +7,7 @@ import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.NetworkTunnelStore; +import io.xpipe.app.ext.NetworkTunnelStore; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlSession.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlSession.java index 92a369015..8c9c3e638 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlSession.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlSession.java @@ -2,8 +2,8 @@ package io.xpipe.ext.base.service; import io.xpipe.core.process.CommandBuilder; import io.xpipe.core.process.ElevationFunction; -import io.xpipe.core.store.Session; -import io.xpipe.core.store.SessionListener; +import io.xpipe.app.ext.Session; +import io.xpipe.app.ext.SessionListener; import lombok.Getter; @@ -12,8 +12,7 @@ public class ServiceControlSession extends Session { private final ServiceControlStore store; - protected ServiceControlSession(SessionListener listener, ServiceControlStore store) { - super(listener); + protected ServiceControlSession(ServiceControlStore store) { this.store = store; } @@ -34,12 +33,8 @@ public class ServiceControlSession extends Session { listener.onStateChange(true); } - public boolean isRunning() throws Exception { - var session = store.getHost().getStore().getOrStartSession(); - var r = session.command(store.getStatusScript()) - .elevated(elevationFunction()) - .executeAndCheck(); - return r; + public boolean isRunning() { + return true; } public void stop() throws Exception { @@ -52,4 +47,9 @@ public class ServiceControlSession extends Session { session.command(store.getStopScript()).elevated(elevationFunction()).execute(); listener.onStateChange(false); } + + @Override + public boolean checkAlive() throws Exception { + return true; + } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStore.java index 2dc2a3a2a..b124ac5b5 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStore.java @@ -5,7 +5,7 @@ import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.Validators; import io.xpipe.core.process.ShellScript; import io.xpipe.core.store.DataStore; -import io.xpipe.core.store.SingletonSessionStore; +import io.xpipe.app.ext.SingletonSessionStore; import com.fasterxml.jackson.annotation.JsonTypeName; import lombok.Value; @@ -34,7 +34,7 @@ public class ServiceControlStore implements SingletonSessionStore {}, this); + return new ServiceControlSession(this); } @Override