feat(threads): observable priority chain + verifier script#183
Open
CGMossa wants to merge 7 commits into
Open
Conversation
Keats
reviewed
May 1, 2026
| const DEFAULT_MAX_THREADS: usize = 16; | ||
| /// Maximum thread count threshold if `DVS_NUM_THREADS` is set | ||
| const ENV_MAX_THREADS: usize = 32; | ||
| const ENVIRONMENT_MAX_THREADS: usize = 32; |
Collaborator
There was a problem hiding this comment.
Do we still need that variable? What's the reason to have special max value if an env var is set vs via set_num_threads?
| const ENVIRONMENT_MAX_THREADS: usize = 32; | ||
|
|
||
| /// Global thread count override. 0 = unset (use env var or default). | ||
| /// Global thread count override. 0 = unset (use environment variable or default). |
Collaborator
There was a problem hiding this comment.
Why expand env var to environment variable? I think everyone understands env var
Contributor
Author
There was a problem hiding this comment.
I.. have no defence 🤣
Keats
reviewed
May 4, 2026
f67d894 to
c371dfc
Compare
c371dfc to
ac3331f
Compare
Adds a debug log line in dvs::utils::get_threadpool that names the resolved thread count *and* the source (override / env / default), and a ui/main_threads.sh script that exercises the chain end-to-end through both dvs-cli and dvs-rpkg. The script's CLI section runs four scenarios — no flag/no env, env only, flag-overrides-env, and --threads 0-clears-override — each rendering one \"thread pool: N threads (source: ..., work_items=W)\" line that proves which tier won. The R section runs four phases (default / env / option-overrides-env / withr-scoped-override) with dvs_add → dvs_status → dvs_get in each, after opting in via set_dvs_log_level(\"debug\"). Every operation's resolution prints the same line through R's console (now possible after dvs-rpkg landed the miniextendr log routing in #182). Also adds 'threads' to ui_names in the justfile so 'just ui-run' / 'just ui-render' / 'just ui-publish' include the new script. Local end-to-end run produced 16 thread-pool lines: 4 from CLI, 12 from R (4 phases × 3 ops), every line matching the expected source tier.
Relabel the existing precedence scenarios (CLI 3, Phase C, Phase D) to call out PRECEDENCE in the section headers, and add Phase E: a single phase that holds DVS_NUM_THREADS=3 constant and toggles set_dvs_threads() between four ops. The dvs::utils::get_threadpool log line then prints, in order: env=3 → override=7 → override=5 → env=3 making it directly observable that set_dvs_threads(N) takes precedence over DVS_NUM_THREADS, and that clearing the override (NULL) falls back to env. The CLI section already demonstrates the analogous --threads N > env case; labels are updated for symmetry. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
dvs/src/utils.rs — fold the priority chain into a single if/else-if/else inside get_threadpool. The previous (count, source) tuple match and the intermediate ThreadCount enum both added indirection without a second call site to justify it; the inline form reads top-down as the priority order with caps and labels adjacent to the branch that selects them. Log message format and source labels (override/env/default) are unchanged. justfile — ui-publish-only now takes a variadic *names. No args = publish all ui_names (current behavior); args = publish only those names. Replaces the separate ui-publish-one recipe. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ronment dvs/src/utils.rs — declare `let num_threads; let source;` up front and assign both in each branch of an `if`/`else if`/`else`. Drops the tuple returned from the expression. Also rename the env-tier source label from "env" to "environment" for parity with the other labels (override/default). Update the matching references in ui/main_threads.sh. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the &'static str source label with a private ThreadSource enum
{Override, Environment, Default} and a Display impl that emits the same
lowercase labels (preserving the contract with ui/main_threads.sh).
Move .min(work_limit) inside each match arm so all bounds for a branch
are at the point of computation; the trailing .min(work_limit) chained
after the match was easy to miss when reading.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Spell out the env-tier in full: ENV_MAX_THREADS → ENVIRONMENT_MAX_THREADS, env_threads → environment_threads, and the matching doc/comment text. The only remaining `env` is `std::env::var` (stdlib path, not renamable). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ac3331f to
300badf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI-written details
Summary
Closes the original investigation: verify that
set_num_threads's priority chain resolves identically when called fromdvs-rpkgas fromdvs-cli.dvs/src/utils.rs(+74/−28):get_threadpoolnow resolves the priority chain (override → environment → default) and emits alog::debug!naming the resolved count and the winning tier via a privateThreadSourceenum (Override/Environment/Default):Each tier clamps to its own cap (
ENVIRONMENT_MAX_THREADS/DEFAULT_MAX_THREADS) and towork_items, co-located inside the match arm so a future edit can't drop a clamp.ui/main_threads.sh(new, +229): exercises the chain end-to-end on both interfaces.--threads Nbeats env;--threads 0clears the override.dvs_add→dvs_status→dvs_getunder one config each (default / env / option-overrides-env /withr-scoped override). Phase E holdsDVS_NUM_THREADS=3constant and togglesset_dvs_threads()between four ops in one repo, so the log line visibly flipsenvironment → override → override → environment.R-side logs render via
set_dvs_log_level("debug")(possible since #182 routed the cross-thread log queue to R's console).justfile(+14/−3):ui_namesaddsthreadssojust ui-run/ui-render/ui-publishcover the new script.ui-publish-onlybecomes variadic (*names): no args publish all; args restrict to those names.Local verification (from previous run)
bash ui/main_threads.shproduces 20thread pool:log lines; every line's source tier matches its configured input. CLI and R sections drive the samedvs::utils::get_threadpoolcode path, so identical(N, source)pairs across the two interfaces confirm the priority chain resolves the same through both bindings.Test plan
Verifying this PR (CLI section)
cargo test -p dvs --libpassesjust install-clirebuilds the dvs binary with the newlog::debug!ui/main_threads.shproduces the expected 4 source-tier outcomesEnv prep needed before the R section of the script runs
The R section needs
dvs-rpkgrebuilt against this branch'sdvs. Becausedvs-rpkg/src/rust/Cargo.tomlpinsdvs = { branch = "main" }, the rpkg won't pick up these changes until this PR lands on main or you temporarily re-pin:dvs-rpkg/src/rust/Cargo.toml'sdvsdep at this branch, or use a local[patch]blockcargo update -p dvs --manifest-path dvs-rpkg/src/rust/Cargo.tomljust rpkg-installui/main_threads.shproduces 16 log lines with the expected tier transitionsgrep -c 'thread pool:' /tmp/ui-threads.logreturns 20After merge, the temporary pin can be reverted and the rpkg picked up via a normal lockfile bump.
Drafted by Claude (claude-opus-4-7). Reviewed by the author.