feat(smart-proxy): add socket-handler relay, fast-path port-only forwarding, metrics and bridge improvements, and various TS/Rust integration fixes
This commit is contained in:
@@ -37,6 +37,7 @@ export class SmartProxy extends plugins.EventEmitter {
|
||||
private socketHandlerServer: SocketHandlerServer | null = null;
|
||||
private metricsAdapter: RustMetricsAdapter;
|
||||
private routeUpdateLock: Mutex;
|
||||
private stopping = false;
|
||||
|
||||
constructor(settingsArg: ISmartProxyOptions) {
|
||||
super();
|
||||
@@ -102,7 +103,10 @@ export class SmartProxy extends plugins.EventEmitter {
|
||||
|
||||
this.bridge = new RustProxyBridge();
|
||||
this.preprocessor = new RoutePreprocessor();
|
||||
this.metricsAdapter = new RustMetricsAdapter(this.bridge);
|
||||
this.metricsAdapter = new RustMetricsAdapter(
|
||||
this.bridge,
|
||||
this.settings.metrics?.sampleIntervalMs ?? 1000
|
||||
);
|
||||
this.routeUpdateLock = new Mutex();
|
||||
}
|
||||
|
||||
@@ -120,23 +124,24 @@ export class SmartProxy extends plugins.EventEmitter {
|
||||
);
|
||||
}
|
||||
|
||||
// Handle unexpected exit
|
||||
// Handle unexpected exit (only emits error if not intentionally stopping)
|
||||
this.bridge.on('exit', (code: number | null, signal: string | null) => {
|
||||
if (this.stopping) return;
|
||||
logger.log('error', `RustProxy exited unexpectedly (code=${code}, signal=${signal})`, { component: 'smart-proxy' });
|
||||
this.emit('error', new Error(`RustProxy exited (code=${code}, signal=${signal})`));
|
||||
});
|
||||
|
||||
// Start socket handler relay if any routes need TS-side handling
|
||||
// Check if any routes need TS-side handling (socket handlers, dynamic functions)
|
||||
const hasHandlerRoutes = this.settings.routes.some(
|
||||
(r) =>
|
||||
(r.action.type === 'socket-handler' && r.action.socketHandler) ||
|
||||
r.action.targets?.some((t) => typeof t.host === 'function' || typeof t.port === 'function')
|
||||
);
|
||||
|
||||
// Start socket handler relay server (but don't tell Rust yet - proxy not started)
|
||||
if (hasHandlerRoutes) {
|
||||
this.socketHandlerServer = new SocketHandlerServer(this.preprocessor);
|
||||
await this.socketHandlerServer.start();
|
||||
await this.bridge.setSocketHandlerRelay(this.socketHandlerServer.getSocketPath());
|
||||
}
|
||||
|
||||
// Preprocess routes (strip JS functions, convert socket-handler routes)
|
||||
@@ -148,6 +153,11 @@ export class SmartProxy extends plugins.EventEmitter {
|
||||
// Start the Rust proxy
|
||||
await this.bridge.startProxy(config);
|
||||
|
||||
// Now that Rust proxy is running, configure socket handler relay
|
||||
if (this.socketHandlerServer) {
|
||||
await this.bridge.setSocketHandlerRelay(this.socketHandlerServer.getSocketPath());
|
||||
}
|
||||
|
||||
// Handle certProvisionFunction
|
||||
await this.provisionCertificatesViaCallback();
|
||||
|
||||
@@ -162,10 +172,14 @@ export class SmartProxy extends plugins.EventEmitter {
|
||||
*/
|
||||
public async stop(): Promise<void> {
|
||||
logger.log('info', 'SmartProxy shutting down...', { component: 'smart-proxy' });
|
||||
this.stopping = true;
|
||||
|
||||
// Stop metrics polling
|
||||
this.metricsAdapter.stopPolling();
|
||||
|
||||
// Remove exit listener before killing to avoid spurious error events
|
||||
this.bridge.removeAllListeners('exit');
|
||||
|
||||
// Stop Rust proxy
|
||||
try {
|
||||
await this.bridge.stopProxy();
|
||||
@@ -283,6 +297,7 @@ export class SmartProxy extends plugins.EventEmitter {
|
||||
* Get all currently listening ports (async - calls Rust).
|
||||
*/
|
||||
public async getListeningPorts(): Promise<number[]> {
|
||||
if (!this.bridge.running) return [];
|
||||
return this.bridge.getListeningPorts();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user