hfinfer / server.mjs
Morgan Funtowicz
Support partitioned data layout, replace bar charts with line charts
482cab0
Raw History Blame
4.68 kB
// Production server for the Docker Space. No dependencies.
//
// / -> static dashboard from dist/
// /data/* -> benchmark files from DATA_DIR (bucket volume, default ./data)
//
// /data/index.json is generated ON THE FLY by scanning DATA_DIR, so new
// .jsonl files dropped into the bucket are discovered immediately — no
// manifest regeneration, no rebuild.
import { createServer } from 'node:http'
import { createReadStream, existsSync, readdirSync, statSync } from 'node:fs'
import { extname, join, normalize, resolve, sep } from 'node:path'
import { fileURLToPath } from 'node:url'
const root = resolve(fileURLToPath(new URL('.', import.meta.url)))
const distDir = join(root, 'dist')
const dataDir = resolve(process.env.DATA_DIR ?? join(root, 'data'))
const port = Number(process.env.PORT ?? 7860)
const MIME = {
'.html': 'text/html; charset=utf-8',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.jsonl': 'application/x-ndjson',
'.svg': 'image/svg+xml',
'.png': 'image/png',
'.ico': 'image/x-icon',
'.woff2': 'font/woff2',
'.map': 'application/json',
}
function sendFile(res, file, cacheControl) {
const stream = createReadStream(file)
stream.on('data', (chunk) => {
res.bytesSent = (res.bytesSent ?? 0) + chunk.length
})
stream.on('error', (err) => {
// Never let a stream error crash the server (it would take down the Space).
console.error(`[server] failed to read ${file}:`, err.message)
if (!res.headersSent) res.writeHead(500)
res.end()
})
res.writeHead(200, {
'Content-Type': MIME[extname(file)] ?? 'application/octet-stream',
'Cache-Control': cacheControl,
})
stream.pipe(res)
}
/** Join rel onto base, refusing path traversal outside base. */
function safeJoin(base, rel) {
const file = normalize(join(base, rel))
return file === base || file.startsWith(base + sep) ? file : null
}
/** Recursively collect .jsonl paths under dir, prefixed with prefix. */
function collectJsonl(dir, prefix, out) {
for (const entry of readdirSync(dir).sort()) {
const full = join(dir, entry)
if (statSync(full).isDirectory()) collectJsonl(full, `${prefix}${entry}/`, out)
else if (entry.endsWith('.jsonl')) out.push(`${prefix}${entry}`)
}
return out
}
/**
* Scan DATA_DIR and build the categories manifest. Category directories are
* walked recursively to support the partitioned layout
* (<category>/<host>/<date>/<name>.jsonl) alongside legacy flat files.
*/
function buildManifest() {
const categories = {}
if (existsSync(dataDir)) {
for (const entry of readdirSync(dataDir).sort()) {
const full = join(dataDir, entry)
if (statSync(full).isDirectory()) {
const files = collectJsonl(full, `${entry}/`, [])
if (files.length > 0) categories[entry] = files
} else if (entry.endsWith('.jsonl')) {
;(categories.models ??= []).push(entry)
}
}
}
return { categories }
}
createServer((req, res) => {
const start = Date.now()
res.on('finish', () => {
console.log(
`[http] ${req.method} ${req.url} -> ${res.statusCode} ${res.bytesSent ?? 0}B (${Date.now() - start}ms)`
)
})
try {
handle(req, res)
} catch (err) {
// Never crash the process on a single bad request.
console.error('[server] handler error:', err)
if (!res.headersSent) res.writeHead(500)
res.end('internal error')
}
}).listen(port, '0.0.0.0', () => {
console.log(`dashboard: http://0.0.0.0:${port} (dist=${distDir}, data=${dataDir})`)
})
function handle(req, res) {
const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`)
const path = decodeURIComponent(url.pathname)
// Dynamic manifest — always reflects the current bucket contents.
if (path === '/data/index.json') {
res.writeHead(200, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store' })
res.end(JSON.stringify(buildManifest()))
return
}
// Benchmark data files (never cached: results are appended over time).
if (path.startsWith('/data/')) {
const file = safeJoin(dataDir, path.slice('/data/'.length))
if (file && existsSync(file) && statSync(file).isFile()) {
sendFile(res, file, 'no-store')
} else {
res.writeHead(404)
res.end('not found')
}
return
}
// Static dashboard, SPA fallback to index.html.
let file = safeJoin(distDir, path === '/' ? 'index.html' : path.slice(1))
if (!file || !existsSync(file) || !statSync(file).isFile()) {
file = join(distDir, 'index.html')
}
sendFile(res, file, file.includes(`${sep}assets${sep}`) ? 'public, max-age=31536000, immutable' : 'no-cache')
}