From 0a6c155dca7936cade21d3633d04bedcb77924f5 Mon Sep 17 00:00:00 2001 From: pat-s Date: Mon, 31 Aug 2026 12:52:29 +0000 Subject: [PATCH] feat(cdn): enable per-R-minor routing in production (#184) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation Everything built today is unreachable until this is set. ``` > install.packages("rlang") trying URL 'https://cran.rpkgs.com/amd64/resolute/latest/src/contrib/rlang_1.3.0.tar.gz' > library(rlang) undefined symbol: SETLENGTH ``` No `4.6/` in that path. With `UNION_SLOTS` empty the client resolves against the generic index and never reaches a per-minor binary: | artifact | size | |---|---| | generic, R 4.5-built | **2079570** — what R downloaded | | `4.6/`, R 4.6-built | 2075106 — correct, unused | The working binary has existed since 12:13 today. Nothing routes anyone to it. ## Change Sets production `UNION_SLOTS` to all 16 slots, from the same `local.rpkgs_slots` the staging zone uses. ## Verified before enabling Against the staging zone, which runs the identical script against the identical origin: | check | result | |---|---| | regressions against the generic slot | 0 across all 16 slots | | R minor served the per-minor index | 48/48 | | excluded R minor sent to CRAN | 16/16 | | client with no R minor still gets generic | 16/16 | | tarball never rewritten | 16/16 | ## Trade-off, stated plainly Coverage on a non-primary minor drops where the per-minor build backlog has not been worked off. `amd64/resolute` serves a 4.6 client 22169 packages rather than the generic slot's 24310. Those ~2100 are ABI-risky packages built under another R minor. They are exactly the ones that would install and then fail at load, so the drop trades a confusing runtime crash for an honest "not available". It shrinks as the 4.6 builds land. If that trade is unwelcome for some slots, `local.rpkgs_slots` can be narrowed to a subset — `amd64/rhel10` and `amd64/alpine323` have the smallest backlogs — and widened as builds catch up. ## After applying ```sh BASE=https://cran.rpkgs.com scripts/verify-r-minor-routing.sh --live ``` and the reported case directly: ```sh docker run --rm --platform linux/amd64 reg.devxy.io/r/r-ubuntu:4.6-resolute \ R -q -e 'install.packages("rlang"); library(rlang); cat("loaded OK\n")' ``` Reviewed-on: https://git.devxy.io/devxy/build-cran-binaries/pulls/184 --- cdn.tf | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cdn.tf b/cdn.tf index 349486e..df30273 100644 --- a/cdn.tf +++ b/cdn.tf @@ -89,9 +89,19 @@ resource "bunnynet_compute_script" "rpkgs_router" { # slot that is not listed here would hide every package the per-minor index does # not carry, so this stays empty until a slot has been backfilled. resource "bunnynet_compute_script_variable" "rpkgs_router_union_slots" { - script = bunnynet_compute_script.rpkgs_router.id - name = "UNION_SLOTS" - default_value = "" + script = bunnynet_compute_script.rpkgs_router.id + name = "UNION_SLOTS" + # Enabled. Until this was set, every client resolved against the generic + # index and never reached a per-minor binary: an R 4.6.1 client on resolute + # downloaded the 4.5-built rlang (2079570 bytes) while the correct 4.6 build + # (2075106 bytes) sat unused one directory away, and died at load with + # `undefined symbol: SETLENGTH`. + # + # Verified before enabling, against the staging zone with the same script and + # the same origin: all 16 slots report zero regressions against the generic + # slot, an excluded R minor is sent to CRAN, a client without an R minor + # still gets the generic index, and tarball requests are never rewritten. + default_value = join(",", local.rpkgs_slots) required = false }