Skip to content

Commit

Permalink
perf: improve monitor query performance
Browse files Browse the repository at this point in the history
  • Loading branch information
moonrailgun committed Apr 23, 2024
1 parent 89fed46 commit f5c13cb
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 32 deletions.
35 changes: 28 additions & 7 deletions src/client/api/trpc.ts
@@ -1,7 +1,13 @@
import { createTRPCReact, getQueryKey } from '@trpc/react-query';
import type { inferRouterInputs, inferRouterOutputs } from '../../server/trpc';
import type { AppRouter } from '../../server/trpc/routers';
import { httpBatchLink, loggerLink, TRPCClientErrorLike } from '@trpc/client';
import {
httpBatchLink,
httpLink,
loggerLink,
splitLink,
TRPCClientErrorLike,
} from '@trpc/client';
import { getJWT } from './auth';
import { message } from 'antd';
import { isDev } from '../utils/env';
Expand All @@ -13,20 +19,35 @@ export const trpc = createTRPCReact<AppRouter>();
export type AppRouterInput = inferRouterInputs<AppRouter>;
export type AppRouterOutput = inferRouterOutputs<AppRouter>;

const url = '/trpc';

function headers() {
return {
Authorization: `Bearer ${getJWT()}`,
};
}

export const trpcClient = trpc.createClient({
links: [
loggerLink({
enabled: (opts) =>
(isDev && typeof window !== 'undefined') ||
(opts.direction === 'down' && opts.result instanceof Error),
}),
httpBatchLink({
url: '/trpc',
async headers() {
return {
Authorization: `Bearer ${getJWT()}`,
};
splitLink({
condition(op) {
// check for context property `skipBatch`
return op.context.skipBatch === true;
},
true: httpLink({
url,
headers,
}),
// when condition is false, use batching
false: httpBatchLink({
url,
headers,
}),
}),
],
});
Expand Down
17 changes: 13 additions & 4 deletions src/client/components/monitor/MonitorDataMetrics.tsx
Expand Up @@ -15,10 +15,19 @@ export const MonitorDataMetrics: React.FC<{
const { t } = useTranslation();
const workspaceId = useCurrentWorkspaceId();
const { monitorId, monitorType, currectResponse } = props;
const { data, isLoading } = trpc.monitor.dataMetrics.useQuery({
workspaceId,
monitorId,
});
const { data, isLoading } = trpc.monitor.dataMetrics.useQuery(
{
workspaceId,
monitorId,
},
{
trpc: {
context: {
skipBatch: true,
},
},
}
);

const provider = useMemo(
() => getMonitorProvider(monitorType),
Expand Down
6 changes: 6 additions & 0 deletions src/client/components/monitor/MonitorInfo.tsx
Expand Up @@ -70,6 +70,9 @@ export const MonitorInfo: React.FC<MonitorInfoProps> = React.memo((props) => {
active: true,
});

trpcUtils.monitor.all.refetch({
workspaceId,
});
trpcUtils.monitor.get.refetch({
workspaceId,
monitorId,
Expand All @@ -87,6 +90,9 @@ export const MonitorInfo: React.FC<MonitorInfoProps> = React.memo((props) => {
active: false,
});

trpcUtils.monitor.all.refetch({
workspaceId,
});
trpcUtils.monitor.get.refetch({
workspaceId,
monitorId,
Expand Down
2 changes: 1 addition & 1 deletion src/client/components/server/ServerList.tsx
Expand Up @@ -139,7 +139,7 @@ export const ServerList: React.FC<ServerListProps> = React.memo((props) => {
cell: (props) => dayjs(props.getValue()).format('MMM D HH:mm:ss'),
}),
];
}, []);
}, [t]);

return (
<div className="flex h-full flex-col">
Expand Down
1 change: 0 additions & 1 deletion src/client/routes/server.tsx
Expand Up @@ -10,7 +10,6 @@ import {
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
import { Switch } from '@/components/ui/switch';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
Expand Down
53 changes: 53 additions & 0 deletions src/server/model/monitor/index.bench.ts
@@ -0,0 +1,53 @@
import { describe, bench } from 'vitest';
import { prisma } from '../_client';

const workspaceId = process.env.BENCH_MONITOR_WORKSPACEID;
const monitorId = process.env.BENCH_MONITOR_ID;

describe.runIf(workspaceId && monitorId)('getMonitorRecentData', () => {
bench('find with join', async () => {
await prisma.monitorData
.findMany({
where: {
monitor: {
id: monitorId,
workspaceId,
},
},
take: 20,
orderBy: {
createdAt: 'desc',
},
select: {
value: true,
createdAt: true,
},
})
.then((arr) => arr.reverse());
});

bench('find with double check', async () => {
await prisma.monitor.findFirstOrThrow({
where: {
workspaceId,
id: monitorId,
},
});

await prisma.monitorData
.findMany({
where: {
monitorId,
},
take: 20,
orderBy: {
createdAt: 'desc',
},
select: {
value: true,
createdAt: true,
},
})
.then((arr) => arr.reverse());
});
});
29 changes: 17 additions & 12 deletions src/server/model/monitor/index.ts
Expand Up @@ -48,17 +48,22 @@ export function getMonitorRecentData(
monitorId: string,
take: number
) {
return prisma.monitorData.findMany({
where: {
monitor: {
id: monitorId,
workspaceId,
return prisma.monitorData
.findMany({
where: {
monitor: {
id: monitorId,
workspaceId,
},
},
},
take: -take,
select: {
value: true,
createdAt: true,
},
});
take,
orderBy: {
createdAt: 'desc',
},
select: {
value: true,
createdAt: true,
},
})
.then((arr) => arr.reverse());
}
@@ -0,0 +1,8 @@
-- CreateIndex
CREATE INDEX "MonitorData_monitorId_createdAt_idx" ON "MonitorData"("monitorId", "createdAt" DESC);

-- CreateIndex
CREATE INDEX "MonitorData_monitorId_createdAt_value_idx" ON "MonitorData"("monitorId", "createdAt", "value");

-- CreateIndex
CREATE INDEX "MonitorEvent_monitorId_idx" ON "MonitorEvent"("monitorId");
4 changes: 4 additions & 0 deletions src/server/prisma/schema.prisma
Expand Up @@ -318,6 +318,8 @@ model MonitorEvent {
createdAt DateTime @default(now()) @db.Timestamptz(6)
monitor Monitor @relation(fields: [monitorId], references: [id], onUpdate: Cascade, onDelete: Cascade)
@@index([monitorId])
}

model MonitorData {
Expand All @@ -329,6 +331,8 @@ model MonitorData {
monitor Monitor @relation(fields: [monitorId], references: [id], onUpdate: Cascade, onDelete: Cascade)
@@index([createdAt])
@@index([monitorId, createdAt(sort: Desc)])
@@index([monitorId, createdAt, value])
}

// Use for record latest monitor status, for example tls status
Expand Down
13 changes: 6 additions & 7 deletions src/server/trpc/routers/monitor.ts
Expand Up @@ -300,14 +300,13 @@ export const monitorRouter = router({
return monitor;
}),
recentData: publicProcedure
.meta({
openapi: {
tags: [OPENAPI_TAG.MONITOR],
protect: false,
.meta(
buildMonitorOpenapi({
method: 'GET',
path: `/monitor/{monitorId}/recentData`,
},
})
protect: false,
path: '/{monitorId}/recentData',
})
)
.input(
z.object({
workspaceId: z.string().cuid2(),
Expand Down

0 comments on commit f5c13cb

Please sign in to comment.