diff --git a/src/client/pages/Servers.tsx b/src/client/pages/Servers.tsx
index 4fa46a8..900e5f1 100644
--- a/src/client/pages/Servers.tsx
+++ b/src/client/pages/Servers.tsx
@@ -1,11 +1,13 @@
-import React, { useEffect, useMemo, useReducer, useRef, useState } from 'react';
+import React, { useMemo, useRef, useState } from 'react';
import {
Badge,
Button,
+ Divider,
Empty,
Form,
Input,
Modal,
+ Popconfirm,
Steps,
Switch,
Table,
@@ -28,15 +30,31 @@ import { Loading } from '../components/Loading';
import { without } from 'lodash-es';
import { useIntervalUpdate } from '../hooks/useIntervalUpdate';
import clsx from 'clsx';
+import { isServerOnline } from '../../shared';
+import { defaultErrorHandler, trpc } from '../api/trpc';
+import { useEvent } from '../hooks/useEvent';
+import { useRequest } from '../hooks/useRequest';
export const Servers: React.FC = React.memo(() => {
const [isModalOpen, setIsModalOpen] = useState(false);
const [hideOfflineServer, setHideOfflineServer] = useState(false);
+ const workspaceId = useCurrentWorkspaceId();
const handleOk = () => {
setIsModalOpen(false);
};
+ const clearOfflineNodeMutation =
+ trpc.serverStatus.clearOfflineServerStatus.useMutation({
+ onError: defaultErrorHandler,
+ });
+
+ const [{ loading }, handleClearOfflineNode] = useRequest(async (e) => {
+ await clearOfflineNodeMutation.mutateAsync({
+ workspaceId,
+ });
+ });
+
return (
@@ -50,6 +68,21 @@ export const Servers: React.FC = React.memo(() => {
Hide Offline
+
+
+
+
+
+
+
+
}
@@ -151,10 +184,10 @@ export const ServerList: React.FC<{
dataIndex: 'hostname',
title: 'Host Name',
},
- {
- dataIndex: ['payload', 'system'],
- title: 'System',
- },
+ // {
+ // dataIndex: ['payload', 'system'],
+ // title: 'System',
+ // },
{
dataIndex: ['payload', 'uptime'],
title: 'Uptime',
@@ -351,7 +384,3 @@ export const AddServerStep: React.FC = React.memo(() => {
);
});
AddServerStep.displayName = 'AddServerStep';
-
-function isServerOnline(info: ServerStatusInfo): boolean {
- return new Date(info.updatedAt).valueOf() + info.timeout * 1000 > Date.now();
-}
diff --git a/src/server/model/serverStatus.ts b/src/server/model/serverStatus.ts
index 0371f00..02b0782 100644
--- a/src/server/model/serverStatus.ts
+++ b/src/server/model/serverStatus.ts
@@ -1,5 +1,8 @@
+import dayjs from 'dayjs';
import { ServerStatusInfo } from '../../types';
import { createSubscribeInitializer, subscribeEventBus } from '../ws/shared';
+import _ from 'lodash';
+import { isServerOnline } from '../../shared';
const serverMap: Record<
string, // workspaceId
@@ -47,3 +50,28 @@ export function recordServerStatus(info: ServerStatusInfo) {
serverMap[workspaceId]
);
}
+
+export function clearOfflineServerStatus(workspaceId: string) {
+ if (!serverMap[workspaceId]) {
+ return;
+ }
+
+ const offlineNode: string[] = [];
+ Object.entries(serverMap[workspaceId]).forEach(([key, info]) => {
+ if (!isServerOnline(info)) {
+ offlineNode.push(key);
+ }
+ });
+
+ for (const node of offlineNode) {
+ delete serverMap[workspaceId][node];
+ }
+
+ subscribeEventBus.emit(
+ 'onServerStatusUpdate',
+ workspaceId,
+ serverMap[workspaceId]
+ );
+
+ return serverMap[workspaceId];
+}
diff --git a/src/server/trpc/routers/index.ts b/src/server/trpc/routers/index.ts
index 1bd53be..bd26437 100644
--- a/src/server/trpc/routers/index.ts
+++ b/src/server/trpc/routers/index.ts
@@ -5,6 +5,7 @@ import { monitorRouter } from './monitor';
import { userRouter } from './user';
import { workspaceRouter } from './workspace';
import { globalRouter } from './global';
+import { serverStatusRouter } from './serverStatus';
export const appRouter = router({
global: globalRouter,
@@ -13,6 +14,7 @@ export const appRouter = router({
website: websiteRouter,
notification: notificationRouter,
monitor: monitorRouter,
+ serverStatus: serverStatusRouter,
});
export type AppRouter = typeof appRouter;
diff --git a/src/server/trpc/routers/serverStatus.ts b/src/server/trpc/routers/serverStatus.ts
new file mode 100644
index 0000000..7472017
--- /dev/null
+++ b/src/server/trpc/routers/serverStatus.ts
@@ -0,0 +1,12 @@
+import { router, workspaceOwnerProcedure } from '../trpc';
+import { clearOfflineServerStatus } from '../../model/serverStatus';
+
+export const serverStatusRouter = router({
+ clearOfflineServerStatus: workspaceOwnerProcedure.mutation(
+ async ({ input }) => {
+ const workspaceId = input.workspaceId;
+
+ return clearOfflineServerStatus(workspaceId);
+ }
+ ),
+});
diff --git a/src/shared/index.ts b/src/shared/index.ts
index 05b562f..c63001a 100644
--- a/src/shared/index.ts
+++ b/src/shared/index.ts
@@ -1 +1,2 @@
export * from './date';
+export * from './server';
diff --git a/src/shared/server.ts b/src/shared/server.ts
new file mode 100644
index 0000000..e27e279
--- /dev/null
+++ b/src/shared/server.ts
@@ -0,0 +1,5 @@
+import { ServerStatusInfo } from '../types';
+
+export function isServerOnline(info: ServerStatusInfo): boolean {
+ return new Date(info.updatedAt).valueOf() + info.timeout * 1000 > Date.now();
+}