Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b3e4746
Introduce safe warm workers
MarcusSorealheis Nov 15, 2025
94924a0
Merge branch 'main' into remote-persistent-safe
MarcusSorealheis Nov 16, 2025
f8071ef
fix: Pin crc-fast to 1.3.0 to avoid unstable feature requirements
MarcusSorealheis Nov 17, 2025
72f3a04
fix: Downgrade AWS SDK packages and crc-fast for Rust 1.87.0 compatib…
MarcusSorealheis Nov 17, 2025
4202683
fix: Ensure protoc is available in CI environments
MarcusSorealheis Nov 17, 2025
ec0b6a2
Merge branch 'main' into remote-persistent-safe
MarcusSorealheis Nov 17, 2025
bf5236f
Merge branch 'main' into remote-persistent-safe
MarcusSorealheis Nov 19, 2025
f7a1f95
fix flakes
MarcusSorealheis Nov 19, 2025
335c90d
fix coverage
MarcusSorealheis Nov 19, 2025
7003259
update-docs
MarcusSorealheis Nov 20, 2025
0abc78b
matcher-based routing and toolchain/version alignment
MarcusSorealheis Dec 11, 2025
3866934
Merge branch 'main' into remote-persistent-safe
MarcusSorealheis Dec 11, 2025
2ad31df
Merge remote-tracking branch 'origin/main' into remote-persistent-safe
MarcusSorealheis May 3, 2026
3537475
Add Java warm-worker isolation test
MarcusSorealheis May 3, 2026
d7b46b9
merge main and update docs
MarcusSorealheis May 3, 2026
4c9b16e
Merge branch 'main' into remote-persistent-safe
MarcusSorealheis May 3, 2026
10bcb94
Repair merge: dedupe [features], align hyper to lockfile, refresh MOD…
MarcusSorealheis May 3, 2026
a0bff67
rustfmt: split runtime use group in cri_client_grpc.rs
MarcusSorealheis May 3, 2026
023e8e3
Add Swift warm-worker pool: language enum, image, example, docs
MarcusSorealheis May 3, 2026
02f2253
Add TypeScript COW isolation test + standalone typescript-pool example
MarcusSorealheis May 3, 2026
84b5fbe
buildifier: disable canonical-repository warning in crio-worker-pool …
MarcusSorealheis May 3, 2026
97d0383
docker: fix TypeScript and Swift worker image build errors
MarcusSorealheis May 3, 2026
20aad88
ci: add fallback = true to Nix config in prepare-nix action
MarcusSorealheis May 3, 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
2 changes: 2 additions & 0 deletions .github/actions/prepare-nix/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ runs:
DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25
with:
source-tag: v3.13.0
extra-conf: |
fallback = true

- name: Setup attic cache
uses: >- # v4
Expand Down
13 changes: 13 additions & 0 deletions .github/styles/config/vocabularies/TraceMachina/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Bazelisk
Cloudflare
Colab
composable
containerd
CPUs
[Dd]eduplication
eviction_policy
Expand Down Expand Up @@ -122,6 +123,18 @@ Brex
Citrix
Menlo
benchmarked
[Rr]epos
[Dd]ockerfile
Dev
max_workers
min_warm_workers
crictl
runtimes
enum
crypto
devs
sudo
fs
Thanos
Quickwit
[Mm]iddleware
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/native-cargo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ jobs:
run: rustup update && rustup default ${{ matrix.toolchain }}
shell: bash

- name: Install protoc
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get update && sudo apt-get install -y protobuf-compiler
elif [ "$RUNNER_OS" == "Windows" ]; then
choco install protoc
fi
shell: bash

- name: Rust cache
# https://github.com/Swatinem/rust-cache/releases/tag/v2.9.1
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/sanitizers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
- name: Free disk space
uses: ./.github/actions/free-disk

- name: Install protoc
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
shell: bash

- name: Setup Bazel
uses: >- # v0.19.0
bazel-contrib/setup-bazel@c5acdfb288317d0b5c0bbd7a396a3dc868bb0f86
Expand Down
5 changes: 5 additions & 0 deletions .hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
ignored:
- DL3008 # Pin versions in apt get install
- DL3016 # Pin versions in npm install
- DL3018 # Pin versions in apk add
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exclude = [
"nativelink-config/generate-stores-config",
"tools/generate-bazel-rc",
]
members = ["nativelink-crio-worker-pool"]
resolver = "2"

[package]
Expand All @@ -28,6 +29,7 @@ name = "nativelink"

[features]
nix = ["nativelink-worker/nix"]
warm-worker-pools = ["nativelink-scheduler/warm-worker-pools"]

[dependencies]
nativelink-config = { path = "nativelink-config" }
Expand Down
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ crate.from_cargo(
cargo_lockfile = "//:Cargo.lock",
manifests = [
"//:Cargo.toml",
"//nativelink-crio-worker-pool:Cargo.toml",
"//nativelink-config:Cargo.toml",
"//nativelink-error:Cargo.toml",
"//nativelink-macro:Cargo.toml",
Expand Down
274 changes: 267 additions & 7 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

190 changes: 190 additions & 0 deletions deployment-examples/warm-worker-pools.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Example NativeLink configuration with warm worker pools
// This demonstrates how to configure CRI-O based warm worker pools
// for faster build times with Java and TypeScript projects.
//
// ISOLATION FEATURE:
// Warm worker pools support Copy-on-Write (COW) isolation to prevent
// state leakage between jobs. When enabled via isolation.strategy="overlayfs",
// each job gets an isolated filesystem using OverlayFS:
// - Template (lower layer): Read-only base from warmed-up worker
// - Job workspace (upper layer): Ephemeral read-write layer per job
// - Automatic cleanup: Job workspace deleted after completion
//
// Benefits:
// - Security: No cross-tenant contamination
// - Performance: Fast cloning vs cold starts (30-45s warmup → <500ms clone)
// - Resource efficiency: One template serves many isolated jobs
//
// Recommended for production deployments with multi-tenant workloads.
{
schedulers: {
// Main scheduler with warm worker pools enabled
main: {
simple: {
// Standard scheduler configuration
supported_platform_properties: {
cpu_count: "minimum",
cpu_arch: "exact",
lang: "exact",
},

// Warm worker pool configuration
// This requires the "warm-worker-pools" feature to be enabled
warm_worker_pools: {
pools: [
// Java/JVM worker pool
{
name: "java-pool",
language: "jvm",

// CRI-O socket path (Unix domain socket)
cri_socket: "unix:///var/run/crio/crio.sock",

// Container image with pre-installed JVM and build tools
container_image: "ghcr.io/tracemachina/nativelink-worker-java:latest",

// Pool sizing
min_warm_workers: 5, // Keep at least 5 workers warmed up
max_workers: 50, // Maximum 50 workers total

// Warmup configuration
warmup: {
// Commands to run when container starts (warms up JVM)
commands: [
{
argv: [
"/opt/warmup/jvm-warmup.sh",
],
timeout_s: 60,
},
],

// Commands to run after each job completes
post_job_cleanup: [
{
// Force garbage collection between jobs
argv: [
"jcmd",
"1",
"GC.run",
],
timeout_s: 30,
},
],
},

// Worker lifecycle management
lifecycle: {
// Recycle workers after 1 hour
worker_ttl_seconds: 3600,

// Recycle workers after 200 jobs
max_jobs_per_worker: 200,

// Run GC every 20 jobs
gc_job_frequency: 20,
},

// Isolation configuration (RECOMMENDED for production)
// Provides Copy-on-Write filesystem isolation between jobs
isolation: {
// Strategy: "overlayfs" for COW isolation, "none" for shared state (backward compatible)
strategy: "overlayfs",

// Path where warm templates are stored (read-only base layer)
template_cache_path: "/var/lib/nativelink/warm-templates",

// Path where job-specific workspaces are created (ephemeral write layers)
job_workspace_path: "/var/lib/nativelink/warm-jobs",
},
},

// TypeScript/Node.js worker pool
{
name: "typescript-pool",
language: "node",
cri_socket: "unix:///var/run/crio/crio.sock",
container_image: "ghcr.io/tracemachina/nativelink-worker-node:latest",
min_warm_workers: 3,
max_workers: 30,
warmup: {
commands: [
{
argv: [
"/opt/warmup/v8-warmup.sh",
],
timeout_s: 45,
},
],
post_job_cleanup: [
{
// Clear V8 heap between jobs
argv: [
"node",
"--expose-gc",
"-e",
"global.gc()",
],
timeout_s: 20,
},
],
},
lifecycle: {
worker_ttl_seconds: 1800, // 30 minutes
max_jobs_per_worker: 100,
gc_job_frequency: 10,
},

// Isolation configuration
isolation: {
strategy: "overlayfs",
template_cache_path: "/var/lib/nativelink/warm-templates",
job_workspace_path: "/var/lib/nativelink/warm-jobs",
},
},
],
},
},
},
},

// Store configuration (same as standard NativeLink)
stores: {
// ... your store configuration here
},

// Server configuration
servers: [
{
listener: {
http: {
socket_address: "0.0.0.0:50051",
},
},
services: {
ac: {
main: {
ac_store: "ac_store",
},
},
cas: {
main: {
cas_store: "cas_store",
},
},
execution: {
main: {
scheduler: "main",
},
},
capabilities: {
main: {
remote_execution: {
scheduler: "main",
},
},
},
},
},
],
}
Loading
Loading