提交 8374d6a4 编写于 作者: A Alex Ross

Detect ports to forward more often

Part of microsoft/vscode-remote-release#4021
上级 71fce013
......@@ -47,8 +47,8 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
});
}
async $registerCandidateFinder(): Promise<void> {
this.remoteExplorerService.registerCandidateFinder(() => this._proxy.$findCandidatePorts());
async $onFoundNewCandidates(candidates: { host: string, port: number, detail: string }[]): Promise<void> {
this.remoteExplorerService.onFoundNewCandidates(candidates);
}
async $tunnelServiceReady(): Promise<void> {
......@@ -78,22 +78,6 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
this.tunnelService.setTunnelProvider(tunnelProvider);
}
async $setCandidateFilter(): Promise<void> {
this._register(this.remoteExplorerService.setCandidateFilter(async (candidates: { host: string, port: number, detail: string }[]): Promise<{ host: string, port: number, detail: string }[]> => {
const filters: boolean[] = await this._proxy.$filterCandidates(candidates);
const filteredCandidates: { host: string, port: number, detail: string }[] = [];
if (filters.length !== candidates.length) {
return candidates;
}
for (let i = 0; i < candidates.length; i++) {
if (filters[i]) {
filteredCandidates.push(candidates[i]);
}
}
return filteredCandidates;
}));
}
dispose(): void {
}
......
......@@ -949,10 +949,9 @@ export interface MainThreadTunnelServiceShape extends IDisposable {
$openTunnel(tunnelOptions: TunnelOptions): Promise<TunnelDto | undefined>;
$closeTunnel(remote: { host: string, port: number }): Promise<void>;
$getTunnels(): Promise<TunnelDescription[]>;
$registerCandidateFinder(): Promise<void>;
$setTunnelProvider(): Promise<void>;
$setCandidateFilter(): Promise<void>;
$tunnelServiceReady(): Promise<void>;
$onFoundNewCandidates(candidates: { host: string, port: number, detail: string }[]): Promise<void>;
}
export interface MainThreadTimelineShape extends IDisposable {
......@@ -1742,8 +1741,6 @@ export interface MainThreadThemingShape extends IDisposable {
}
export interface ExtHostTunnelServiceShape {
$findCandidatePorts(): Promise<{ host: string, port: number, detail: string }[]>;
$filterCandidates(candidates: { host: string, port: number, detail: string }[]): Promise<boolean[]>;
$forwardPort(tunnelOptions: TunnelOptions): Promise<TunnelDto> | undefined;
$closeTunnel(remote: { host: string, port: number }, silent?: boolean): Promise<void>;
$onDidTunnelsChange(): Promise<void>;
......
......@@ -57,12 +57,6 @@ export class ExtHostTunnelService implements IExtHostTunnelService {
async getTunnels(): Promise<vscode.TunnelDescription[]> {
return [];
}
async $findCandidatePorts(): Promise<{ host: string, port: number; detail: string; }[]> {
return [];
}
async $filterCandidates(candidates: { host: string, port: number, detail: string }[]): Promise<boolean[]> {
return candidates.map(() => true);
}
async setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> {
await this._proxy.$tunnelServiceReady();
return { dispose: () => { } };
......
......@@ -69,21 +69,25 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
return this._proxy.$getTunnels();
}
registerCandidateFinder(): Promise<void> {
return this._proxy.$registerCandidateFinder();
}
$filterCandidates(candidates: { host: string, port: number, detail: string }[]): Promise<boolean[]> {
return Promise.all(candidates.map(candidate => {
return this._showCandidatePort(candidate.host, candidate.port, candidate.detail);
}));
registerCandidateFinder(): void {
// Every two seconds, scan to see if the candidate ports have changed;
if (isLinux) {
let oldPorts: { host: string, port: number, detail: string }[] | undefined = undefined;
setInterval(async () => {
const newPorts = await this.findCandidatePorts();
if (!oldPorts || (JSON.stringify(oldPorts) !== JSON.stringify(newPorts))) {
oldPorts = newPorts;
this._proxy.$onFoundNewCandidates(oldPorts.filter(async (candidate) => await this._showCandidatePort(candidate.host, candidate.port, candidate.detail)));
return;
}
}, 2000);
}
}
async setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> {
if (provider) {
if (provider.showCandidatePort) {
this._showCandidatePort = provider.showCandidatePort;
await this._proxy.$setCandidateFilter();
}
if (provider.tunnelFactory) {
this._forwardPortProvider = provider.tunnelFactory;
......@@ -133,11 +137,7 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
}
async $findCandidatePorts(): Promise<{ host: string, port: number, detail: string }[]> {
if (!isLinux) {
return [];
}
async findCandidatePorts(): Promise<{ host: string, port: number, detail: string }[]> {
const ports: { host: string, port: number, detail: string }[] = [];
let tcp: string = '';
let tcp6: string = '';
......
......@@ -936,18 +936,6 @@ namespace CopyAddressAction {
}
}
namespace RefreshTunnelViewAction {
export const ID = 'remote.tunnel.refresh';
export const LABEL = nls.localize('remote.tunnel.refreshView', "Refresh");
export function handler(): ICommandHandler {
return (accessor, arg) => {
const remoteExplorerService = accessor.get(IRemoteExplorerService);
return remoteExplorerService.refresh();
};
}
}
namespace ChangeLocalPortAction {
export const ID = 'remote.tunnel.changeLocalPort';
export const LABEL = nls.localize('remote.tunnel.changeLocalPort', "Change Local Port");
......@@ -1022,7 +1010,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
handler: CopyAddressAction.inlineHandler()
});
CommandsRegistry.registerCommand(CopyAddressAction.COMMANDPALETTE_ID, CopyAddressAction.commandPaletteHandler());
CommandsRegistry.registerCommand(RefreshTunnelViewAction.ID, RefreshTunnelViewAction.handler());
CommandsRegistry.registerCommand(ChangeLocalPortAction.ID, ChangeLocalPortAction.handler());
MenuRegistry.appendMenuItem(MenuId.CommandPalette, ({
......@@ -1055,15 +1042,6 @@ MenuRegistry.appendMenuItem(MenuId.TunnelTitle, ({
icon: { id: 'codicon/plus' }
}
}));
MenuRegistry.appendMenuItem(MenuId.TunnelTitle, ({
group: 'navigation',
order: 1,
command: {
id: RefreshTunnelViewAction.ID,
title: RefreshTunnelViewAction.LABEL,
icon: { id: 'codicon/refresh' }
}
}));
MenuRegistry.appendMenuItem(MenuId.TunnelContext, ({
group: '0_manage',
order: 0,
......@@ -1109,15 +1087,6 @@ MenuRegistry.appendMenuItem(MenuId.TunnelContext, ({
},
when: ContextKeyExpr.or(TunnelTypeContextKey.isEqualTo(TunnelType.Candidate), TunnelTypeContextKey.isEqualTo(TunnelType.Add))
}));
MenuRegistry.appendMenuItem(MenuId.TunnelContext, ({
group: '0_manage',
order: 2,
command: {
id: RefreshTunnelViewAction.ID,
title: RefreshTunnelViewAction.LABEL,
},
when: TunnelTypeContextKey.isEqualTo(TunnelType.Candidate)
}));
MenuRegistry.appendMenuItem(MenuId.TunnelContext, ({
group: '1_manage',
order: 1,
......
......@@ -90,7 +90,6 @@ export class TunnelModel extends Disposable {
private _onPortName: Emitter<{ host: string, port: number }> = new Emitter();
public onPortName: Event<{ host: string, port: number }> = this._onPortName.event;
private _candidates: { host: string, port: number, detail: string }[] = [];
private _candidateFinder: (() => Promise<{ host: string, port: number, detail: string }[]>) | undefined;
private _onCandidatesChanged: Emitter<void> = new Emitter();
public onCandidatesChanged: Event<void> = this._onCandidatesChanged.event;
private _candidateFilter: ((candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>) | undefined;
......@@ -217,40 +216,29 @@ export class TunnelModel extends Disposable {
this._onForwardPort.fire();
}
registerCandidateFinder(finder: () => Promise<{ host: string, port: number, detail: string }[]>): void {
this._candidateFinder = finder;
this._onCandidatesChanged.fire();
}
setCandidateFilter(filter: ((candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>) | undefined): void {
this._candidateFilter = filter;
}
get candidates(): Promise<{ host: string, port: number, detail: string }[]> {
return this.updateCandidates().then(() => this._candidates);
}
private async updateCandidates(): Promise<void> {
if (this._candidateFinder) {
let candidates = await this._candidateFinder();
if (this._candidateFilter && (candidates.length > 0)) {
candidates = await this._candidateFilter(candidates);
}
this._candidates = candidates.map(value => {
const nullIndex = value.detail.indexOf('\0');
const detail = value.detail.substr(0, nullIndex > 0 ? nullIndex : value.detail.length).trim();
return {
host: value.host,
port: value.port,
detail
};
});
async setCandidates(candidates: { host: string, port: number, detail: string }[]) {
let processedCandidates = candidates;
if (this._candidateFilter) {
processedCandidates = await this._candidateFilter(candidates);
}
this._candidates = processedCandidates.map(value => {
const nullIndex = value.detail.indexOf('\0');
const detail = value.detail.substr(0, nullIndex > 0 ? nullIndex : value.detail.length).trim();
return {
host: value.host,
port: value.port,
detail
};
});
this._onCandidatesChanged.fire();
}
async refresh(): Promise<void> {
await this.updateCandidates();
this._onCandidatesChanged.fire();
get candidates(): { host: string, port: number, detail: string }[] {
return this._candidates;
}
}
......@@ -265,9 +253,8 @@ export interface IRemoteExplorerService {
forward(remote: { host: string, port: number }, localPort?: number, name?: string): Promise<RemoteTunnel | void>;
close(remote: { host: string, port: number }): Promise<void>;
setTunnelInformation(tunnelInformation: TunnelInformation | undefined): void;
registerCandidateFinder(finder: () => Promise<{ host: string, port: number, detail: string }[]>): void;
setCandidateFilter(filter: ((candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>) | undefined): IDisposable;
refresh(): Promise<void>;
onFoundNewCandidates(candidates: { host: string, port: number, detail: string }[]): void;
restore(): Promise<void>;
}
......@@ -340,10 +327,6 @@ class RemoteExplorerService implements IRemoteExplorerService {
this._editable.data : undefined;
}
registerCandidateFinder(finder: () => Promise<{ host: string, port: number, detail: string }[]>): void {
this.tunnelModel.registerCandidateFinder(finder);
}
setCandidateFilter(filter: (candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>): IDisposable {
if (!filter) {
return {
......@@ -358,8 +341,8 @@ class RemoteExplorerService implements IRemoteExplorerService {
};
}
refresh(): Promise<void> {
return this.tunnelModel.refresh();
onFoundNewCandidates(candidates: { host: string, port: number, detail: string }[]): void {
this.tunnelModel.setCandidates(candidates);
}
restore(): Promise<void> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册