Tunnel session rework

This commit is contained in:
crschnick
2025-05-30 16:42:46 +00:00
parent 914fd6be37
commit ccc7188e9b
20 changed files with 107 additions and 68 deletions

View File

@@ -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;

View File

@@ -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.*;

View File

@@ -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;

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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();
}
}

View File

@@ -1,4 +1,4 @@
package io.xpipe.core.store;
package io.xpipe.app.ext;
public interface SessionListener {

View File

@@ -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<ShellControl> supplier;
private final ShellControl shellControl;
public ShellSession(SessionListener listener, FailableSupplier<ShellControl> supplier) throws Exception {
super(listener);
public ShellSession(FailableSupplier<ShellControl> 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();
}
}

View File

@@ -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

View File

@@ -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<T extends Session>
extends ExpandedLifecycleStore, InternalCacheDataStore, SessionListener {
@@ -51,6 +54,9 @@ public interface SingletonSessionStore<T extends Session>
setSessionEnabled(true);
s = newSession();
if (s != null) {
s.addListener(running -> {
onStateChange(running);
});
s.start();
setCache("session", s);
onStateChange(true);

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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<ServiceControl
@Override
public ServiceControlSession newSession() {
return new ServiceControlSession(running -> {}, this);
return new ServiceControlSession(this);
}
@Override