Fix a worker-blocking Lua socket call and add gzip/caching for static assets

- ops/nginx_conf/targetinfo.lua's wildcard-subdomain lookup fallback used
  classic LuaSocket (require("socket.unix")) instead of an OpenResty
  cosocket. LuaSocket is blocking, and called from an nginx worker it
  stalls the ENTIRE worker — every other in-flight connection on it — for
  the round-trip to the Node app. Worse, the Node side never
  newline-terminated its response, so the old blocking receive() only ever
  returned via its read-timeout-then-partial-read fallback, meaning every
  single cache-miss lookup paid a fixed timeout penalty while blocking the
  whole worker. Replaced with an ngx.socket.tcp() cosocket (unix-domain via
  "unix:/path", the only cosocket API this lua-nginx-module ships) and
  newline-terminated the Node service's responses so receive() actually
  completes instead of timing out. Verified against a live container:
  previously this crashed OpenResty's Lua VM entirely
  (ngx.socket.unix doesn't exist); fixed version resolves fresh wildcard
  subdomains in ~2ms.
- Add gzip compression (`compression` middleware) and far-future
  Cache-Control on static assets (7d for vendor libs under
  /static-modules, 1h for the app's own /static JS/CSS, which isn't
  cache-busted). The admin UI is a traditional multi-page app that loads
  ~13 separate vendor/app JS+CSS files on every full navigation; previously
  none of them were compressed and Cache-Control was `max-age=0` (Express's
  default), forcing a revalidation round-trip for every asset on every page
  view.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 00:41:31 -04:00
parent ad2cacf094
commit a19ff81c76
5 changed files with 138 additions and 25 deletions
+9 -1
View File
@@ -3,6 +3,7 @@
const path = require('path');
const ejs = require('ejs')
const express = require('express');
const compression = require('compression');
// Set up the express app.
const app = express();
@@ -52,8 +53,15 @@ app.onListen.push(function(){
});
});
// Gzip text responses (HTML/JS/CSS/JSON). The admin UI loads ~13 separate,
// uncompressed vendor JS/CSS files on every full page navigation (a
// traditional multi-page app, not an SPA) — this alone meaningfully cuts
// bytes-over-the-wire and perceived load time on a real network, where it
// matters far more than on localhost.
app.use(compression());
// load the JSON parser middleware. Express will parse JSON into native objects
// for any request that has JSON in its content type.
// for any request that has JSON in its content type.
app.use(express.json());
// Set up the templating engine to build HTML for the front end.