chadtmiller.com/knotless
git that lives in your Atmosphere account
1
10
Each run on the runner host has 10 GiB, and builds a crate for each 4
.knotless/workflows/deploy.yml+1−1
| @@ -80,7 +80,7 @@ env: | ||
KNOTLESS_RUNNER_ARGS: --queue --unmetered did:plc:bcgltzqazw5tb6k2g3ttenbj --unmetered did:plc:e7rftrdyz5e2rw4y6ocszew2 --trust did:plc:bcgltzqazw5tb6k2g3ttenbj --trust did:plc:e7rftrdyz5e2rw4y6ocszew2 --pull-jobs 4 | ||
KNOTLESS_RUNNER_CPUS: "4" | ||
KNOTLESS_RUNNER_JOBS: "4" | ||
KNOTLESS_RUNNER_MEMORY: "7" | ||
KNOTLESS_RUNNER_MEMORY: "10" | ||
# The oldest client this asks for: 0.6.0 deletes a deleted ref's record | ||
# and starts a new ref at the time, and an older client making a branch | ||
# again under a name deleted within the day can have its pushes refused. | ||
deploy/runner-host/README.md+4−4
| @@ -169,7 +169,7 @@ rest name [the trusted runner](#the-trusted-runner). In | ||
```sh | ||
KNOTLESS_RUNNER_ARGS="--queue --unmetered did:plc:bcgltzqazw5tb6k2g3ttenbj --trust did:plc:bcgltzqazw5tb6k2g3ttenbj --pull-jobs 4" | ||
KNOTLESS_RUNNER_JOBS=4 | ||
KNOTLESS_RUNNER_MEMORY=7 | ||
KNOTLESS_RUNNER_MEMORY=10 | ||
KNOTLESS_RUNNER_CPUS=4 | ||
``` | ||
| ||
| @@ -184,12 +184,12 @@ lets pulls take every job, not half. Its `test` workflow builds every | ||
test binary with coverage and starts PDSes, which takes more than the | ||
default 3 GiB a run: past it the sandbox is killed | ||
(`containerManager.WaitPID failed: EOF` in the log, an OOM kill of | ||
`gvisor_sentry` in `dmesg`). So four jobs of 7 GiB and 4 CPUs each, on a | ||
`gvisor_sentry` in `dmesg`). So four jobs of 10 GiB and 4 CPUs each, on a | ||
dedicated 6-core, 12-thread, 64 GB host (an AX41), which share its threads | ||
only when all four are busy. Within them, cargo would still start a rustc for | ||
each of the host's cores, and knotless-serve's takes near 3 GiB under | ||
each of the host's cores, and knotless-serve's takes more than 3 GiB under | ||
coverage: `harness/cov.mjs` builds as many crates at once as the | ||
cgroup's CPUs, and one for each 2.5 GiB of its memory at most, so 2 here | ||
cgroup's CPUs, and one for each 4 GiB of its memory at most, so 2 here | ||
(`rustc` killed by `oom-killer` in `dmesg` is this, past those). | ||
knotless names this runner's account first among its `runners` | ||
(`knotless runners knotless://chadtmiller.com/knotless`), so it lands | ||
harness/cov.mjs+5−4
| @@ -115,9 +115,10 @@ for (const [, k, v] of shown.stdout.matchAll(/^export ([A-Z_0-9]+)=(.*)$/gm)) | ||
// container held to fewer CPUs and less memory than the host has, as a | ||
// runner's --cpus and --memory hold it: on an 8-core host, in 4 CPUs and | ||
// 7 GiB, eight rustc at once, knotless-serve's near 3 GiB among them, | ||
// were killed for memory. So where the cgroup limits it, the build takes | ||
// as many at once as the CPUs it is given, and one for each 2.5 GiB at | ||
// most. CARGO_BUILD_JOBS, set, is kept. | ||
// were killed for memory, and later two at once, as its lib and its tests | ||
// grew past that. So where the cgroup limits it, the build takes as many | ||
// at once as the CPUs it is given, and one for each 4 GiB at most. | ||
// CARGO_BUILD_JOBS, set, is kept. | ||
const cgroup = (file) => { | ||
try { | ||
return readFileSync(join('/sys/fs/cgroup', file), 'utf8').trim() | ||
| @@ -130,7 +131,7 @@ const buildJobs = () => { | ||
const memory = cgroup('memory.max') | ||
const caps = [] | ||
if (quota !== 'max') caps.push(Math.floor(Number(quota) / Number(period))) | ||
if (memory !== 'max') caps.push(Math.floor(Number(memory) / (2.5 * 2 ** 30))) | ||
if (memory !== 'max') caps.push(Math.floor(Number(memory) / (4 * 2 ** 30))) | ||
return caps.length ? Math.max(1, Math.min(...caps)) : undefined | ||
} | ||
const limited = buildJobs() | ||