Skip to content

release: v0.8.1 — deploy-safe busy-poll (O3) + single-shard tuning preset#393

Merged
pilotspacex-byte merged 3 commits into
mainfrom
release/v0.8.1
Jul 19, 2026
Merged

release: v0.8.1 — deploy-safe busy-poll (O3) + single-shard tuning preset#393
pilotspacex-byte merged 3 commits into
mainfrom
release/v0.8.1

Conversation

@pilotspacex-byte

@pilotspacex-byte pilotspacex-byte commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Patch release folding the post-v0.8.0 perf/correctness train (#361#392) plus a single-shard tuning preset shipped this cycle.

What's in it

Single-shard tuning preset (new work this PR)

  • --profile standalone broadened: on --features jemalloc builds it now also drops the jemalloc arena cap to 2 (single-shard has one hot allocator thread; 8 arenas are oversized). Resolved in the pre-clap allocator re-spawn scan — the only path that reaches jemalloc before init — so it's CLI-only; explicit --memory-arenas-cap always wins.
  • New annotated conf/moon-standalone.conf shipping the same tuning (durability on) as an editable config file.
  • Docs: tuning.md gains a contention-governor (auto-gating) section and drops the "pinned cores only" caveat from the busy-poll + Profiles sections; configuration.md documents --memory-thp, MOON_SPIN_ADAPTIVE, MOON_SPIN_MAX_PREEMPTS_PER_SEC; README + guides + architecture updated to say the busy-poll is safe on any host.

Rolled up from #361#392

Release mechanics

  • Cargo.toml/lock 0.8.0 → 0.8.1; CHANGELOG [Unreleased] → [0.8.1] — 2026-07-19; RELEASES.md ledger (lag 0); ROADMAP current-release + train row.

Gate (soak-first-then-tag)

Crash-matrix nightly full 46-cell matrix + ITERS=20 probabilistic soak dispatched on this RC via workflow_dispatch, both green before merge. This patch touches no crash/persistence path, but the gate is run to hold the ritual.

Verification

  • fmt clean; clippy clean on default (mimalloc) and runtime-tokio,jemalloc.
  • New scan_argv + apply_profile tests green on both matrices; conf/moon-standalone.conf smoke-tested end to end (resolved shards=1 / epoll / busy-poll 40 / appendonly everysec; PING/SET/GET).
  • Zero new unsafe.

Summary by CodeRabbit

  • New Features

    • Added conf/moon-standalone.conf and --profile standalone for deploy-safe single-shard setups.
    • Busy-poll tuning is now auto-gated for safer use on shared/contended CPU cores.
    • Standalone preset applies memory tuning when applicable (including jemalloc arena-cap via CLI/profile behavior).
  • Bug Fixes

    • Ensured --memory-arenas-cap explicitly overrides any standalone-implied arena-cap, even with tricky argument forms.
  • Documentation

    • Updated configuration, tuning, README benchmarks, roadmap, and release docs to reflect the new deploy-safety and memory tuning guidance.
    • Documented additional tuning flags and diagnostic environment knobs.
  • Release

    • Version 0.8.1 (2026-07-19).

…ip conf/moon-standalone.conf

Deliver the best single-shard tuning as one flag and one file, and retire
the pinned-cores-only caveat that the O3 contention governor made obsolete.

`--profile standalone` already filled `--shards 1`, `--io-busy-poll-us 40`,
and `--io-driver epoll`. It now additionally drops the jemalloc arena cap to
2 on `--features jemalloc` builds: a single-shard instance has one hot
allocator thread, so the baked-in `narenas:8` (sized for the multi-shard
thread-per-core layout) is oversized, and 2 arenas cut the allocator's
per-arena metadata + dirty-page RSS baseline with no contention cost at this
concurrency.

The arena cap is resolved where it must be — in the pre-clap allocator
re-spawn scan (`malloc_respawn::scan_argv`), the only path that reaches
jemalloc before its one-time init. `apply_profile` mirrors the value into the
config struct (gated to jemalloc builds) purely so the startup transparency
log stays accurate; on non-jemalloc builds the profile makes no claim about
an arena cap it cannot affect. Precedence is preserved end to end: an
explicit `--memory-arenas-cap` always beats the profile fill, in both the
pre-clap scan (`arenas_flag_seen` gate) and `apply_profile`
(`flag_was_explicit`). Because the scan runs before the conf file is merged,
a conf-file `profile standalone` sets the other three flags but not the arena
cap — consistent with the existing CLI-only rule for the two allocator flags.

New `conf/moon-standalone.conf`: an annotated, editable moon.conf shipping the
same tuning (durability on) for operators who want to keep port / maxmemory /
persistence settings alongside the preset. It documents the CLI-only arena
caveat inline.

Docs: tuning.md gains a "contention governor (auto-gating)" section and drops
the "pinned cores only" warnings from the busy-poll and Profiles sections;
configuration.md documents `--memory-thp`, `MOON_SPIN_ADAPTIVE`, and
`MOON_SPIN_MAX_PREEMPTS_PER_SEC`; the guides/configuration, README, and
scale-ha-architecture docs are updated to say the busy-poll is now safe on any
host.

Tests: scan_argv gains profile-fill + explicit-cap-wins coverage (5 cases,
both flag spellings, malformed-explicit-suppresses-fill); apply_profile gains
a jemalloc-gated explicit-cap-wins test and asserts the arena fill. Verified
green on both the default (mimalloc) and runtime-tokio,jemalloc matrices; the
conf file was smoke-tested end to end (PING / CONFIG GET / SET-GET, resolved
shards=1 / epoll / busy-poll 40 / appendonly everysec).

Refs #392 (O3 governor), docs/guides/tuning.md
author: Tin Dang <tindang.ht97@gmail.com>
… CPU-cache digest closed

Patch release folding the PRs merged after the v0.8.0 tag (#361#392) plus
the single-shard tuning preset shipped in this cycle. No new runtime code
beyond the preset — bump, ledger roll, and doc flips only.

Roll-up highlights:
- Performance / CPU (the CPU-cache digest, adjudicated end to end by
  measurement): O3 per-shard contention governor makes --io-busy-poll-us
  deploy-safe on any host (#392); auxiliary threads re-pinned off shard cores
  (O5, #388); --memory-thp added as permanently-opt-in (O4, #387) after a
  soak DISQUALIFIED a default flip (#390); value-line prefetch (O1, #389) and
  a lock-free Notify swap (O2, #391) both rejected by measurement and recorded
  as dead ends. Idle-tick CPU trimmed to ~0.5–0.9% (#375/#378).
- Correctness: multi-shard SWAPDB durable + abort-safe before +OK (#385);
  cold recovery re-attaches spilled keys to their own database (#383); SCAN
  stable-key guarantee + O(COUNT) hot pages + cold range-resume under offload
  (#379/#380/#382); data-dir instance lock (#363); DBSIZE/SCAN cold-plane
  visibility under offload (#362/#367); DashTable double-NeedsSplit recovery
  panic fixed.
- Single-shard tuning: --profile standalone broadened + conf/moon-standalone.conf;
  tuning/configuration/README docs updated for the now-safe-everywhere busy-poll.

Release gate: crash-matrix nightly full 46-cell matrix + ITERS=20 soak
dispatched on the RC via workflow_dispatch, both green before merge
(soak-first-then-tag). This patch touches no crash/persistence path, but the
gate is run to hold the ritual.

- Cargo.toml/Cargo.lock: 0.8.0 → 0.8.1
- CHANGELOG.md: [Unreleased] rolled to [0.8.1] — 2026-07-19
- RELEASES.md: v0.8.1 ledger entry (lag 0)
- ROADMAP: current-release header + release-train row

Refs RELEASES.md, docs/roadmap/ROADMAP.md
author: Tin Dang <tindang.ht97@gmail.com>
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97b924b5-7793-496c-a4c4-ff68ec725c15

📥 Commits

Reviewing files that changed from the base of the PR and between 09a4539 and 70d2f62.

📒 Files selected for processing (3)
  • conf/moon-standalone.conf
  • docs/guides/tuning.md
  • src/config.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • conf/moon-standalone.conf
  • docs/guides/tuning.md

📝 Walkthrough

Walkthrough

Moon v0.8.1 adds a single-shard standalone configuration preset, updates busy-polling guidance for shared hosts, applies a CLI-only jemalloc arena-cap default with explicit precedence, and updates release metadata and documentation.

Changes

Standalone profile behavior

Layer / File(s) Summary
Standalone profile application
src/config.rs
Documents that allocator arena-cap changes occur before profile application and tests that apply_profile leaves the parsed arena cap unchanged and unreported.
Allocator argument pre-scan
src/malloc_respawn.rs
Recognizes --profile standalone and applies arena-cap 2 only when no explicit arena-cap flag is present, including malformed explicit values.
Configuration preset and tuning guidance
conf/moon-standalone.conf, docs/configuration.md, docs/guides/*.md, README.md, docs/roadmap/scale-ha-architecture.md
Adds the standalone configuration and documents auto-gated busy-polling, diagnostic environment variables, profile expansion, and CLI-only arena-cap behavior.
v0.8.1 release metadata
Cargo.toml, CHANGELOG.md, RELEASES.md, docs/roadmap/ROADMAP.md
Updates the package version and records the v0.8.1 release and standalone preset changes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant scan_argv
  participant ServerConfig
  CLI->>scan_argv: Pass --profile standalone
  scan_argv->>scan_argv: Detect explicit --memory-arenas-cap
  scan_argv->>ServerConfig: Provide arena cap 2 when no explicit flag exists
  ServerConfig->>ServerConfig: Apply standalone profile fields
Loading

Possibly related PRs

  • pilotspace/moon#387: Both changes modify the allocator argument pre-scan and arena-cap override resolution.

Suggested reviewers: tindang97

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main release and preset changes in this pull request.
Description check ✅ Passed The description is detailed and covers summary, performance impact, release mechanics, verification, and notes, though not in the exact template order.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/v0.8.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/config.rs (1)

331-339: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Refactor to adhere to the 1500-line file size limit.

This file currently exceeds 2900 lines. As per coding guidelines, each Rust file must be kept at or below 1500 lines. Consider splitting the configuration logic into smaller, dedicated modules to improve maintainability and strictly adhere to this limit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config.rs` around lines 331 - 339, Split the configuration logic in
config.rs into dedicated Rust modules so every resulting file is at or below the
1500-line limit. Preserve the existing public configuration API, behavior,
profile handling, and startup validation while relocating cohesive logic and
updating module references accordingly.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/config.rs`:
- Around line 331-339: Split the configuration logic in config.rs into dedicated
Rust modules so every resulting file is at or below the 1500-line limit.
Preserve the existing public configuration API, behavior, profile handling, and
startup validation while relocating cohesive logic and updating module
references accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b3dc4a42-0906-418a-a938-bbbc7ad4edc4

📥 Commits

Reviewing files that changed from the base of the PR and between 9e4dbab and 09a4539.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • CHANGELOG.md
  • Cargo.toml
  • README.md
  • RELEASES.md
  • conf/moon-standalone.conf
  • docs/configuration.md
  • docs/guides/configuration.md
  • docs/guides/tuning.md
  • docs/roadmap/ROADMAP.md
  • docs/roadmap/scale-ha-architecture.md
  • src/config.rs
  • src/malloc_respawn.rs

…for conf-file profiles

Adversarial review of the standalone-preset commit found a HIGH-severity
defect (empirically reproduced): when `profile standalone` is set as a KEY in
a moon.conf, `apply_profile` still filled `memory_arenas_cap = 2` and logged
"set --memory-arenas-cap=2", but the pre-clap allocator re-spawn
(`malloc_respawn::scan_argv`) only sees the RAW command line — never the
conf-merged token stream — so jemalloc actually stayed at narenas:8. That
produced two contradictory startup log lines (the profile claim, then
`warn_if_conf_only_overrides` firing "has NO effect") and falsified the
commit/docs claim that a conf-file profile does not set the arena cap. Root
cause: clap reports both CLI- and conf-sourced `--profile` as `CommandLine`
on the merged argv, so apply_profile cannot distinguish them — only the raw
pre-merge scan can.

Fix: `apply_profile` no longer touches `memory_arenas_cap` at all. The
allocator re-spawn is the single source of truth for the arena cap (it
correctly honors only the CLI form, since jemalloc initialises before the
conf file is parsed). This removes the false claim and the spurious warning,
and makes the docs accurate. It also dissolves the review's secondary
literal-drift finding: `STANDALONE_PROFILE_ARENAS` (malloc_respawn) is now the
sole `2`, no longer mirrored across the lib/bin crate boundary.

Behaviour after the fix (verified on a runtime-tokio,jemalloc build):
- `moon --profile standalone` (CLI): re-spawn sets
  `_RJEM_MALLOC_CONF=narenas:2`, `MOON_ARENAS_CAP_APPLIED=1` — jemalloc really
  runs 2 arenas; no false log, no warning.
- `profile standalone` as a conf key: no re-spawn env, jemalloc stays at 8,
  no arena-cap claim, no spurious warning — matching the docs.

Docs: the tuning.md startup-log example drops the arena-cap field (it was
never in the fields list); `conf/moon-standalone.conf` gains an explicit note
that `profile standalone` as a conf key does not apply the arena cap; the
config.rs profile doc comment states the cap is applied by the re-spawn on the
CLI form only. Tests: `test_profile_standalone_fills_unset_fields` now asserts
`apply_profile` leaves the cap at its default and never lists it in the fields
log; the obsolete jemalloc-mirroring test is removed (arena precedence is
covered by `scan_argv`'s own tests).

Refs review of 7ba7762
author: Tin Dang <tindang.ht97@gmail.com>
@pilotspacex-byte
pilotspacex-byte merged commit 3f99f50 into main Jul 19, 2026
13 checks passed
@TinDang97
TinDang97 deleted the release/v0.8.1 branch July 19, 2026 16:09
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.

2 participants