Add TTL-based expiry for wildcard subdomain cache entries

Adopt model-redis v1.5.0 and give the on-demand is_cache Host records
(and their Cached tracking records) created by Host.addCache a TTL, so
they auto-expire instead of accumulating forever. Only the record hash
carries the TTL, so OpenResty's direct HGETALL sees a miss once it
expires and re-resolves through the lookup path.

The lifetime is configurable via conf.cacheTTL (seconds, default 3600;
0 disables expiry). This also mitigates the matchAny=false "wrong host"
bug: stale leftover cache entries now expire (and are still busted on
parent update), so undefined subdomains stop being served by old caches.

Add test/unit/wildcard_matchany.test.js covering the matchAny routing
decision (defined vs undefined subdomains, mixed-policy sibling
wildcards, and cache-entry behavior) and wire it into the test scripts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 10:51:06 -04:00
parent bb9bbb1d6e
commit 7cc7f95019
5 changed files with 185 additions and 10 deletions
+9 -2
View File
@@ -50,18 +50,25 @@ class Host extends Table{
return;
}
// Give the on-demand cache entry a TTL so it auto-expires instead of
// living forever. Only the record hash carries the TTL (model-redis
// reaps the dangling index member on the next read), so OpenResty's
// direct HGETALL sees a miss once it expires and re-resolves through
// this lookup path. 0/falsy conf disables expiry.
let ttl = conf.cacheTTL > 0 ? {ttl: conf.cacheTTL} : undefined;
await this.create({
...parentOBJ,
host: host,
is_cache: true,
is_wildcard: false,
wildcard_parent: parentOBJ.host
}, true);
}, ttl);
await Cached.create({
host: host,
parent: parentOBJ.host
});
}, ttl);
}catch(error){
console.error('add cache error', {...parentOBJ, host, is_cache: true}, error);
throw error;