mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-04-22 23:49:09 -04:00
Tunnel session rework
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
@@ -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 {
|
||||
|
||||
59
app/src/main/java/io/xpipe/app/ext/Session.java
Normal file
59
app/src/main/java/io/xpipe/app/ext/Session.java
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.core.store;
|
||||
package io.xpipe.app.ext;
|
||||
|
||||
public interface SessionListener {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user