2 Commits
Author SHA1 Message Date
openhands 9d0da5d65a Perf: cache Nitro client assets and parallelize client page
CI / check (push) Successful in 31s
CI / release (push) Skipped
CI / deploy (push) Successful in 59s
- Serve /swf and /nitro-assets (~2.8GB) with 7-day Cache-Control plus
  stale-while-revalidate so client opens stop re-fetching hundreds of
  files while asset updates still propagate in the background
- Issue the SSO ticket and the online count query in parallel on the
  client page to shave a round-trip off the critical render path
2026-08-26 15:06:16 +02:00
openhands e7f70bb429 Chore: remove unused e2e register debug script
Flagged by knip as unused. It was a one-off DB smoke test with a
hardcoded database password that should never have been committed.
2026-08-26 15:06:14 +02:00
3 changed files with 34 additions and 75 deletions

No files matched your search

+22
View File
@@ -125,6 +125,28 @@ const nextConfig: NextConfig = {
},
],
},
{
// Nitro client payload (~2.8GB across swf/nitro-assets): without
// caching every client open re-downloads hundreds of files.
// Fresh for 7 days, then serve stale + revalidate in background
// so asset updates still propagate without blocking players.
source: "/swf/(.*)",
headers: [
{
key: "Cache-Control",
value: "public, max-age=604800, stale-while-revalidate=2592000",
},
],
},
{
source: "/nitro-assets/(.*)",
headers: [
{
key: "Cache-Control",
value: "public, max-age=604800, stale-while-revalidate=2592000",
},
],
},
{
source: "/images/(.*)",
headers: [{ key: "Cache-Control", value: "public, max-age=86400" }],
-67
View File
@@ -1,67 +0,0 @@
import { randomBytes } from "node:crypto";
import { eq } from "drizzle-orm";
import { drizzle } from "drizzle-orm/mysql2";
import { bcrypt, bcryptVerify } from "hash-wasm";
import mysql from "mysql2/promise";
import * as schema from "@/db/schema";
const url = new URL(
"mysql://cms:HeelM%3Coeikgsdgsccusygcsugy@localhost:3306/habbo",
);
const pool = mysql.createPool({
host: url.hostname,
port: Number(url.port) || 3306,
user: decodeURIComponent(url.username),
password: decodeURIComponent(url.password),
database: "habbo",
charset: "utf8mb4",
});
const db = drizzle(pool, { schema, mode: "default" });
async function main() {
const hash = await bcrypt({
password: "Test1234",
salt: randomBytes(16),
costFactor: 12,
outputType: "encoded",
});
const uname = "__e2e_test_" + Date.now();
try {
await db.insert(schema.User).values({
username: uname,
password: hash,
mail: null,
accountCreated: Math.floor(Date.now() / 1000),
ipRegister: "127.0.0.1",
ipCurrent: "127.0.0.1",
look: "hr-100-.hd-180-1.ch-255-66.lg-280-110.sh-305-62",
});
console.log("INSERT OK");
// Simuleer login-verificatie
const [user] = await db
.select()
.from(schema.User)
.where(eq(schema.User.username, uname))
.limit(1);
if (!user) throw new Error("User not found after insert");
const ok = await bcryptVerify({
password: "Test1234",
hash: user.password,
});
console.log("LOGIN VERIFY:", ok ? "OK" : "FAILED");
} catch (err) {
console.error("FAILED:", (err as Error).message);
if ((err as { cause?: Error }).cause)
console.error("CAUSE:", (err as { cause?: Error }).cause?.message);
process.exitCode = 1;
} finally {
await pool.execute(
"DELETE FROM users WHERE username LIKE '\\_\\_e2e\\_test\\_%'",
);
await pool.end();
}
}
main();
+12 -8
View File
@@ -21,15 +21,19 @@ export default async function ClientPage() {
]);
const ip = (await headers()).get("x-real-client-ip") ?? "0.0.0.0";
const ticket = await issueSsoTicket(userId, hotelName, ip);
const onlineCount = await cached("online_count", 10_000, async () => {
const [row] = await db
.select({ total: count() })
.from(User)
.where(eq(User.online, "1"));
return row?.total ?? 0;
}).catch(() => 0);
// Ticket write and online count run in parallel — the client page should
// render as fast as possible since the player is waiting for the game.
const [ticket, onlineCount] = await Promise.all([
issueSsoTicket(userId, hotelName, ip),
cached("online_count", 10_000, async () => {
const [row] = await db
.select({ total: count() })
.from(User)
.where(eq(User.online, "1"));
return row?.total ?? 0;
}).catch(() => 0),
]);
return (
<ClientView