mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-19 22:59:48 +01:00
Make standard tunnel service re-use tunnels when possible
This commit is contained in:
@@ -88,12 +88,20 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel {
|
||||
export class TunnelService implements ITunnelService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private readonly _tunnels = new Map</* port */ number, { refcount: number, readonly value: Promise<RemoteTunnel> }>();
|
||||
|
||||
public constructor(
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IRemoteAuthorityResolverService private readonly remoteAuthorityResolverService: IRemoteAuthorityResolverService,
|
||||
@ISignService private readonly signService: ISignService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) {
|
||||
@ILogService private readonly logService: ILogService,
|
||||
) { }
|
||||
|
||||
dispose(): void {
|
||||
for (const { value } of this._tunnels.values()) {
|
||||
value.then(tunnel => tunnel.dispose());
|
||||
}
|
||||
this._tunnels.clear();
|
||||
}
|
||||
|
||||
openTunnel(remotePort: number): Promise<RemoteTunnel> | undefined {
|
||||
@@ -102,6 +110,33 @@ export class TunnelService implements ITunnelService {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const resolvedTunnel = this.retainOrCreateTunnel(remoteAuthority, remotePort);
|
||||
if (!resolvedTunnel) {
|
||||
return resolvedTunnel;
|
||||
}
|
||||
|
||||
return resolvedTunnel.then(tunnel => ({
|
||||
tunnelRemotePort: tunnel.tunnelRemotePort,
|
||||
tunnelLocalPort: tunnel.tunnelLocalPort,
|
||||
dispose: () => {
|
||||
const existing = this._tunnels.get(remotePort);
|
||||
if (existing) {
|
||||
if (--existing.refcount <= 0) {
|
||||
existing.value.then(tunnel => tunnel.dispose());
|
||||
this._tunnels.delete(remotePort);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private retainOrCreateTunnel(remoteAuthority: string, remotePort: number): Promise<RemoteTunnel> | undefined {
|
||||
const existing = this._tunnels.get(remotePort);
|
||||
if (existing) {
|
||||
++existing.refcount;
|
||||
return existing.value;
|
||||
}
|
||||
|
||||
const options: IConnectionOptions = {
|
||||
commit: product.commit,
|
||||
socketFactory: nodeSocketFactory,
|
||||
@@ -114,7 +149,10 @@ export class TunnelService implements ITunnelService {
|
||||
signService: this.signService,
|
||||
logService: this.logService
|
||||
};
|
||||
return createRemoteTunnel(options, remotePort);
|
||||
|
||||
const tunnel = createRemoteTunnel(options, remotePort);
|
||||
this._tunnels.set(remotePort, { refcount: 1, value: tunnel });
|
||||
return tunnel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user