Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions web/packages/teleterm/src/services/pty/fixtures/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,30 @@ export class MockPtyProcess implements IPtyProcess {

dispose() {}

onData() {}
onData() {
return () => {};
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it so that all on(Event) functions return cleanup functions, even though we call the cleanup functions only for a few of them.


I know that we discussed returning cleanup functions under the cleanup key of an object, but I'm still not sure about this approach. In my opinion it makes the function definition a little bit more noisy. Besides, what else would an onEvent function return? Usually they return void, so having a convention where they instead return a cleanup function instead makes sense to me.


onExit() {}
onExit() {
return () => {};
}

onOpen() {}
onOpen() {
return () => {};
}

onStartError() {
return () => {};
}

getPid() {
return 0;
}

getPtyId() {
return '1234';
}

async getCwd() {
return '';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

import { ClientDuplexStream } from '@grpc/grpc-js';

import Logger from 'teleterm/logger';

import {
PtyClientEvent,
PtyEventData,
Expand All @@ -25,15 +27,22 @@ import {
} from 'teleterm/sharedProcess/ptyHost';

export class PtyEventsStreamHandler {
private logger: Logger;

constructor(
private readonly stream: ClientDuplexStream<PtyClientEvent, PtyServerEvent>
) {}
private readonly stream: ClientDuplexStream<PtyClientEvent, PtyServerEvent>,
ptyId: string
) {
this.logger = new Logger(`PtyEventsStreamHandler ${ptyId}`);
}

/**
* Client -> Server stream events
*/

start(columns: number, rows: number): void {
this.logger.info('Start');

this.writeOrThrow(
new PtyClientEvent().setStart(
new PtyEventStart().setColumns(columns).setRows(rows)
Expand All @@ -56,6 +65,8 @@ export class PtyEventsStreamHandler {
}

dispose(): void {
this.logger.info('Dispose');

this.stream.end();
this.stream.removeAllListeners();
}
Expand All @@ -64,30 +75,51 @@ export class PtyEventsStreamHandler {
* Stream -> Client stream events
*/

onOpen(callback: () => void): void {
this.stream.addListener('data', (event: PtyServerEvent) => {
if (event.hasOpen()) {
callback();
onOpen(callback: () => void): RemoveListenerFunction {
return this.addDataListenerAndReturnRemovalFunction(
(event: PtyServerEvent) => {
if (event.hasOpen()) {
callback();
}
}
});
);
}

onData(callback: (data: string) => void): void {
this.stream.addListener('data', (event: PtyServerEvent) => {
if (event.hasData()) {
callback(event.getData().getMessage());
onData(callback: (data: string) => void): RemoveListenerFunction {
return this.addDataListenerAndReturnRemovalFunction(
(event: PtyServerEvent) => {
if (event.hasData()) {
callback(event.getData().getMessage());
}
}
});
);
}

onExit(
callback: (reason: { exitCode: number; signal?: number }) => void
): void {
this.stream.addListener('data', (event: PtyServerEvent) => {
if (event.hasExit()) {
callback(event.getExit().toObject());
): RemoveListenerFunction {
return this.addDataListenerAndReturnRemovalFunction(
(event: PtyServerEvent) => {
if (event.hasExit()) {
this.logger.info('On exit', event.getExit().toObject());
callback(event.getExit().toObject());
}
}
});
);
}

onStartError(callback: (message: string) => void): RemoveListenerFunction {
return this.addDataListenerAndReturnRemovalFunction(
(event: PtyServerEvent) => {
if (event.hasStartError()) {
this.logger.info(
'On start error',
event.getStartError().toObject().message
);
callback(event.getStartError().toObject().message);
}
}
);
}

private writeOrThrow(event: PtyClientEvent) {
Expand All @@ -97,4 +129,16 @@ export class PtyEventsStreamHandler {
}
});
}

private addDataListenerAndReturnRemovalFunction(
callback: (event: PtyServerEvent) => void
) {
this.stream.addListener('data', callback);

return () => {
this.stream.removeListener('data', callback);
};
}
}

type RemoveListenerFunction = () => void;
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function createPtyHostClient(
const metadata = new Metadata();
metadata.set('ptyId', ptyId);
const stream = client.exchangeEvents(metadata);
return new PtyEventsStreamHandler(stream);
return new PtyEventsStreamHandler(stream, ptyId);
},
};
}
22 changes: 14 additions & 8 deletions web/packages/teleterm/src/services/pty/ptyHost/ptyProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export function createPtyProcess(
const exchangeEventsStream = ptyHostClient.exchangeEvents(ptyId);

return {
getPtyId() {
return ptyId;
},

/**
* Client -> Server stream events
*/
Expand All @@ -49,18 +53,20 @@ export function createPtyProcess(
* Server -> Client stream events
*/

onData(callback: (data: string) => void): void {
exchangeEventsStream.onData(callback);
onData(callback: (data: string) => void) {
return exchangeEventsStream.onData(callback);
},

onOpen(callback: () => void) {
return exchangeEventsStream.onOpen(callback);
},

onOpen(callback: () => void): void {
exchangeEventsStream.onOpen(callback);
onExit(callback: (reason: { exitCode: number; signal?: number }) => void) {
return exchangeEventsStream.onExit(callback);
},

onExit(
callback: (reason: { exitCode: number; signal?: number }) => void
): void {
exchangeEventsStream.onExit(callback);
onStartError(callback: (message: string) => void) {
return exchangeEventsStream.onStartError(callback);
},

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ message PtyServerEvent {
PtyEventData data = 2;
PtyEventOpen open = 3;
PtyEventExit exit = 4;
PtyEventStartError start_error = 5;
}
}

Expand All @@ -75,6 +76,10 @@ message PtyEventExit {
optional uint32 signal = 2;
}

message PtyEventStartError {
string message = 1;
}

message PtyCwd {
string cwd = 1;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading