make it an abstract transport

This commit is contained in:
Simon Knott 2024-08-23 13:12:08 +02:00
parent 8ca1f63b07
commit 0f37e55eec
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
3 changed files with 53 additions and 21 deletions

View file

@ -19,16 +19,48 @@ import * as events from './events';
// -- Reuse boundary -- Everything below this line is reused in the vscode extension.
export interface TestServerSocket {
addEventListener(type: 'message', listener: (event: { data: string }) => void): void;
addEventListener(type: 'open', listener: () => void): void;
addEventListener(type: 'error', listener: () => void): void;
addEventListener(type: 'close', listener: () => void): void;
export interface TestServerTransport {
onmessage(listener: (message: string) => void): void;
onopen(listener: () => void): void;
onerror(listener: () => void): void;
onclose(listener: () => void): void;
send(data: string): void;
close(): void;
}
export class WebSocketTestServerTransport implements TestServerTransport {
private _ws: WebSocket;
constructor(url: URL) {
this._ws = new WebSocket(url);
}
onmessage(listener: (message: string) => void) {
this._ws.addEventListener('message', event => listener(event.data));
}
onopen(listener: () => void) {
this._ws.addEventListener('open', listener);
}
onerror(listener: () => void) {
this._ws.addEventListener('error', listener);
}
onclose(listener: () => void) {
this._ws.addEventListener('close', listener);
}
send(data: string) {
this._ws.send(data);
}
close() {
this._ws.close();
}
}
export class TestServerConnection implements TestServerInterface, TestServerInterfaceEvents {
readonly onClose: events.Event<void>;
readonly onReport: events.Event<any>;
@ -43,21 +75,21 @@ export class TestServerConnection implements TestServerInterface, TestServerInte
private _onLoadTraceRequestedEmitter = new events.EventEmitter<{ traceUrl: string }>();
private _lastId = 0;
private _socket: TestServerSocket;
private _transport: TestServerTransport;
private _callbacks = new Map<number, { resolve: (arg: any) => void, reject: (arg: Error) => void }>();
private _connectedPromise: Promise<void>;
private _isClosed = false;
constructor(socket: TestServerSocket) {
constructor(transport: TestServerTransport) {
this.onClose = this._onCloseEmitter.event;
this.onReport = this._onReportEmitter.event;
this.onStdio = this._onStdioEmitter.event;
this.onTestFilesChanged = this._onTestFilesChangedEmitter.event;
this.onLoadTraceRequested = this._onLoadTraceRequestedEmitter.event;
this._socket = socket;
this._socket.addEventListener('message', event => {
const message = JSON.parse(String(event.data));
this._transport = transport;
this._transport.onmessage(data => {
const message = JSON.parse(data);
const { id, result, error, method, params } = message;
if (id) {
const callback = this._callbacks.get(id);
@ -72,12 +104,12 @@ export class TestServerConnection implements TestServerInterface, TestServerInte
this._dispatchEvent(method, params);
}
});
const pingInterval = setInterval(() => this._sendMessage('ping').catch(() => {}), 30000);
const pingInterval = setInterval(() => this._sendMessage('ping').catch(() => { }), 30000);
this._connectedPromise = new Promise<void>((f, r) => {
this._socket.addEventListener('open', () => f());
this._socket.addEventListener('error', r);
this._transport.onopen(f);
this._transport.onerror(r);
});
this._socket.addEventListener('close', () => {
this._transport.onclose(() => {
this._isClosed = true;
this._onCloseEmitter.fire();
clearInterval(pingInterval);
@ -95,14 +127,14 @@ export class TestServerConnection implements TestServerInterface, TestServerInte
await this._connectedPromise;
const id = ++this._lastId;
const message = { id, method, params };
this._socket.send(JSON.stringify(message));
this._transport.send(JSON.stringify(message));
return new Promise((resolve, reject) => {
this._callbacks.set(id, { resolve, reject });
});
}
private _sendMessageNoReply(method: string, params?: any) {
this._sendMessage(method, params).catch(() => {});
this._sendMessage(method, params).catch(() => { });
}
private _dispatchEvent(method: string, params?: any) {
@ -210,7 +242,7 @@ export class TestServerConnection implements TestServerInterface, TestServerInte
close() {
try {
this._socket.close();
this._transport.close();
} catch {
}
}

View file

@ -33,7 +33,7 @@ import { useDarkModeSetting } from '@web/theme';
import { clsx, settings, useSetting } from '@web/uiUtils';
import { statusEx, TestTree } from '@testIsomorphic/testTree';
import type { TreeItem } from '@testIsomorphic/testTree';
import { TestServerConnection } from '@testIsomorphic/testServerConnection';
import { TestServerConnection, WebSocketTestServerTransport } from '@testIsomorphic/testServerConnection';
import { pathSeparator } from './uiModeModel';
import type { TestModel } from './uiModeModel';
import { FiltersView } from './uiModeFiltersView';
@ -135,7 +135,7 @@ export const UIModeView: React.FC<{}> = ({
const inputRef = React.useRef<HTMLInputElement>(null);
const reloadTests = React.useCallback(() => {
setTestServerConnection(new TestServerConnection(new WebSocket(wsURL)));
setTestServerConnection(new TestServerConnection(new WebSocketTestServerTransport(wsURL)));
}, []);
// Load tests on startup.

View file

@ -21,7 +21,7 @@ import { MultiTraceModel } from './modelUtil';
import './workbenchLoader.css';
import { toggleTheme } from '@web/theme';
import { Workbench } from './workbench';
import { TestServerConnection } from '@testIsomorphic/testServerConnection';
import { TestServerConnection, WebSocketTestServerTransport } from '@testIsomorphic/testServerConnection';
export const WorkbenchLoader: React.FunctionComponent<{
}> = () => {
@ -102,7 +102,7 @@ export const WorkbenchLoader: React.FunctionComponent<{
const guid = new URLSearchParams(window.location.search).get('ws');
const wsURL = new URL(`../${guid}`, window.location.toString());
wsURL.protocol = (window.location.protocol === 'https:' ? 'wss:' : 'ws:');
const testServerConnection = new TestServerConnection(new WebSocket(wsURL));
const testServerConnection = new TestServerConnection(new WebSocketTestServerTransport(wsURL));
testServerConnection.onLoadTraceRequested(async params => {
setTraceURLs(params.traceUrl ? [params.traceUrl] : []);
setDragOver(false);