From fae6bff6fbf268193b87d0da2d7814d115da4ae3 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Mon, 6 Jun 2022 07:34:03 -0400 Subject: [PATCH] Remove all manual uses of v8 serialization (#5548) * Remove all manual uses of v8 serialization - Seems that sometimes the is a versioning mismatch within the binary format causes cluster screen the go grey Signed-off-by: Sebastian Malton * handle ping Signed-off-by: Sebastian Malton --- src/common/terminal/channels.ts | 31 +++++++++++++++++ src/main/helm/helm-chart-manager.ts | 7 ++-- .../node-shell-session/node-shell-session.ts | 2 +- src/main/shell-session/shell-session.ts | 19 ++++++----- src/renderer/api/terminal-api.ts | 34 +++---------------- src/renderer/api/websocket-api.ts | 11 +++--- .../dock/terminal/send-command.injectable.ts | 2 +- .../components/dock/terminal/terminal.ts | 2 +- 8 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 src/common/terminal/channels.ts diff --git a/src/common/terminal/channels.ts b/src/common/terminal/channels.ts new file mode 100644 index 0000000000..f958c9c696 --- /dev/null +++ b/src/common/terminal/channels.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + + +export enum TerminalChannels { + STDIN = "stdin", + STDOUT = "stdout", + CONNECTED = "connected", + RESIZE = "resize", + PING = "ping", +} + +export type TerminalMessage = { + type: TerminalChannels.STDIN; + data: string; +} | { + type: TerminalChannels.STDOUT; + data: string; +} | { + type: TerminalChannels.CONNECTED; +} | { + type: TerminalChannels.RESIZE; + data: { + width: number; + height: number; + }; +} | { + type: TerminalChannels.PING; +}; diff --git a/src/main/helm/helm-chart-manager.ts b/src/main/helm/helm-chart-manager.ts index 1f12bba051..981c8602e8 100644 --- a/src/main/helm/helm-chart-manager.ts +++ b/src/main/helm/helm-chart-manager.ts @@ -4,7 +4,6 @@ */ import fs from "fs"; -import v8 from "v8"; import * as yaml from "js-yaml"; import type { HelmRepo } from "./helm-repo-manager"; import logger from "../logger"; @@ -15,7 +14,7 @@ import type { SetRequired } from "type-fest"; import { assert } from "console"; interface ChartCacheEntry { - data: Buffer; + data: string; // serialized JSON mtimeMs: number; } @@ -88,7 +87,7 @@ export class HelmChartManager { HelmChartManager.#cache, this.repo.name, { - data: v8.serialize(normalized), + data: JSON.stringify(normalized), mtimeMs: cacheFileStats.mtimeMs, }, ); @@ -107,7 +106,7 @@ export class HelmChartManager { } } - return v8.deserialize(cacheEntry.data); + return JSON.parse(cacheEntry.data); } } diff --git a/src/main/shell-session/node-shell-session/node-shell-session.ts b/src/main/shell-session/node-shell-session/node-shell-session.ts index b37e8c25b5..4c619a612c 100644 --- a/src/main/shell-session/node-shell-session/node-shell-session.ts +++ b/src/main/shell-session/node-shell-session/node-shell-session.ts @@ -13,8 +13,8 @@ import { get, once } from "lodash"; import { Node, NodeApi } from "../../../common/k8s-api/endpoints"; import { KubeJsonApi } from "../../../common/k8s-api/kube-json-api"; import logger from "../../logger"; -import { TerminalChannels } from "../../../renderer/api/terminal-api"; import type { Kubectl } from "../../kubectl/kubectl"; +import { TerminalChannels } from "../../../common/terminal/channels"; export class NodeShellSession extends ShellSession { ShellType = "node-shell"; diff --git a/src/main/shell-session/shell-session.ts b/src/main/shell-session/shell-session.ts index 59827b2314..42286ee24d 100644 --- a/src/main/shell-session/shell-session.ts +++ b/src/main/shell-session/shell-session.ts @@ -16,11 +16,9 @@ import { UserStore } from "../../common/user-store"; import * as pty from "node-pty"; import { appEventBus } from "../../common/app-event-bus/event-bus"; import logger from "../logger"; -import type { TerminalMessage } from "../../renderer/api/terminal-api"; -import { TerminalChannels } from "../../renderer/api/terminal-api"; -import { deserialize, serialize } from "v8"; import { stat } from "fs/promises"; import { getOrInsertWith } from "../../common/utils"; +import { type TerminalMessage, TerminalChannels } from "../../common/terminal/channels"; export class ShellOpenError extends Error { constructor(message: string, options?: ErrorOptions) { @@ -161,7 +159,7 @@ export abstract class ShellSession { } protected send(message: TerminalMessage): void { - this.websocket.send(serialize(message)); + this.websocket.send(JSON.stringify(message)); } protected async getCwd(env: Record): Promise { @@ -232,17 +230,19 @@ export abstract class ShellSession { }); this.websocket - .on("message", (data: string | Uint8Array): void => { + .on("message", (rawData: unknown): void => { if (!this.running) { return void logger.debug(`[SHELL-SESSION]: received message from ${this.terminalId}, but shellProcess isn't running`); } - if (typeof data === "string") { - return void logger.silly(`[SHELL-SESSION]: Received message from ${this.terminalId}`, { data }); + if (!(rawData instanceof Buffer)) { + return void logger.error(`[SHELL-SESSION]: Received message non-buffer message.`, { rawData }); } + const data = rawData.toString(); + try { - const message: TerminalMessage = deserialize(data); + const message: TerminalMessage = JSON.parse(data); switch (message.type) { case TerminalChannels.STDIN: @@ -251,6 +251,9 @@ export abstract class ShellSession { case TerminalChannels.RESIZE: shellProcess.resize(message.data.width, message.data.height); break; + case TerminalChannels.PING: + logger.silly(`[SHELL-SESSION]: ${this.terminalId} ping!`); + break; default: logger.warn(`[SHELL-SESSION]: unknown or unhandleable message type for ${this.terminalId}`, message); break; diff --git a/src/renderer/api/terminal-api.ts b/src/renderer/api/terminal-api.ts index 2e41b2f69d..75d907616c 100644 --- a/src/renderer/api/terminal-api.ts +++ b/src/renderer/api/terminal-api.ts @@ -10,31 +10,8 @@ import url from "url"; import { makeObservable, observable } from "mobx"; import { ipcRenderer } from "electron"; import logger from "../../common/logger"; -import { deserialize, serialize } from "v8"; import { once } from "lodash"; - -export enum TerminalChannels { - STDIN = "stdin", - STDOUT = "stdout", - CONNECTED = "connected", - RESIZE = "resize", -} - -export type TerminalMessage = { - type: TerminalChannels.STDIN; - data: string; -} | { - type: TerminalChannels.STDOUT; - data: string; -} | { - type: TerminalChannels.CONNECTED; -} | { - type: TerminalChannels.RESIZE; - data: { - width: number; - height: number; - }; -}; +import { type TerminalMessage, TerminalChannels } from "../../common/terminal/channels"; enum TerminalColor { RED = "\u001b[31m", @@ -133,13 +110,10 @@ export class TerminalApi extends WebSocketApi { this.prependListener("connected", onReady); super.connect(socketUrl); - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.socket!.binaryType = "arraybuffer"; } sendMessage(message: TerminalMessage) { - return this.send(serialize(message)); + return this.send(JSON.stringify(message)); } sendTerminalSize(cols: number, rows: number) { @@ -154,9 +128,9 @@ export class TerminalApi extends WebSocketApi { } } - protected _onMessage({ data, ...evt }: MessageEvent): void { + protected _onMessage({ data, ...evt }: MessageEvent): void { try { - const message: TerminalMessage = deserialize(new Uint8Array(data)); + const message = JSON.parse(data) as TerminalMessage; switch (message.type) { case TerminalChannels.STDOUT: diff --git a/src/renderer/api/websocket-api.ts b/src/renderer/api/websocket-api.ts index 8a7072ec78..748fef5e7b 100644 --- a/src/renderer/api/websocket-api.ts +++ b/src/renderer/api/websocket-api.ts @@ -9,6 +9,7 @@ import type TypedEventEmitter from "typed-emitter"; import type { Arguments } from "typed-emitter"; import { isDevelopment } from "../../common/vars"; import type { Defaulted } from "../utils"; +import { TerminalChannels, type TerminalMessage } from "../../common/terminal/channels"; interface WebsocketApiParams { /** @@ -30,9 +31,9 @@ interface WebsocketApiParams { /** * The message for pinging the websocket * - * @default "PING" + * @default "{type: \"ping\"}" */ - pingMessage?: string | ArrayBufferLike | Blob | ArrayBufferView; + pingMessage?: string; /** * If set to a number > 0, then the API will ping the socket on that interval. @@ -65,7 +66,7 @@ export interface WebSocketEvents { export class WebSocketApi extends (EventEmitter as { new(): TypedEventEmitter }) { protected socket: WebSocket | null = null; - protected pendingCommands: (string | ArrayBufferLike | Blob | ArrayBufferView)[] = []; + protected pendingCommands: string[] = []; protected reconnectTimer?: number; protected pingTimer?: number; protected params: Defaulted; @@ -76,7 +77,7 @@ export class WebSocketApi extends (EventEmitter logging: isDevelopment, reconnectDelay: 10, flushOnOpen: true, - pingMessage: "PING", + pingMessage: JSON.stringify({ type: TerminalChannels.PING } as TerminalMessage), }; constructor(params: WebsocketApiParams) { @@ -149,7 +150,7 @@ export class WebSocketApi extends (EventEmitter } } - send(command: string | ArrayBufferLike | Blob | ArrayBufferView) { + send(command: string) { if (this.getIsConnected()) { this.socket.send(command); } else { diff --git a/src/renderer/components/dock/terminal/send-command.injectable.ts b/src/renderer/components/dock/terminal/send-command.injectable.ts index 19de24e1ce..7580059daa 100644 --- a/src/renderer/components/dock/terminal/send-command.injectable.ts +++ b/src/renderer/components/dock/terminal/send-command.injectable.ts @@ -4,9 +4,9 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { when } from "mobx"; +import { TerminalChannels } from "../../../../common/terminal/channels"; import { waitUntilDefined } from "../../../../common/utils/wait"; import type { TerminalApi } from "../../../api/terminal-api"; -import { TerminalChannels } from "../../../api/terminal-api"; import { noop } from "../../../utils"; import { Notifications } from "../../notifications"; import selectDockTabInjectable from "../dock/select-dock-tab.injectable"; diff --git a/src/renderer/components/dock/terminal/terminal.ts b/src/renderer/components/dock/terminal/terminal.ts index fa93c68c79..f4819f332b 100644 --- a/src/renderer/components/dock/terminal/terminal.ts +++ b/src/renderer/components/dock/terminal/terminal.ts @@ -10,7 +10,6 @@ import { Terminal as XTerm } from "xterm"; import { FitAddon } from "xterm-addon-fit"; import type { TabId } from "../dock/store"; import type { TerminalApi } from "../../../api/terminal-api"; -import { TerminalChannels } from "../../../api/terminal-api"; import type { ThemeStore } from "../../../themes/store"; import { disposer } from "../../../utils"; import { isMac } from "../../../../common/vars"; @@ -19,6 +18,7 @@ import { clipboard } from "electron"; import logger from "../../../../common/logger"; import type { TerminalConfig } from "../../../../common/user-store/preferences-helpers"; import assert from "assert"; +import { TerminalChannels } from "../../../../common/terminal/channels"; export interface TerminalDependencies { readonly spawningPool: HTMLElement;