summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Rief <riearn@proton.me>2026-02-13 21:04:35 +0100
committerArne Rief <riearn@proton.me>2026-02-13 21:04:35 +0100
commit50c0b1e5650bd1e8bc853d9a5520067d37860673 (patch)
tree314b10bcaa9da224e16e1fbaa9b753db236466c7
parent44b0ea903dd35bae26aa5a167a2a04f157f5f53b (diff)
Better caching during simulation
-rw-r--r--backend/package-lock.json6
-rw-r--r--backend/src/database/postgres.ts2
-rw-r--r--backend/src/simulation/robotMovementSimulator.ts27
-rw-r--r--frontend/package-lock.json14
-rw-r--r--frontend/src/pages/Dashboard.tsx6
5 files changed, 34 insertions, 21 deletions
diff --git a/backend/package-lock.json b/backend/package-lock.json
index a721fb0..ccc093b 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -1723,9 +1723,9 @@
}
},
"node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "version": "6.14.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
+ "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
diff --git a/backend/src/database/postgres.ts b/backend/src/database/postgres.ts
index 6f6b682..e2493a9 100644
--- a/backend/src/database/postgres.ts
+++ b/backend/src/database/postgres.ts
@@ -8,7 +8,7 @@ const pool = new Pool({
port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 5432,
});
-/* Too strict for Docker:
+/* Too strict for Docker, use docker compose healthcheck instead:
pool.connect((error, _client, release) => {
if (error) {
console.error("Verbindung zur Datenbank fehlgeschlagen: ", error);
diff --git a/backend/src/simulation/robotMovementSimulator.ts b/backend/src/simulation/robotMovementSimulator.ts
index 2299f43..d3a2564 100644
--- a/backend/src/simulation/robotMovementSimulator.ts
+++ b/backend/src/simulation/robotMovementSimulator.ts
@@ -1,6 +1,7 @@
import { QueryResult } from "pg";
import { Server } from "socket.io";
import db from "../database/postgres.js";
+import redisClient from "../database/redis.js";
import {
Robot,
RobotPosition,
@@ -8,6 +9,9 @@ import {
SimulationResponse,
} from "../types/robot.js";
+const CACHE_TTL = 10;
+const ROBOTS_CACHE_KEY = "allMyRobots";
+
// Coordinates for the boundaries of the frontend map
const LEIPZIG_AREA = {
WEST: 12.22,
@@ -70,10 +74,19 @@ async function updateRobotPositions(io: Server) {
try {
client = await db.connect();
- const allRobotsQuery: QueryResult<Robot> = await client.query(
- "SELECT * FROM robots ORDER BY id;"
- );
- const allRobots = allRobotsQuery.rows;
+ let allRobots;
+ const cachedData = await redisClient.get(ROBOTS_CACHE_KEY);
+
+ // Check Redis for cached data, otherwise query database
+ if (cachedData) {
+ allRobots = JSON.parse(cachedData);
+ } else {
+ const allRobotsQuery: QueryResult<Robot> = await client.query(
+ "SELECT * FROM robots ORDER BY id;"
+ );
+
+ allRobots = allRobotsQuery.rows;
+ }
// Update database
await client.query("BEGIN");
@@ -142,6 +155,12 @@ async function updateRobotPositions(io: Server) {
await client.query("COMMIT");
+ // Keep robots in Redis cache indefinitely while simulation is running to avoid db query on every tick
+ // Once the simulation stops, keep the cache alive for 10 seconds
+ await redisClient.set(ROBOTS_CACHE_KEY, JSON.stringify(updatedRobots), {
+ EX: movingRobots.size === 0 ? CACHE_TTL : undefined,
+ });
+
// Websocket broadcast, make sure robots stay in correct order
updatedRobots.sort((a, b) => a.id - b.id);
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 6a79969..41e8803 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -3030,9 +3030,9 @@
}
},
"node_modules/react-router": {
- "version": "7.11.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.11.0.tgz",
- "integrity": "sha512-uI4JkMmjbWCZc01WVP2cH7ZfSzH91JAZUDd7/nIprDgWxBV1TkkmLToFh7EbMTcMak8URFRa2YoBL/W8GWnCTQ==",
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz",
+ "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
@@ -3052,12 +3052,12 @@
}
},
"node_modules/react-router-dom": {
- "version": "7.11.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.11.0.tgz",
- "integrity": "sha512-e49Ir/kMGRzFOOrYQBdoitq3ULigw4lKbAyKusnvtDu2t4dBX4AGYPrzNvorXmVuOyeakai6FUPW5MmibvVG8g==",
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.0.tgz",
+ "integrity": "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==",
"license": "MIT",
"dependencies": {
- "react-router": "7.11.0"
+ "react-router": "7.13.0"
},
"engines": {
"node": ">=20.0.0"
diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx
index b1b38e4..807d4e3 100644
--- a/frontend/src/pages/Dashboard.tsx
+++ b/frontend/src/pages/Dashboard.tsx
@@ -33,12 +33,6 @@ function Dashboard() {
// Request robot data from backend on component mount
useEffect(() => {
- // Additional safety check to protect this page from unauthorized access
- if (!token || token === "undefined" || token === "null") {
- navigate("/login");
- return;
- }
-
async function fetchRobots() {
try {
setIsLoading(true);