Skip to content

Commit

Permalink
chore: 측정용 로그 파일들
Browse files Browse the repository at this point in the history
  • Loading branch information
hyonun321 committed Dec 5, 2024
1 parent 28f4b84 commit 7ebdfe8
Show file tree
Hide file tree
Showing 6 changed files with 775 additions and 75 deletions.
4 changes: 4 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { ErrorModal } from "@components/modal/ErrorModal";
import { WorkSpace } from "@features/workSpace/WorkSpace";
import { useErrorStore } from "@stores/useErrorStore";
import { useUserInfo } from "@stores/useUserStore";
import PerformanceComparison from "./babo";
import { useSocketStore } from "./stores/useSocketStore";
import PerformanceTest from "./test";

const App = () => {
// TODO 라우터, react query 설정
Expand All @@ -27,6 +29,8 @@ const App = () => {
<>
{isErrorModalOpen && <ErrorModal errorMessage={errorMessage} />}
<WorkSpace />
<PerformanceTest />
<PerformanceComparison />
</>
);
};
Expand Down
198 changes: 198 additions & 0 deletions client/src/babo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import React, { useEffect, useState } from "react";
import { LineChart, Line, XAxis, YAxis, Tooltip, Legend, ResponsiveContainer } from "recharts";
import { useSocketStore } from "./stores/useSocketStore";

const PerformanceComparison = () => {
const [performanceData, setPerformanceData] = useState({
individualEvents: {
latencies: [],
totalEvents: 0,
averageLatency: 0,
eventCounts: {
"insert/char": 0,
"delete/char": 0,
"update/char": 0,
"insert/block": 0,
"delete/block": 0,
"update/block": 0,
},
},
networkStats: {
requestCount: 0,
totalDataSent: 0,
avgRequestPerSecond: 0,
},
timeSeriesData: [],
});

const socket = useSocketStore((state) => state.socket);

useEffect(() => {
if (!socket) return;

let requestsLastSecond = 0;
let lastSecondTimestamp = Date.now();
const operationStartTimes = new Map();

const eventTypes = [
"insert/char",
"delete/char",
"update/char",
"insert/block",
"delete/block",
"update/block",
];

const handleEvent = (eventType, data) => {
const operationId = `${eventType}-${Date.now()}`;
const startTime = performance.now();
operationStartTimes.set(operationId, startTime);

requestsLastSecond++;

Check failure on line 51 in client/src/babo.tsx

View workflow job for this annotation

GitHub Actions / Lint and Unit Test

Unary operator '++' used
const requestSize = JSON.stringify(data).length;

// 작업 완료 시점 측정
const endTime = performance.now();
const duration = endTime - startTime;

setPerformanceData((prev) => {
const timestamp = Date.now();
const newLatencies = [...prev.individualEvents.latencies, duration].slice(-50);
const totalEvents = prev.individualEvents.totalEvents + 1;
const avgLatency = newLatencies.reduce((a, b) => a + b, 0) / newLatencies.length;

// 초당 요청 수 계산
if (timestamp - lastSecondTimestamp >= 1000) {
prev.networkStats.avgRequestPerSecond = requestsLastSecond;
requestsLastSecond = 0;
lastSecondTimestamp = timestamp;
}

const eventCounts = {
...prev.individualEvents.eventCounts,
[eventType]: (prev.individualEvents.eventCounts[eventType] || 0) + 1,
};

// 시계열 데이터 업데이트
const newTimeSeriesData = [
...prev.timeSeriesData,
{
timestamp,
latency: duration,
requestsPerSecond: prev.networkStats.avgRequestPerSecond,
eventType,
},
].slice(-100);

return {
individualEvents: {
latencies: newLatencies,
totalEvents,
averageLatency: avgLatency,
eventCounts,
},
networkStats: {
requestCount: prev.networkStats.requestCount + 1,
totalDataSent: prev.networkStats.totalDataSent + requestSize,
avgRequestPerSecond: prev.networkStats.avgRequestPerSecond,
},
timeSeriesData: newTimeSeriesData,
};
});

operationStartTimes.delete(operationId);
};

// 이벤트 리스너 등록
eventTypes.forEach((eventType) => {
socket.on(eventType, (data) => handleEvent(eventType, data));
});

return () => {
eventTypes.forEach((eventType) => {
socket.off(eventType);
});
};
}, [socket]);

const chartData = performanceData.timeSeriesData.map((data, index) => ({
name: index,
latency: data.latency,
requestsPerSecond: data.requestsPerSecond,
}));

return (
<div className="p-6 bg-white rounded-lg shadow-lg">
<h2 className="text-2xl font-bold mb-6">개별 이벤트 모드 성능 모니터링</h2>

<div className="grid grid-cols-2 gap-6 mb-8">
<div className="p-4 bg-blue-50 rounded-lg">
<h3 className="text-lg font-semibold mb-3">이벤트 통계</h3>
<div className="space-y-2">
<p>총 이벤트 수: {performanceData.individualEvents.totalEvents}</p>
<p>평균 지연 시간: {performanceData.individualEvents.averageLatency.toFixed(2)}ms</p>
<p>초당 요청 수: {performanceData.networkStats.avgRequestPerSecond}</p>
</div>
</div>

<div className="p-4 bg-green-50 rounded-lg">
<h3 className="text-lg font-semibold mb-3">네트워크 통계</h3>
<div className="space-y-2">
<p>총 요청 수: {performanceData.networkStats.requestCount}</p>
<p>
전송된 데이터: {(performanceData.networkStats.totalDataSent / 1024).toFixed(2)} KB
</p>
</div>
</div>
</div>

<div className="grid grid-cols-2 gap-6 mb-8">
<div className="p-4 bg-purple-50 rounded-lg">
<h3 className="text-lg font-semibold mb-3">이벤트 타입별 카운트</h3>
<div className="space-y-2">
{Object.entries(performanceData.individualEvents.eventCounts).map(([type, count]) => (
<p key={type}>
{type}: {count}
</p>
))}
</div>
</div>
</div>

<div className="space-y-6">
<div className="h-80">
<h3 className="text-lg font-semibold mb-3">지연 시간 & 요청 추이</h3>
<ResponsiveContainer width="100%" height="100%">
<LineChart data={chartData}>
<XAxis dataKey="name" />
<YAxis yAxisId="left" />
<YAxis yAxisId="right" orientation="right" />
<Tooltip />
<Legend />
<Line
yAxisId="left"
type="monotone"
dataKey="latency"
stroke="#8884d8"
name="지연 시간 (ms)"
dot={false}
isAnimationActive={false}
/>
<Line
yAxisId="right"
type="monotone"
dataKey="requestsPerSecond"
stroke="#82ca9d"
name="초당 요청 수"
dot={false}
isAnimationActive={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
</div>
</div>
);
};

export default PerformanceComparison;
80 changes: 50 additions & 30 deletions client/src/stores/useSocketStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ interface PageOperationsHandlers {
onRemotePageDelete: (operation: RemotePageDeleteOperation) => void;
onRemotePageUpdate: (operation: RemotePageUpdateOperation) => void;
}

const test = false;
export const useSocketStore = create<SocketStore>((set, get) => ({
socket: null,
clientId: null,
Expand Down Expand Up @@ -242,45 +242,62 @@ export const useSocketStore = create<SocketStore>((set, get) => ({
},

sendBlockInsertOperation: (operation: RemoteBlockInsertOperation) => {
// const { socket } = get();
// socket?.emit("insert/block", operation);
const { sendOperation } = get();
sendOperation(operation);
if (test) {
const { socket } = get();
socket?.emit("insert/block", operation);
} else {
const { sendOperation } = get();
sendOperation(operation);
}
},

sendCharInsertOperation: (operation: RemoteCharInsertOperation) => {
// const { socket } = get();
// socket?.emit("insert/char", operation);
const { sendOperation } = get();
sendOperation(operation);
if (test) {
const { socket } = get();
socket?.emit("insert/char", operation);
} else {
const { sendOperation } = get();
sendOperation(operation);
}
},

sendBlockUpdateOperation: (operation: RemoteBlockUpdateOperation) => {
// const { socket } = get();
// socket?.emit("update/block", operation);
const { sendOperation } = get();
sendOperation(operation);
if (test) {
const { socket } = get();
socket?.emit("update/block", operation);
} else {
const { sendOperation } = get();
sendOperation(operation);
}
},

sendBlockDeleteOperation: (operation: RemoteBlockDeleteOperation) => {
// const { socket } = get();
// socket?.emit("delete/block", operation);
const { sendOperation } = get();
sendOperation(operation);
if (test) {
const { socket } = get();
socket?.emit("delete/block", operation);
} else {
const { sendOperation } = get();
sendOperation(operation);
}
},

sendCharDeleteOperation: (operation: RemoteCharDeleteOperation) => {
// const { socket } = get();
// socket?.emit("delete/char", operation);
const { sendOperation } = get();
sendOperation(operation);
if (test) {
const { socket } = get();
socket?.emit("delete/char", operation);
} else {
const { sendOperation } = get();
sendOperation(operation);
}
},

sendCharUpdateOperation: (operation: RemoteCharUpdateOperation) => {
// const { socket } = get();
// socket?.emit("update/char", operation);
const { sendOperation } = get();
sendOperation(operation);
if (test) {
const { socket } = get();
socket?.emit("update/char", operation);
} else {
const { sendOperation } = get();
sendOperation(operation);
}
},

sendCursorPosition: (position: CursorPosition) => {
Expand All @@ -289,10 +306,13 @@ export const useSocketStore = create<SocketStore>((set, get) => ({
},

sendBlockReorderOperation: (operation: RemoteBlockReorderOperation) => {
// const { socket } = get();
// socket?.emit("reorder/block", operation);
const { sendOperation } = get();
sendOperation(operation);
if (test) {
const { socket } = get();
socket?.emit("reorder/block", operation);
} else {
const { sendOperation } = get();
sendOperation(operation);
}
},

sendBlockCheckboxOperation: (operation: RemoteBlockCheckboxOperation) => {
Expand Down
Loading

0 comments on commit 7ebdfe8

Please sign in to comment.