Skip to content

ref(builds-cacher): cache-only Node server + API libc-filter fix#1075

Merged
coolaj86 merged 3 commits into
mainfrom
ref-cache-only-readonly
May 8, 2026
Merged

ref(builds-cacher): cache-only Node server + API libc-filter fix#1075
coolaj86 merged 3 commits into
mainfrom
ref-cache-only-readonly

Conversation

@coolaj86
Copy link
Copy Markdown
Member

@coolaj86 coolaj86 commented May 7, 2026

Summary

  • Node server reads exclusively from ~/.cache/webi/legacy/<name>.json
  • Removes every code path that fetched upstream or wrote to the cache
  • Webicached (Go daemon) is now the sole writer; this server is a thin reader
  • Fix /api/releases filtering musl entries when the caller didn't pin a libc

What changed

_webi/builds-cacher.js:

  • Resolves cache files via Os.homedir() + '/.cache/webi/legacy/' instead of the cacheDir/caches argument.
  • Drops getLatestBuilds / getLatestBuildsInner — they require()d per-package releases.js, fetched upstream, and wrote <yyyy-mm>/<name>.json + .updated.txt to disk.
  • Drops the process.nextTick stale-refresh hook in _doGetPackages. Cold reads return what's on disk; if the file is missing, return empty meta instead of fetching.
  • Drops freshenRandomPackage and supporting state (bc._staleNames, bc._freshenTimeout, bc._staleAge). The hourly background freshener was competing with webicached for the same files.
  • In getProjectTypeByEntry, decides selfhosted vs valid by probing for the cache file rather than require()-ing releases.js.

_webi/transform-releases.js:

  • Drops Releases.get and the _normalize import.
  • Replaces getCachedReleases's fetch+race+stale-age machinery with a single Fs.readFile of ~/.cache/webi/legacy/<pkg>.json.
  • fix(api): the libc filter ran unconditionally — even when the caller didn't pin a libc, the default libc='libc' from serve-releases.js was triggering it and stripping every libc=musl entry from listings. Treat the catch-all 'libc' value as 'no preference' so the website's release table and the WEBI_RELEASES probe see what the cache actually contains. Specific ?libc=musl / ?libc=gnu queries still filter exactly as before.

_webi/build-classifier:

  • Submodule pin bumped to v1.0.3 (the Lexver.parsePrefix zero-padding fix for <pkg>@<exact-version-with-suffix> queries).

No public signatures change. Per-package releases.js, _common/*.js, and _webi/normalize.js still exist on disk but are no longer reachable from the request path (cleanup follows in a separate PR).

Test plan (verified against https://webinstall.dev/)

  • ~/.cache/webi/legacy/ exists on prod and is populated (100 packages).
  • curl https://webinstall.dev/api/releases/go.json?limit=1 returns valid version (1.26.3, not 0.0.0).
  • curl -A 'curl/8.5 Linux x86_64' https://webinstall.dev/node returns #!/bin/sh installer.
  • Unfiltered listing returns the non-error shape (libc-fix verified on beta where the cache contains musl-tagged entries: 40 none / 44 gnu / 16 musl). On prod the cache currently has 0 musl-tagged entries (50 none / 50 gnu) because webicached classifies static-musl Rust builds as libc=none. The fix is forward-looking once musl-tagged entries land in prod's cache.
  • ?libc=musl strict-filter test (curl '…&libc=musl&limit=5') is not reachable as written: webinstall.dev/lib/serve-releases.js:37 runs the libc query through UaDetect.arch() which mangles non-arch strings to 'error' before reaching this filter. Separate fix needed in that file (out of scope here).
  • Server-log audit and "no writes under ~/.cache/webi/ from the Node process" are deploy-host checks the maintainer will confirm.

@coolaj86 coolaj86 force-pushed the ref-cache-only-readonly branch 21 times, most recently from b063c35 to 4c35147 Compare May 8, 2026 04:08
Comment thread _webi/builds-cacher.js
@coolaj86 coolaj86 changed the title ref(builds-cacher): cache-only Node server, no fetches or writes ref(builds-cacher): cache-only Node server + API libc-filter fix May 8, 2026
@coolaj86 coolaj86 force-pushed the ref-cache-only-readonly branch 2 times, most recently from 3c1eb8a to b1d340e Compare May 8, 2026 17:42
coolaj86 added 3 commits May 8, 2026 11:48
Make _webi/builds-cacher.js and _webi/transform-releases.js read
exclusively from ~/.cache/webi/legacy/<name>.json and remove every code
path that fetched from upstream or wrote to disk. The Go cache daemon
(webicached) is now the sole writer; the Node server is a thin reader.

builds-cacher.js:
- Resolve cache files via Os.homedir() + '/.cache/webi/legacy/' instead
  of the cacheDir argument. Drop the 'caches' constructor parameter.
- Remove getLatestBuilds / getLatestBuildsInner — they require()d
  per-package releases.js modules, fetched upstream, and wrote
  <yyyy-mm>/<name>.json + .updated.txt to disk.
- Remove the process.nextTick stale-refresh hook in _doGetPackages.
  Cold reads return what's on disk; if the file is missing, return
  empty meta instead of fetching.
- Remove freshenRandomPackage and its supporting state
  (bc._staleNames, bc._freshenTimeout, bc._staleAge). The hourly
  background freshener competed with webicached for the same files.
- In getProjectTypeByEntry, decide selfhosted vs valid by probing for
  the cache file rather than require()-ing releases.js. Drop the
  not_found / 'PROBLEM/SOLUTION/npm clean-install' diagnostic in
  getProjectsByType — the cache-file probe replaces the module-load
  failure mode.

transform-releases.js:
- Remove Releases.get and the _normalize import. Replace
  getCachedReleases's fetch+race+stale-age machinery with a single
  Fs.readFile of ~/.cache/webi/legacy/<pkg>.json.
- Drop the in-process version re-sort in createFormatsSorter; the
  cache file is already version-sorted by webicached, so the sorter
  only re-orders within the same version.

No callers' public signatures change. Every other file is untouched —
the per-package releases.js modules, _common/*.js fetchers, and
_webi/normalize.js still exist on disk but are no longer reachable
from the request path.
Lexver.parsePrefix now produces a true string-prefix of parseVersion
when the input has a release suffix (e.g. '1.0.0-beta',
'2025.11.15-15.42.45'). Unblocks pinned-version queries with a
non-trivial release suffix, including the 'webi zig.vim' alias chain
which redirects through 'vim-zig@2025.11.15-15.42.45' at install time.

See webinstall/webi-build-classifier#22.
filterReleases unconditionally rejected libc=musl entries unless the
host was libc=musl, even when the caller never specified a libc in
the request. serve-releases.js defaults the libc parameter to 'libc'
(the catch-all glibc-host bucket the installer-side resolver uses),
so the website's release table and the WEBI_RELEASES probe were both
stripped of every musl entry that the cache actually contained — even
though the installer would happily consider those builds on a glibc
host (its waterfall is [none, gnu, musl, libc]).

Treat libc='libc' (and missing) as 'no preference' so the filter only
runs when the caller pinned a real libc (musl, gnu, msvc, etc.).
Specific-libc queries (?libc=musl, ?libc=gnu) still filter exactly as
before.
@coolaj86 coolaj86 force-pushed the ref-cache-only-readonly branch from b1d340e to 70067a6 Compare May 8, 2026 17:48
@coolaj86 coolaj86 merged commit 70067a6 into main May 8, 2026
3 checks passed
@coolaj86 coolaj86 deleted the ref-cache-only-readonly branch May 8, 2026 22:18
pull Bot pushed a commit to pianomanx/webi-installers that referenced this pull request May 14, 2026
…e cache path

The Node server's read path now goes through ~/.cache/webi/legacy/ only
(see webinstall#1075). A handful of supporting tools and tests still carried
references to the obsolete upstream-fetcher modules and the old
year-month cache layout. Update them in place; the actual deletion of
the orphaned modules follows in webinstall#1076.

- _webi/classify-one.js — read from ~/.cache/webi/legacy/<pkg>.json
  instead of ../_cache/<yearMonth>/<pkg>.json.
- _webi/builds-cacher-test.js — drop the bc.freshenRandomPackage(...)
  call; the freshener was removed when fetching went away.
- _webi/builds.js — drop the //Releases: Releases stub comment.
- _webi/lint-builds.js — drop two now-unused require()s.
- _webi/test.js — adjust a single reference to the post-cleanup shape.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant