Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Servers console performance improvements #3007

Merged
merged 59 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
79c5588
feat: init selecting paper+purpur on purchase flow
ferothefox Nov 13, 2024
b3ba796
feat: properly implement Paper/Purpur in Platform
ferothefox Nov 15, 2024
f4af06c
chore: correct wording
ferothefox Nov 15, 2024
e63a499
feat: redo platform modal
ferothefox Nov 15, 2024
0e65976
Switch to HCaptcha for Auth-related captchas (#2945)
Geometrically Nov 17, 2024
4a5c1b6
fix hcaptcha not loading
Geometrically Nov 17, 2024
0773f03
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 18, 2024
fee8cc2
fix: more robust loader dropdown logic
ferothefox Nov 18, 2024
ce5cc2a
fix: handle "not yet supported" install err
ferothefox Nov 18, 2024
e3f1bcf
chore: fix icon kerfuffles
ferothefox Nov 18, 2024
490b87e
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 19, 2024
1e07401
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 19, 2024
7a03e95
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 19, 2024
9bbd03e
chore: improve vanilla install modal title
ferothefox Nov 19, 2024
34e96a9
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 19, 2024
36d7791
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 20, 2024
452ab25
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 20, 2024
4bdab6b
fix: spacing
ferothefox Nov 21, 2024
8d2fbc5
feat: usePyroConsole store instead of passing a prop to prevent bulk …
thewander02 Nov 21, 2024
a0c0065
chore: improve no loader state
ferothefox Nov 21, 2024
974e641
fix: type error
ferothefox Nov 21, 2024
e496c5f
chore: adjust mod version modal title
ferothefox Nov 21, 2024
0a4343c
chore: adjust modpack warning copy
ferothefox Nov 21, 2024
56ddf9e
feat: vanilla empty state in content page
ferothefox Nov 21, 2024
fb073b9
chore: adjust copy
ferothefox Nov 21, 2024
244d6f2
chore: update icon
ferothefox Nov 21, 2024
23d2d1f
fix: loader type
ferothefox Nov 21, 2024
ddc5983
fix: loader type
ferothefox Nov 21, 2024
0b4e129
feat: always show dropdown if possible
ferothefox Nov 21, 2024
da8f0d8
chore: improve spacing
ferothefox Nov 21, 2024
d8ea1f2
chore: appear disabled
ferothefox Nov 21, 2024
ac1bc76
h
ferothefox Nov 21, 2024
69f2a84
chore: if reinstalling, show it on the modal title
ferothefox Nov 21, 2024
242f11c
feat: put it in the dropdown, they said
ferothefox Nov 21, 2024
6880184
chore: adjust style
ferothefox Nov 21, 2024
8982eeb
chore: sort paper-purpur versions desc
ferothefox Nov 21, 2024
9a33ad1
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 22, 2024
fb88bbf
Merge branch 'modrinth:main' into evan/mod-173-panel-terminal-perf
ferothefox Nov 22, 2024
63b97de
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 22, 2024
1f30077
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 25, 2024
e109b95
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 27, 2024
140f294
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Nov 27, 2024
a190f07
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Dec 7, 2024
e8a63e9
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Dec 7, 2024
17407a1
fix: do not consider backup limit in reinstall prompt
ferothefox Dec 8, 2024
fcd4d4f
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Dec 9, 2024
c7f903a
feat: backup locking, plugin support
thewander02 Dec 10, 2024
d8d60bc
fix: content type error
ferothefox Dec 10, 2024
5a96190
Merge branch 'modrinth:main' into evan/mod-172-paper-and-purpur-frontend
ferothefox Dec 10, 2024
23713fa
fix: casing
ferothefox Dec 10, 2024
4cc9622
fix: plugins pt 2
thewander02 Dec 10, 2024
5f6cc08
feat: backups, mrpack
thewander02 Dec 11, 2024
2dd9a18
fix: type errors come on
ferothefox Dec 11, 2024
33ad6ea
fix: spacing
ferothefox Dec 11, 2024
809a9e6
fix: type maxing
thewander02 Dec 11, 2024
52110b3
chore: show copy button on allocation rows
ferothefox Dec 11, 2024
153533a
feat: suspend improvement
thewander02 Dec 11, 2024
98188ae
Merge branch 'evan/mod-172-paper-and-purpur-frontend' into evan/mod-1…
ferothefox Dec 11, 2024
dd99c13
Merge branch 'modrinth:main' into evan/mod-173-panel-terminal-perf
ferothefox Dec 11, 2024
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
21 changes: 12 additions & 9 deletions apps/frontend/src/components/ui/servers/PanelTerminal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,18 @@
<script setup lang="ts">
import { RightArrowIcon } from "@modrinth/assets";
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue";
import { usePyroConsole } from "~/store/console.ts";

const { $cosmetics } = useNuxtApp();
const cosmetics = $cosmetics;

const props = defineProps<{
consoleOutput: string[];
fullScreen: boolean;
}>();

const pyroConsole = usePyroConsole();
const consoleOutput = pyroConsole.output;

const scrollContainer = ref<HTMLElement | null>(null);
const itemHeights = ref<number[]>([]);
const averageItemHeight = ref(36);
Expand All @@ -170,7 +173,7 @@ const handleScrollEvent = () => {
const totalHeight = computed(
() =>
itemHeights.value.reduce((sum, height) => sum + height, 0) ||
props.consoleOutput.length * averageItemHeight.value,
consoleOutput.value.length * averageItemHeight.value,
);

watch(totalHeight, () => {
Expand Down Expand Up @@ -223,7 +226,7 @@ const visibleStartIndex = computed(() => {
let index = 0;
let offset = 0;
while (
index < props.consoleOutput.length &&
index < consoleOutput.value.length &&
offset < scrollTop.value - bufferSize * averageItemHeight.value
) {
offset += itemHeights.value[index] || averageItemHeight.value;
Expand All @@ -236,17 +239,17 @@ const visibleEndIndex = computed(() => {
let index = visibleStartIndex.value;
let offset = getItemOffset(index);
while (
index < props.consoleOutput.length &&
index < consoleOutput.value.length &&
offset < scrollTop.value + clientHeight.value + bufferSize * averageItemHeight.value
) {
offset += itemHeights.value[index] || averageItemHeight.value;
index++;
}
return Math.min(props.consoleOutput.length - 1, index);
return Math.min(consoleOutput.value.length - 1, index);
});

const visibleItems = computed(() =>
props.consoleOutput.slice(visibleStartIndex.value, visibleEndIndex.value + 1),
consoleOutput.value.slice(visibleStartIndex.value, visibleEndIndex.value + 1),
);

const offsetY = computed(() => getItemOffset(visibleStartIndex.value));
Expand Down Expand Up @@ -280,7 +283,7 @@ const updateItemHeights = async () => {
const index = visibleStartIndex.value + idx;
const height = el.getBoundingClientRect().height;
itemHeights.value[index] = height;
const content = props.consoleOutput[index];
const content = consoleOutput.value[index];
if (content) {
cachedHeights.value.set(content, height);
}
Expand Down Expand Up @@ -457,7 +460,7 @@ const initializeTerminal = async () => {

updateClientHeight();

const initialHeights = props.consoleOutput.map(
const initialHeights = consoleOutput.value.map(
(content) => cachedHeights.value.get(content) || averageItemHeight.value,
);
itemHeights.value = initialHeights;
Expand Down Expand Up @@ -487,7 +490,7 @@ onUnmounted(() => {
});

watch(
() => props.consoleOutput,
() => consoleOutput.value,
async (newOutput) => {
const newItemsCount = newOutput.length - itemHeights.value.length;

Expand Down
23 changes: 8 additions & 15 deletions apps/frontend/src/pages/servers/manage/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@
:stats="stats"
:server-power-state="serverPowerState"
:power-state-details="powerStateDetails"
:console-output="throttledConsoleOutput"
:socket="socket"
:server="server"
@reinstall="onReinstall"
Expand All @@ -302,9 +301,9 @@ import {
} from "@modrinth/assets";
import DOMPurify from "dompurify";
import { ButtonStyled } from "@modrinth/ui";
import { refThrottled } from "@vueuse/core";
import { Intercom, shutdown } from "@intercom/messenger-js-sdk";
import type { ServerState, Stats, WSEvent, WSInstallationResultEvent } from "~/types/servers";
import { usePyroConsole } from "~/store/console.ts";

const socket = ref<WebSocket | null>(null);
const isReconnecting = ref(false);
Expand Down Expand Up @@ -357,9 +356,8 @@ const serverData = computed(() => server.general);
const error = ref<Error | null>(null);
const isConnected = ref(false);
const isWSAuthIncorrect = ref(false);
const maxConsoleOutput = 5000;
const consoleOutput = ref<string[]>([]);
const throttledConsoleOutput = refThrottled(consoleOutput, 200);
const pyroConsole = usePyroConsole();
console.log("||||||||||||||||||||||| console", pyroConsole.output);
const cpuData = ref<number[]>([]);
const ramData = ref<number[]>([]);
const isActioning = ref(false);
Expand Down Expand Up @@ -439,15 +437,15 @@ const connectWebSocket = () => {
return;
}

consoleOutput.value = [];
pyroConsole.clear();
socket.value?.send(JSON.stringify({ event: "auth", jwt: wsAuth.value?.token }));
isConnected.value = true;
isReconnecting.value = false;
isLoading.value = false;

if (firstConnect.value) {
for (let i = 0; i < initialConsoleMessage.length; i++) {
consoleOutput.value.push(initialConsoleMessage[i]);
pyroConsole.addLine(initialConsoleMessage[i]);
}
}

Expand All @@ -470,9 +468,7 @@ const connectWebSocket = () => {

socket.value.onclose = () => {
if (isMounted.value) {
consoleOutput.value.push(
"\nSomething went wrong with the connection, we're reconnecting...",
);
pyroConsole.addLine("\nSomething went wrong with the connection, we're reconnecting...");
isConnected.value = false;
scheduleReconnect();
}
Expand Down Expand Up @@ -530,10 +526,7 @@ const handleWebSocketMessage = (data: WSEvent) => {
case "log":
// eslint-disable-next-line no-case-declarations
const log = data.message.split("\n").filter((l) => l.trim());
if (consoleOutput.value.length > maxConsoleOutput) {
consoleOutput.value.shift();
}
consoleOutput.value.push(...log);
pyroConsole.addLines(log);
break;
case "stats":
updateStats(data);
Expand Down Expand Up @@ -623,7 +616,7 @@ const onReinstall = (potentialArgs: any) => {
// serverData.value.loader_version = potentialArgs.lVersion;
// serverData.value.mc_version = potentialArgs.mVersion;
// if (potentialArgs?.loader) {
// console.log("setting loader to", potentialArgs.loader);
// console.log("setting loadeconsole
// serverData.value.loader = potentialArgs.loader;
// }
// if (potentialArgs?.lVersion) {
Expand Down
3 changes: 1 addition & 2 deletions apps/frontend/src/pages/servers/manage/[id]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
<UiServersPanelServerStatus :state="serverPowerState" />
</div>
</div>
<UiServersPanelTerminal :console-output="consoleOutput" :full-screen="fullScreen">
<UiServersPanelTerminal :full-screen="fullScreen">
<div class="relative w-full px-4 pt-4">
<ul
v-if="suggestions.length"
Expand Down Expand Up @@ -192,7 +192,6 @@ type ServerProps = {
isConnected: boolean;
isWsAuthIncorrect: boolean;
stats: Stats;
consoleOutput: string[];
serverPowerState: ServerState;
powerStateDetails?: {
oom_killed?: boolean;
Expand Down
68 changes: 68 additions & 0 deletions apps/frontend/src/store/console.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { createGlobalState } from "@vueuse/core";
import { type Ref, ref } from "vue";

/**
* Maximum number of console output lines to store
* @type {number}
*/
const maxLines = 5000;

/**
* Provides a global console output state management system
* Allows adding, storing, and clearing console output with a maximum line limit
*
* @returns {Object} Console state management methods and reactive state
* @property {Ref<string[]>} consoleOutput - Reactive array of console output lines
* @property {function(string): void} addConsoleOutput - Method to add a new console output line
* @property {function(): void} clear - Method to clear all console output
*/
export const usePyroConsole = createGlobalState(() => {
/**
* Reactive array storing console output lines
* @type {Ref<string[]>}
*/
const output: Ref<string[]> = ref<string[]>([]);

/**
* Adds a new output line to the console output
* Automatically removes the oldest line if max output is exceeded
*
* @param {string} line - The console output line to add
*/
const addLine = (line: string): void => {
output.value.push(line);

if (output.value.length > maxLines) {
output.value.shift();
}
};

/**
* Adds multiple output lines to the console output
* Automatically removes the oldest lines if max output is exceeded
*
* @param {string[]} lines - The console output lines to add
* @returns {void}
*/
const addLines = (lines: string[]): void => {
output.value.push(...lines);

if (output.value.length > maxLines) {
output.value.splice(0, output.value.length - maxLines);
}
};

/**
* Clears all console output lines
*/
const clear = (): void => {
output.value = [];
};

return {
output,
addLine,
addLines,
clear,
};
});
Loading