提交 36bf392f 编写于 作者: M Matt Bierner

Make standard tunnel service re-use tunnels when possible

上级 9bc37621
......@@ -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;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册