Skip to content

Commit c8ecbe6

Browse files
committed
Update logic to listen for a restoration completion event
1 parent f558bc8 commit c8ecbe6

File tree

9 files changed

+68
-48
lines changed

9 files changed

+68
-48
lines changed

resources/scripts/components/server/Console.tsx

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'xterm/css/xterm.css';
1313
import useEventListener from '@/plugins/useEventListener';
1414
import { debounce } from 'debounce';
1515
import { usePersistedState } from '@/plugins/usePersistedState';
16+
import { SocketEvent, SocketRequest } from '@/components/server/events';
1617

1718
const theme = {
1819
background: th`colors.black`.toString(),
@@ -172,32 +173,35 @@ export default () => {
172173
useEventListener('resize', () => fit());
173174

174175
useEffect(() => {
176+
const listeners: Record<string, (s: string) => void> = {
177+
[SocketEvent.STATUS]: handlePowerChangeEvent,
178+
[SocketEvent.CONSOLE_OUTPUT]: handleConsoleOutput,
179+
[SocketEvent.INSTALL_OUTPUT]: handleConsoleOutput,
180+
[SocketEvent.TRANSFER_LOGS]: handleConsoleOutput,
181+
[SocketEvent.TRANSFER_STATUS]: handleTransferStatus,
182+
[SocketEvent.DAEMON_MESSAGE]: line => handleConsoleOutput(line, true),
183+
[SocketEvent.DAEMON_ERROR]: handleDaemonErrorOutput,
184+
};
185+
175186
if (connected && instance) {
176187
// Do not clear the console if the server is being transferred.
177188
if (!isTransferring) {
178189
terminal.clear();
179190
}
180191

181-
instance.addListener('status', handlePowerChangeEvent);
182-
instance.addListener('console output', handleConsoleOutput);
183-
instance.addListener('install output', handleConsoleOutput);
184-
instance.addListener('transfer logs', handleConsoleOutput);
185-
instance.addListener('transfer status', handleTransferStatus);
186-
instance.addListener('daemon message', line => handleConsoleOutput(line, true));
187-
instance.addListener('daemon error', handleDaemonErrorOutput);
188-
instance.send('send logs');
192+
Object.keys(listeners).forEach((key: string) => {
193+
instance.addListener(key, listeners[key]);
194+
});
195+
instance.send(SocketRequest.SEND_LOGS);
189196
}
190197

191198
return () => {
192-
instance && instance.removeListener('status', handlePowerChangeEvent)
193-
.removeListener('console output', handleConsoleOutput)
194-
.removeListener('install output', handleConsoleOutput)
195-
.removeListener('transfer logs', handleConsoleOutput)
196-
.removeListener('transfer status', handleTransferStatus)
197-
.removeListener('daemon message', line => handleConsoleOutput(line, true))
198-
.removeListener('daemon error', handleDaemonErrorOutput);
199+
if (instance) {
200+
Object.keys(listeners).forEach((key: string) => {
201+
instance.removeListener(key, listeners[key]);
202+
});
203+
}
199204
};
200-
// eslint-disable-next-line react-hooks/exhaustive-deps
201205
}, [ connected, instance ]);
202206

203207
return (

resources/scripts/components/server/InstallListener.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
import useWebsocketEvent from '@/plugins/useWebsocketEvent';
22
import { ServerContext } from '@/state/server';
3+
import { SocketEvent } from '@/components/server/events';
4+
import useFileManagerSwr from '@/plugins/useFileManagerSwr';
35

46
const InstallListener = () => {
57
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
68
const getServer = ServerContext.useStoreActions(actions => actions.server.getServer);
9+
const { mutate } = useFileManagerSwr();
710
const setServerFromState = ServerContext.useStoreActions(actions => actions.server.setServerFromState);
811

12+
useWebsocketEvent(SocketEvent.BACKUP_RESTORE_COMPLETED, () => {
13+
mutate(undefined);
14+
setServerFromState(s => ({ ...s, status: null }));
15+
});
16+
917
// Listen for the installation completion event and then fire off a request to fetch the updated
1018
// server information. This allows the server to automatically become available to the user if they
1119
// just sit on the page.
12-
useWebsocketEvent('install completed', () => {
20+
useWebsocketEvent(SocketEvent.INSTALL_COMPLETED, () => {
1321
getServer(uuid).catch(error => console.error(error));
1422
});
1523

1624
// When we see the install started event immediately update the state to indicate such so that the
1725
// screens automatically update.
18-
useWebsocketEvent('install started', () => {
19-
setServerFromState(s => ({ ...s, isInstalling: true }));
26+
useWebsocketEvent(SocketEvent.INSTALL_STARTED, () => {
27+
setServerFromState(s => ({ ...s, status: 'installing' }));
2028
});
2129

2230
return null;

resources/scripts/components/server/ServerDetailsBlock.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { bytesToHuman, megabytesToHuman } from '@/helpers';
66
import TitledGreyBox from '@/components/elements/TitledGreyBox';
77
import { ServerContext } from '@/state/server';
88
import CopyOnClick from '@/components/elements/CopyOnClick';
9+
import { SocketEvent, SocketRequest } from '@/components/server/events';
910

1011
interface Stats {
1112
memory: number;
@@ -55,11 +56,11 @@ const ServerDetailsBlock = () => {
5556
return;
5657
}
5758

58-
instance.addListener('stats', statsListener);
59-
instance.send('send stats');
59+
instance.addListener(SocketEvent.STATS, statsListener);
60+
instance.send(SocketRequest.SEND_STATS);
6061

6162
return () => {
62-
instance.removeListener('stats', statsListener);
63+
instance.removeListener(SocketEvent.STATS, statsListener);
6364
};
6465
}, [ instance, connected ]);
6566

resources/scripts/components/server/StatGraphs.tsx

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import React, { useCallback, useEffect, useState } from 'react';
1+
import React, { useCallback, useState } from 'react';
22
import Chart, { ChartConfiguration } from 'chart.js';
33
import { ServerContext } from '@/state/server';
44
import { bytesToMegabytes } from '@/helpers';
55
import merge from 'deepmerge';
66
import TitledGreyBox from '@/components/elements/TitledGreyBox';
77
import { faMemory, faMicrochip } from '@fortawesome/free-solid-svg-icons';
88
import tw from 'twin.macro';
9+
import { SocketEvent } from '@/components/server/events';
10+
import useWebsocketEvent from '@/plugins/useWebsocketEvent';
911

1012
const chartDefaults = (ticks?: Chart.TickOptions | undefined): ChartConfiguration => ({
1113
type: 'line',
@@ -70,7 +72,6 @@ const chartDefaults = (ticks?: Chart.TickOptions | undefined): ChartConfiguratio
7072
export default () => {
7173
const status = ServerContext.useStoreState(state => state.status.value);
7274
const limits = ServerContext.useStoreState(state => state.server.data!.limits);
73-
const { connected, instance } = ServerContext.useStoreState(state => state.socket);
7475

7576
const [ memory, setMemory ] = useState<Chart>();
7677
const [ cpu, setCpu ] = useState<Chart>();
@@ -84,7 +85,7 @@ export default () => {
8485
new Chart(node.getContext('2d')!, chartDefaults({
8586
callback: (value) => `${value}Mb `,
8687
suggestedMax: limits.memory,
87-
}))
88+
})),
8889
);
8990
}, []);
9091

@@ -100,7 +101,7 @@ export default () => {
100101
);
101102
}, []);
102103

103-
const statsListener = (data: string) => {
104+
useWebsocketEvent(SocketEvent.STATS, (data: string) => {
104105
let stats: any = {};
105106
try {
106107
stats = JSON.parse(data);
@@ -125,27 +126,19 @@ export default () => {
125126

126127
cpu.update({ lazy: true });
127128
}
128-
};
129-
130-
useEffect(() => {
131-
if (!connected || !instance) {
132-
return;
133-
}
134-
135-
instance.addListener('stats', statsListener);
136-
137-
return () => {
138-
instance.removeListener('stats', statsListener);
139-
};
140-
// eslint-disable-next-line react-hooks/exhaustive-deps
141-
}, [ instance, connected, memory, cpu ]);
129+
});
142130

143131
return (
144132
<div css={tw`flex flex-wrap mt-4`}>
145133
<div css={tw`w-full sm:w-1/2`}>
146134
<TitledGreyBox title={'Memory usage'} icon={faMemory} css={tw`mr-0 sm:mr-4`}>
147135
{status !== 'offline' ?
148-
<canvas id={'memory_chart'} ref={memoryRef} aria-label={'Server Memory Usage Graph'} role={'img'}/>
136+
<canvas
137+
id={'memory_chart'}
138+
ref={memoryRef}
139+
aria-label={'Server Memory Usage Graph'}
140+
role={'img'}
141+
/>
149142
:
150143
<p css={tw`text-xs text-neutral-400 text-center p-3`}>
151144
Server is offline.

resources/scripts/components/server/TransferListener.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import useWebsocketEvent from '@/plugins/useWebsocketEvent';
22
import { ServerContext } from '@/state/server';
3+
import { SocketEvent } from '@/components/server/events';
34

45
const TransferListener = () => {
56
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
67
const getServer = ServerContext.useStoreActions(actions => actions.server.getServer);
78
const setServerFromState = ServerContext.useStoreActions(actions => actions.server.setServerFromState);
89

910
// Listen for the transfer status event so we can update the state of the server.
10-
useWebsocketEvent('transfer status', (status: string) => {
11+
useWebsocketEvent(SocketEvent.TRANSFER_STATUS, (status: string) => {
1112
if (status === 'starting') {
1213
setServerFromState(s => ({ ...s, isTransferring: true }));
1314
return;

resources/scripts/components/server/backups/BackupRow.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import tw from 'twin.macro';
1111
import GreyRowBox from '@/components/elements/GreyRowBox';
1212
import getServerBackups from '@/api/swr/getServerBackups';
1313
import { ServerBackup } from '@/api/server/types';
14+
import { SocketEvent } from '@/components/server/events';
1415

1516
interface Props {
1617
backup: ServerBackup;
@@ -20,7 +21,7 @@ interface Props {
2021
export default ({ backup, className }: Props) => {
2122
const { mutate } = getServerBackups();
2223

23-
useWebsocketEvent(`backup completed:${backup.uuid}`, data => {
24+
useWebsocketEvent(`${SocketEvent.BACKUP_COMPLETED}:${backup.uuid}` as SocketEvent, data => {
2425
try {
2526
const parsed = JSON.parse(data);
2627

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
export enum SocketEvent {
22
DAEMON_MESSAGE = 'daemon message',
3+
DAEMON_ERROR = 'daemon error',
34
INSTALL_OUTPUT = 'install output',
45
INSTALL_STARTED = 'install started',
56
INSTALL_COMPLETED = 'install completed',
67
CONSOLE_OUTPUT = 'console output',
78
STATUS = 'status',
89
STATS = 'stats',
10+
TRANSFER_LOGS = 'transfer logs',
11+
TRANSFER_STATUS = 'transfer status',
912
BACKUP_COMPLETED = 'backup completed',
13+
BACKUP_RESTORE_COMPLETED = 'backup restore completed',
14+
}
15+
16+
export enum SocketRequest {
17+
SEND_LOGS = 'send logs',
18+
SEND_STATS = 'send stats',
19+
SET_STATE = 'set state'
1020
}

resources/scripts/components/server/features/eula/EulaModalFeature.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Button from '@/components/elements/Button';
66
import saveFileContents from '@/api/server/files/saveFileContents';
77
import FlashMessageRender from '@/components/FlashMessageRender';
88
import useFlash from '@/plugins/useFlash';
9+
import { SocketEvent, SocketRequest } from '@/components/server/events';
910

1011
const EulaModalFeature = () => {
1112
const [ visible, setVisible ] = useState(false);
@@ -25,10 +26,10 @@ const EulaModalFeature = () => {
2526
}
2627
};
2728

28-
instance.addListener('console output', listener);
29+
instance.addListener(SocketEvent.CONSOLE_OUTPUT, listener);
2930

3031
return () => {
31-
instance.removeListener('console output', listener);
32+
instance.removeListener(SocketEvent.CONSOLE_OUTPUT, listener);
3233
};
3334
}, [ connected, instance, status ]);
3435

@@ -39,7 +40,7 @@ const EulaModalFeature = () => {
3940
saveFileContents(uuid, 'eula.txt', 'eula=true')
4041
.then(() => {
4142
if (status === 'offline' && instance) {
42-
instance.send('set state', 'restart');
43+
instance.send(SocketRequest.SET_STATE, 'restart');
4344
}
4445

4546
setLoading(false);

resources/scripts/plugins/useWebsocketEvent.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { ServerContext } from '@/state/server';
22
import { useEffect, useRef } from 'react';
3+
import { SocketEvent } from '@/components/server/events';
34

4-
const useWebsocketEvent = (event: string, callback: (data: string) => void) => {
5+
const useWebsocketEvent = (event: SocketEvent, callback: (data: string) => void) => {
56
const { connected, instance } = ServerContext.useStoreState(state => state.socket);
67
const savedCallback = useRef<any>(null);
78

@@ -10,7 +11,7 @@ const useWebsocketEvent = (event: string, callback: (data: string) => void) => {
1011
}, [ callback ]);
1112

1213
return useEffect(() => {
13-
const eventListener = (event: any) => savedCallback.current(event);
14+
const eventListener = (event: SocketEvent) => savedCallback.current(event);
1415
if (connected && instance) {
1516
instance.addListener(event, eventListener);
1617
}

0 commit comments

Comments
 (0)