Skip to content

Commit

Permalink
refactor: Transport into an abstract class
Browse files Browse the repository at this point in the history
Create parent destroy() and make sure 'close' always is emitted,
child classes implement their own _destroy() logic.
  • Loading branch information
fredriklindberg committed Sep 29, 2023
1 parent 2c50175 commit 2a22cbd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 42 deletions.
7 changes: 1 addition & 6 deletions src/transport/ssh/ssh-transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,8 @@ class SSHTransport extends Transport {
return sock;
}

async destroy() {
if (this.destroyed) {
return;
}
async _destroy() {
this._client.end();
this.destroyed = true;
this.emit('close');
return this._tunnelService.destroy();
}
}
Expand Down
19 changes: 0 additions & 19 deletions src/transport/transport.js

This file was deleted.

33 changes: 33 additions & 0 deletions src/transport/transport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { EventEmitter } from 'events';
import { Duplex } from 'stream';

export type TransportConnectionOptions = {
tunnelId?: string,
port?: number,
};

export interface TransportOptions {
max_connections?: number
}

export default abstract class Transport extends EventEmitter {
public readonly max_connections: number;
public destroyed: boolean = false;

constructor(opts: TransportOptions) {
super();
this.max_connections = opts.max_connections || 1;
}

public abstract createConnection(opts: TransportConnectionOptions, callback: (err: Error | undefined, sock: Duplex) => void): Duplex;

protected abstract _destroy(): Promise<void>;

public async destroy(err?: Error): Promise<void> {
this.destroyed = true;
this._destroy();
this.emit('close', err);
this.removeAllListeners();
}

}
28 changes: 11 additions & 17 deletions src/transport/ws/ws-transport.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import WebSocket from 'ws';
import Transport from '../transport.js';
import Transport, { TransportOptions } from '../transport.js';
import { WebSocketMultiplex } from '@exposr/ws-multiplex';
import { Duplex } from 'stream';

export type WebSocketTransportOptions = {
export type WebSocketTransportOptions = TransportOptions & {
tunnelId: string,
max_connections: number,
socket: WebSocket,
};

export default class WebSocketTransport extends Transport {
private wsm: WebSocketMultiplex;
private destroyed: boolean = false;

constructor(options: WebSocketTransportOptions) {
super({
Expand All @@ -22,25 +20,21 @@ export default class WebSocketTransport extends Transport {
reference: options.tunnelId
});

this.wsm.on('error', (err: Error) => {
this._destroy(err);
this.wsm.once('error', (err: Error) => {
this.destroy(err);
});
}

public createConnection(opts: object = {}, callback: (err: Error | undefined, sock: Duplex) => void): any {
return this.wsm.createConnection({}, callback);
this.wsm.once('close', () => {
this.destroy();
});
}

public async destroy(): Promise<void> {
return this._destroy();
public createConnection(opts: any = {}, callback: (err: Error | undefined, sock: Duplex) => void): Duplex {
return this.wsm.createConnection({}, callback);
}

private async _destroy(err?: Error): Promise<void> {
if (this.destroyed) {
return;
}
this.destroyed = true;
protected async _destroy(): Promise<void> {
this.wsm.removeAllListeners();
await this.wsm.destroy();
this.emit('close', err);
}
}

0 comments on commit 2a22cbd

Please sign in to comment.