Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
02a64f2
Admin API: list connected workers and queued demand (#2804)
amankrx Sep 28, 2026
a7cc44d
Placement: least_loaded and best_fit allocation strategies, typed pro…
amankrx Sep 28, 2026
5ef7a83
Redis scheduler store: RESP3 cursor pages, the retention default, an …
amankrx Sep 28, 2026
2762510
Matching pass: room that opens mid-pass goes to the oldest waiting ac…
amankrx Sep 28, 2026
2bfa020
GoingAway with a drain flag, reconnect backoff with jitter, and a shu…
amankrx Sep 28, 2026
a21d82c
Dispatch is acknowledged or declined by the worker (#2808)
amankrx Sep 29, 2026
e6aa38a
Worker: kill the whole process group when an action times out or is c…
amankrx Sep 29, 2026
f10c7b7
Worker: bound output capture, upload fan-out, precondition scripts an…
amankrx Sep 29, 2026
74688d6
docs(llms): regenerate llms.txt, llms-small.txt and llms-full.txt (#2…
github-actions[bot] Sep 29, 2026
fcdccc8
Worker: soft memory enforcement against the reservation, and a disk g…
amankrx Sep 29, 2026
3ff63f1
Give the oversized-upload store tests the 30 s deadline the third alr…
amankrx Sep 29, 2026
d86ff4f
Worker advertises CPU and memory from its own cgroup limits (#2820)
amankrx Sep 29, 2026
de7a540
Worker readiness follows scheduler registration (#2821)
amankrx Sep 29, 2026
9a95e29
Worker: SIGTERM grace before the kill, output kept, a TMPDIR per acti…
amankrx Sep 29, 2026
5aa89ad
docs(llms): regenerate llms.txt, llms-small.txt and llms-full.txt (#2…
github-actions[bot] Sep 29, 2026
4fe0a27
Worker reaps the zombies actions leave behind, and an action's stragg…
amankrx Sep 29, 2026
c79e3bb
Namespaces: each action gets a private /tmp, its own tmp directory bo…
amankrx Sep 30, 2026
7bd3c54
Worker: a disk soft limit, and peak_disk_kb from the files an action …
amankrx Sep 30, 2026
3c52ee1
Scheduler: memory escalation with retry budgets by cause, the whole w…
amankrx Sep 30, 2026
035dd63
Persistent workers: a configurable pool with an idle sweeper, the act…
amankrx Sep 30, 2026
59cbad2
Historical resource scheduler: hints by digest keys, size classes wit…
amankrx Sep 30, 2026
938c56f
docs(llms): regenerate llms.txt, llms-small.txt and llms-full.txt (#2…
github-actions[bot] Sep 30, 2026
9a03932
Worker: build the cleanup mark's guard after the lock is released (#2…
amankrx Sep 30, 2026
fd6530e
Store: a read that stops short of the digest's size is an error, not …
amankrx Sep 30, 2026
b4a5468
Worker: read capacity and free memory from the worker's own cgroup di…
amankrx Sep 30, 2026
82240c6
Worker: bound the input fetch with max_download_timeout and let a kil…
amankrx Sep 30, 2026
181a1d3
Support queueing-service through an opt-in gRPC event sink (#2811)
MarcusSorealheis Sep 30, 2026
514d75e
ci: gate rbe-*/LRE lanes on affected paths, full matrix on main
b7r6 Sep 30, 2026
66dc08d
test: scheduler-only diff (expect rbe/lre lanes to skip)
b7r6 Sep 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/lre.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,41 @@ concurrency:
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
# Compute whether this diff can affect the LRE example builds. These lanes
# build @local-remote-execution//examples, so they are keyed off the LRE
# toolchain inputs. Pushes to main always run the full matrix (backstop).
changes:
name: Compute affected lanes
runs-on: ubuntu-24.04
outputs:
lre: ${{ steps.filter.outputs.lre }}
steps:
- name: Checkout
uses: >- # v6.0.2
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Filter LRE-affecting paths
uses: >- # v3.0.2
dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
id: filter
with:
filters: |
lre:
- 'local-remote-execution/**'
- 'MODULE.bazel'
- 'MODULE.bazel.lock'
- '*.bazelrc'
- 'flake.nix'
- 'flake.lock'
- 'tools/**'
- '.github/workflows/lre.yaml'
- '.github/actions/**'

local:
needs: [changes]
if: >-
github.ref == 'refs/heads/main'
|| needs.changes.outputs.lre == 'true'
strategy:
fail-fast: false
matrix:
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/nix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,45 @@ jobs:
nativelink_attic_token: ${{ secrets.NATIVELINK_ATTIC_TOKEN }}
nix_name: .#${{ matrix.test-name }}-with-nativelink-test

# Compute which lanes this diff can affect. The rbe-* lanes validate
# "does this toolchain still build through NativeLink", so they are keyed
# off the toolchain/LRE configuration inputs they consume. Pushes to main
# always run the full matrix (backstop), so no change can merge without
# the complete matrix running against it.
changes:
name: Compute affected lanes
runs-on: ubuntu-24.04
outputs:
toolchain: ${{ steps.filter.outputs.toolchain }}
steps:
- name: Checkout
uses: >- # v6.0.2
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Filter toolchain-affecting paths
uses: >- # v3.0.2
dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
id: filter
with:
filters: |
toolchain:
- 'toolchain-examples/**'
- 'local-remote-execution/**'
- 'MODULE.bazel'
- 'MODULE.bazel.lock'
- '*.bazelrc'
- 'flake.nix'
- 'flake.lock'
- 'tools/**'
- '.github/workflows/nix.yaml'
- '.github/actions/**'

# rbe-toolchain is slow because it has many subcommands, so split it out
generate-rbe-commands:
needs: [changes]
if: >-
github.ref == 'refs/heads/main'
|| needs.changes.outputs.toolchain == 'true'
runs-on: ubuntu-24.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
Expand Down
551 changes: 477 additions & 74 deletions llms-full.txt

Large diffs are not rendered by default.

56 changes: 43 additions & 13 deletions llms-small.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1653,11 +1653,12 @@ reusing a warm process, and a clear-eyed view of the isolation you trade for it.

## Two things to know before you start

**Almost nothing needs configuring in NativeLink.** No field anywhere in
[the configuration model](/configuration) turns this on, tunes the pool, or
selects a protocol; `LocalWorkerConfig` has no persistent-worker section at
all, and every pool parameter is a compiled-in constant. The feature is
driven by two platform properties on each action.
**Little needs configuring in NativeLink.** The pool is on by default and
the protocol is chosen by two platform properties on each action. The
worker's `persistent_workers` block (v1.7.3 and later) sizes it: how many
processes per key, how long an idle one lives, how many requests one serves,
how long an action at the cap waits for a process to come back, and
`enabled: false` to run every such action one-shot.

## Opt an action in

Expand All @@ -1672,13 +1673,14 @@ Actions are pooled by a key derived from the command line:

## The isolation you give up

This is the part to read twice. NativeLink applies real isolation to ordinary
actions and **applies none of it to persistent workers**. The persistent path
returns before any of it runs.
This is the part to read twice. A persistent worker process outlives the
actions it serves, so some of the isolation an ordinary action gets cannot
apply to it, and some of it did not apply until v1.7.3.

## The pool's actual behaviour

Every parameter below is a compiled-in constant. None is configurable.
The pool is configured under `persistent_workers` on the worker; every value
below is its default.

## Steps

Expand Down Expand Up @@ -3457,6 +3459,15 @@ short fix and all five are prerequisites.
Before you write a readiness probe, understand what `/status` actually
measures, because the answer is surprising in both directions.

## Readiness is a different question

`/status` answers whether the components that registered a health indicator
have failed. It stays `200` while a component is still initializing, which is
the right answer for a liveness probe and the wrong one for readiness. The
`health` service therefore also serves `/ready` (`readiness_path`, default
`/ready`), which answers `503` while anything is initializing or failed and
`200` otherwise.

## Build the deployment

<li>
Expand Down Expand Up @@ -3596,6 +3607,22 @@ in response to what the worker returns.
Several NativeLink limits queue instead of erroring, which is why "hung" is a
more common symptom than "failed":

## Every build stalls at `[Sched]` and nothing errors

Clients sit on `WaitExecution` for hours, the scheduler log is quiet apart
from `Could not find AwaitedAction for the given operation id`, idle workers
take nothing, and the provisioner reads demand as zero. The scheduler's
records are being evicted from Redis.

## The scheduler's Redis keeps every completed action

**Symptom.** With the Redis scheduler backend, `DBSIZE` on the scheduler's
database grows by one `aa_*` hash per action ever run and never falls; the
records all read `completed` and `TTL` says `-1`. Once the search index holds
more than one cursor page, listings over it (the admin read the worker
provisioner makes, the scheduler admin endpoints) can fail with
`Failed to get operations list! Parse: Non map item`.

## Restarting the scheduler

Not an incident so much as a procedure that behaves worse than you expect.
Expand Down Expand Up @@ -3958,8 +3985,8 @@ Every property key a worker advertises has a declared type:

## Retries, and what "failed" means

The attempt counter is incremented by two different events, with different
rules.
The attempt counter is incremented by one event, and two other events that
used to spend it now have budgets of their own.

### Two timeouts with very different defaults

Expand Down Expand Up @@ -4100,8 +4127,11 @@ result computed with a different value of it.
### Actions can run more than once

The default `max_job_retries` of 3 is checked strictly, so an action may
execute **four** times. A worker disconnect always costs an attempt; a
`ResourceExhausted` never does.
execute **four** times on its own failures. A lost worker has its own budget,
`max_worker_loss_retries` (default 10), and a memory escalation its own
(`memory_escalation.max_steps`, default 8), so an action can run more often
than four times when workers die under it or it keeps outgrowing its
reservation; a `ResourceExhausted` never costs anyth…

### Some output metadata is discarded

Expand Down
Loading
Loading